Go hefur sem stendur einokun á forritunarmálunum sem fólk velur að skrifa yfirlýsingar fyrir Kubernetes. Fyrir því eru hlutlægar ástæður, svo sem:
Það er öflugur rammi til að þróa rekstraraðila í Go - SDK rekstraraðila.
Leikjabreytandi forrit eins og Docker og Kubernetes eru skrifuð í Go. Að skrifa símafyrirtækið þitt í Go þýðir að tala sama tungumálið við vistkerfið.
Mikil afköst Go forrita og einföld verkfæri til að vinna með samhliða út úr kassanum.
NB: Við the vegur, hvernig á að skrifa þína eigin yfirlýsingu í Go, we þegar lýst er í einni af þýðingum okkar eftir erlenda höfunda.
En hvað ef þú ert hindraður í að læra Go vegna tímaskorts eða einfaldlega hvatningar? Greinin gefur dæmi um hvernig þú getur skrifað góða yfirlýsingu með því að nota eitt vinsælasta tungumálið sem næstum allir DevOps verkfræðingar þekkja - Python.
Hittu: Ljósritunarvél - afritunaraðili!
Sem dæmi skaltu íhuga að þróa einfalda yfirlýsingu sem er hönnuð til að afrita ConfigMap annað hvort þegar nýtt nafnrými birtist eða þegar annar af tveimur einingum breytist: ConfigMap og Secret. Frá hagnýtu sjónarhorni getur rekstraraðilinn verið gagnlegur fyrir magnuppfærslur á stillingum forrita (með því að uppfæra ConfigMap) eða til að uppfæra leynileg gögn - til dæmis lykla til að vinna með Docker Registry (þegar Secret er bætt við nafnrýmið).
Hægt er að stilla rekstraraðila. Til að gera þetta munum við nota skipanalínuflögg og umhverfisbreytur.
Smíði Docker gámsins og Helm töflunnar er hannað þannig að notendur geti auðveldlega (bókstaflega með einni skipun) sett upp rekstraraðilann í Kubernetes þyrpinguna sína.
CRD
Til þess að rekstraraðili viti hvaða úrræði á að leita að og hvert á að leita þurfum við að setja reglu fyrir hann. Hver regla verður sýnd sem einn CRD hlutur. Hvaða reiti ætti þetta CRD að hafa?
Gerð auðlindar, sem við munum leita að (ConfigMap eða Secret).
Listi yfir nafnrými, þar sem auðlindirnar ættu að vera staðsettar.
Val, þar sem við munum leita að tilföngum í nafnrýminu.
Tilbúið! Nú þurfum við einhvern veginn að fá upplýsingar um regluna okkar. Leyfðu mér að gera fyrirvara strax um að við munum ekki skrifa beiðnir til cluster API Server sjálf. Til að gera þetta munum við nota tilbúið Python bókasafn kubernetes-viðskiptavinur:
import kubernetes
from contextlib import suppress
CRD_GROUP = 'flant.com'
CRD_VERSION = 'v1'
CRD_PLURAL = 'copyrators'
def load_crd(namespace, name):
client = kubernetes.client.ApiClient()
custom_api = kubernetes.client.CustomObjectsApi(client)
with suppress(kubernetes.client.api_client.ApiException):
crd = custom_api.get_namespaced_custom_object(
CRD_GROUP,
CRD_VERSION,
namespace,
CRD_PLURAL,
name,
)
return {x: crd[x] for x in ('ruleType', 'selector', 'namespace')}
Sem afleiðing af því að keyra þennan kóða fáum við eftirfarandi:
Frábært: okkur tókst að fá reglu fyrir rekstraraðilann. Og síðast en ekki síst, við gerðum það sem kallast Kubernetes leiðin.
Umhverfisbreytur eða fánar? Við tökum allt!
Við skulum halda áfram í aðalstillingu rekstraraðila. Það eru tvær grundvallaraðferðir við að stilla forrit:
notaðu skipanalínuvalkosti;
nota umhverfisbreytur.
Skipanalínuvalkostir gera þér kleift að lesa stillingar á sveigjanlegri hátt, með stuðningi og staðfestingu gagnategunda. Staðlað bókasafn Python er með einingu argparser, sem við munum nota. Upplýsingar og dæmi um getu þess eru fáanleg í opinber skjöl.
Fyrir okkar tilvik, þetta er hvernig dæmi um að setja upp lestur skipanalínuflögg myndi líta út:
Á hinn bóginn, með því að nota umhverfisbreytur í Kubernetes, geturðu auðveldlega flutt þjónustuupplýsingar um belg inni í ílátinu. Til dæmis getum við fengið upplýsingar um nafnrýmið sem belgurinn er í gangi með eftirfarandi byggingu:
Til að skilja hvernig á að aðskilja aðferðir til að vinna með ConfigMap og Secret, munum við nota sérstök kort. Þá getum við skilið hvaða aðferðir við þurfum til að rekja og búa til hlutinn:
Næst þarftu að fá viðburði frá API þjóninum. Við skulum útfæra það sem hér segir:
def handle(specs):
kubernetes.config.load_incluster_config()
v1 = kubernetes.client.CoreV1Api()
# Получаем метод для слежения за объектами
method = getattr(v1, LIST_TYPES_MAP[specs['ruleType']])
func = partial(method, specs['namespace'])
w = kubernetes.watch.Watch()
for event in w.stream(func, _request_timeout=60):
handle_event(v1, specs, event)
Eftir að við höfum fengið viðburðinn förum við yfir í meginrökfræðina við að vinna úr honum:
# Типы событий, на которые будем реагировать
ALLOWED_EVENT_TYPES = {'ADDED', 'UPDATED'}
def handle_event(v1, specs, event):
if event['type'] not in ALLOWED_EVENT_TYPES:
return
object_ = event['object']
labels = object_['metadata'].get('labels', {})
# Ищем совпадения по selector'у
for key, value in specs['selector'].items():
if labels.get(key) != value:
return
# Получаем активные namespace'ы
namespaces = map(
lambda x: x.metadata.name,
filter(
lambda x: x.status.phase == 'Active',
v1.list_namespace().items
)
)
for namespace in namespaces:
# Очищаем метаданные, устанавливаем namespace
object_['metadata'] = {
'labels': object_['metadata']['labels'],
'namespace': namespace,
'name': object_['metadata']['name'],
}
# Вызываем метод создания/обновления объекта
methodcaller(
CREATE_TYPES_MAP[specs['ruleType']],
namespace,
object_
)(v1)
Helstu rökfræðin er tilbúin! Nú þurfum við að pakka þessu öllu í einn Python pakka. Við undirbúum skrána setup.py, skrifaðu meta upplýsingar um verkefnið þar:
from sys import version_info
from setuptools import find_packages, setup
if version_info[:2] < (3, 5):
raise RuntimeError(
'Unsupported python version %s.' % '.'.join(version_info)
)
_NAME = 'copyrator'
setup(
name=_NAME,
version='0.0.1',
packages=find_packages(),
classifiers=[
'Development Status :: 3 - Alpha',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
author='Flant',
author_email='[email protected]',
include_package_data=True,
install_requires=[
'kubernetes==9.0.0',
],
entry_points={
'console_scripts': [
'{0} = {0}.cli:main'.format(_NAME),
]
}
)
NB: Kubernetes viðskiptavinurinn fyrir Python hefur sína eigin útgáfu. Frekari upplýsingar um samhæfni milli útgáfu viðskiptavina og Kubernetes útgáfur er að finna í eindrægni fylki.
Nú lítur verkefnið okkar svona út:
copyrator
├── copyrator
│ ├── cli.py # Логика работы с командной строкой
│ ├── constant.py # Константы, которые мы приводили выше
│ ├── load_crd.py # Логика загрузки CRD
│ └── operator.py # Основная логика работы оператора
└── setup.py # Оформление пакета
Docker og Helm
Dockerfile verður ótrúlega einfalt: taktu grunn python-alpine myndina og settu upp pakkann okkar. Við skulum fresta hagræðingu þess þar til betri tímar:
FROM python:3.7.3-alpine3.9
ADD . /app
RUN pip3 install /app
ENTRYPOINT ["copyrator"]
Uppsetning fyrir rekstraraðila er líka mjög einföld:
Þannig gátum við, án þess að óttast, ávíta eða læra Go, byggt upp okkar eigin símafyrirtæki fyrir Kubernetes í Python. Auðvitað hefur það enn pláss til að vaxa: í framtíðinni mun það geta unnið úr mörgum reglum, unnið í mörgum þráðum, sjálfstætt fylgst með breytingum á CRDs þess ...
Til að skoða kóðann nánar höfum við sett hann inn opinber geymsla. Ef þú vilt dæmi um alvarlegri rekstraraðila útfærð með Python geturðu beint athyglinni að tveimur rekstraraðilum til að dreifa mongodb (первый и annað).
PS Og ef þú ert of latur til að takast á við Kubernetes viðburði eða þú ert einfaldlega vanari að nota Bash, hafa samstarfsmenn okkar útbúið tilbúna lausn í formi skel-rekstraraðili (Við tilkynnt það í apríl).