Go kounye a gen yon monopoli sou langaj pwogramasyon moun chwazi pou ekri deklarasyon pou Kubernetes. Gen rezon objektif pou sa, tankou:
Gen yon fondasyon pwisan pou devlope operatè nan Go - Operatè SDK.
Aplikasyon pou chanje jwèt tankou Docker ak Kubernetes yo ekri nan Go. Ekri operatè ou nan Go vle di pale menm lang ak ekosistèm nan.
Segondè pèfòmans aplikasyon Go ak zouti senp pou travay ak konkou soti nan bwat la.
NB: By wout la, ki jan yo ekri deklarasyon pwòp ou a nan Go, nou deja dekri nan youn nan tradiksyon nou yo pa otè etranje.
Men, e si yo anpeche w aprann Ale pa mank de tan oswa, tou senpleman, motivasyon? Atik la bay yon egzanp sou fason ou ka ekri yon bon deklarasyon lè l sèvi avèk youn nan lang ki pi popilè ke prèske tout enjenyè DevOps konnen - Piton.
Rankontre: Copier - kopi operatè!
Kòm yon egzanp, konsidere devlope yon deklarasyon senp ki fèt pou kopye yon ConfigMap swa lè yon nouvo espas non parèt oswa lè youn nan de antite chanje: ConfigMap ak sekrè. Soti nan yon pwen de vi pratik, operatè a ka itil pou mete ajou konfigirasyon aplikasyon an (pa mete ajou ConfigMap la) oswa pou mete ajou done sekrè - pou egzanp, kle pou travay ak Rejis Docker (lè ajoute sekrè nan espas non an).
Se konsa, kisa yon bon operatè ta dwe genyen:
Se entèraksyon ak operatè a te pote soti lè l sèvi avèk Definisyon Resous Custom (ki refere yo kòm CRD).
Operatè a ka configuré. Pou fè sa, nou pral sèvi ak drapo liy lòd ak varyab anviwònman an.
Konstriksyon veso Docker ak tablo Helm la fèt pou itilizatè yo ka fasilman (literalman ak yon sèl lòd) enstale operatè a nan gwoup Kubernetes yo.
CRD
Pou operatè a konnen ki resous pou chèche ak ki kote yo gade, nou bezwen mete yon règ pou li. Chak règ pral reprezante kòm yon sèl objè CRD. Ki jaden CRD sa a ta dwe genyen?
Kalite resous, ke nou pral chèche (ConfigMap oswa sekrè).
Lis espas non yo, nan ki resous yo ta dwe lokalize.
Selektè, pa ki nou pral chèche resous nan espas non an.
Pare! Koulye a, nou bezwen yon jan kanmenm jwenn enfòmasyon sou règ nou an. Kite m 'fè yon rezèvasyon touswit ke nou pa pral ekri demann nan sèvè API gwoup la tèt nou. Pou fè sa, nou pral sèvi ak yon bibliyotèk Python pare kubernetes-kliyan:
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')}
Kòm yon rezilta nan kouri kòd sa a, nou jwenn bagay sa yo:
Gwo: nou jere jwenn yon règ pou operatè a. Ak pi enpòtan, nou te fè sa yo rele fason Kubernetes la.
Varyab anviwònman oswa drapo? Nou pran tout bagay!
Ann ale nan konfigirasyon operatè prensipal la. Gen de apwòch debaz pou konfigirasyon aplikasyon yo:
itilize opsyon liy lòd;
itilize varyab anviwònman yo.
Opsyon liy kòmand pèmèt ou li paramèt plis fleksib, ak sipò kalite done ak validation. Bibliyotèk estanda Python a gen yon modil argparser, ke nou pral itilize. Detay ak egzanp kapasite li yo disponib nan dokiman ofisyèl yo.
Pou ka nou an, sa a se yon egzanp pou mete drapo lekti liy lòd ta sanble:
Nan lòt men an, lè l sèvi avèk varyab anviwònman nan Kubernetes, ou ka fasilman transfere enfòmasyon sèvis sou gous la andedan veso a. Pou egzanp, nou ka jwenn enfòmasyon sou espas non kote gous la ap kouri ak konstriksyon sa a:
Pou konprann kijan pou separe metòd pou travay ak ConfigMap ak sekrè, nou pral sèvi ak kat espesyal. Lè sa a, nou ka konprann ki metòd nou bezwen swiv ak kreye objè a:
Apre sa, ou bezwen resevwa evènman nan sèvè API a. Ann aplike li jan sa a:
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)
Apre nou fin resevwa evènman an, nou ale nan lojik prensipal la nan trete li:
# Типы событий, на которые будем реагировать
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)
Lojik prensipal la pare! Koulye a, nou bezwen pake tout bagay sa yo nan yon sèl pake Python. Nou prepare dosye a setup.py, ekri meta enfòmasyon sou pwojè a la:
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: Kliyan kubernetes pou Python gen pwòp vèsyon li yo. Ou ka jwenn plis enfòmasyon sou konpatibilite ant vèsyon kliyan ak vèsyon Kubernetes nan matris konpatibilite.
Koulye a, pwojè nou an sanble tankou sa a:
copyrator
├── copyrator
│ ├── cli.py # Логика работы с командной строкой
│ ├── constant.py # Константы, которые мы приводили выше
│ ├── load_crd.py # Логика загрузки CRD
│ └── operator.py # Основная логика работы оператора
└── setup.py # Оформление пакета
Docker ak Helm
Dockerfile a pral ekstrèmman senp: pran imaj la baz python-alpine epi enstale pake nou an. Ann ranvwaye optimize li yo jiskaske pi bon moman:
FROM python:3.7.3-alpine3.9
ADD . /app
RUN pip3 install /app
ENTRYPOINT ["copyrator"]
Se konsa, san pè, repwoch, oswa aprann Go, nou te kapab bati pwòp operatè pa nou pou Kubernetes nan Python. Natirèlman, li toujou gen plas yo grandi: nan lavni an li pral kapab trete règ miltip, travay nan plizyè fil, poukont kontwole chanjman nan CRDs li yo ...
Pou ba ou yon gade pi pre nan kòd la, nou te mete l 'nan depo piblik. Si ou vle egzanp operatè ki pi grav aplike lè l sèvi avèk Python, ou ka vire atansyon ou a de operatè pou deplwaye mongodb (premye a и dezyèm).
PS Men, si ou twò parese pou fè fas ak evènman Kubernetes oswa ou tou senpleman plis abitye itilize Bash, kòlèg nou yo te prepare yon solisyon pare-fè nan fòm lan. shell-operateur (Nou te anonse li nan mwa avril).