ProHoster > Блог > басқарма > Python тіліндегі Kubernetes операторы фреймворксыз және SDK
Python тіліндегі Kubernetes операторы фреймворксыз және SDK
Go қазіргі уақытта адамдар Kubernetes үшін мәлімдеме жазуды таңдайтын бағдарламалау тілдеріне монополияға ие. Мұның объективті себептері бар, мысалы:
Go-да операторларды дамыту үшін қуатты негіз бар - SDK операторы.
Docker және Kubernetes сияқты ойынды өзгертетін қолданбалар Go жүйесінде жазылған. Операторыңызды Go тілінде жазу экожүйемен бір тілде сөйлеуді білдіреді.
Go қолданбаларының жоғары өнімділігі және параллельділікпен жұмыс істеуге арналған қарапайым құралдар.
NB: Айтпақшы, Go бағдарламасында өз мәлімдемеңізді қалай жазуға болады, біз бұрыннан сипатталған шетелдік авторлардың аудармаларымыздың бірінде.
Бірақ егер сізге уақыттың жетіспеуі немесе қарапайым тілмен айтқанда мотивация оқуға кедергі болса ше? Мақалада әрбір DevOps инженері білетін ең танымал тілдердің бірін пайдаланып жақсы мәлімдеме жазудың мысалы келтірілген - Python.
Танысыңыз: Көшірме – көшіру операторы!
Мысал ретінде, жаңа аттар кеңістігі пайда болғанда немесе екі нысанның бірі өзгерген кезде ConfigMap файлын көшіруге арналған қарапайым мәлімдемені әзірлеуді қарастырыңыз: ConfigMap және Құпия. Практикалық тұрғыдан алғанда, оператор қолданба конфигурацияларын жаппай жаңарту үшін (ConfigMap жаңарту арқылы) немесе құпия деректерді жаңарту үшін пайдалы болуы мүмкін - мысалы, Docker тізілімімен жұмыс істеу кілттері (аттар кеңістігіне құпияны қосқанда).
Операторды конфигурациялауға болады. Ол үшін пәрмен жолының жалаушалары мен ортаның айнымалы мәндерін қолданамыз.
Docker контейнерінің және Helm диаграммасының құрылымы пайдаланушылар операторды Kubernetes кластеріне оңай орната алатындай етіп жасалған.
CRD
Оператор қандай ресурстарды және қайда іздеу керектігін білуі үшін біз оған ереже орнатуымыз керек. Әрбір ереже жалғыз CRD нысаны ретінде көрсетіледі. Бұл CRD қандай өрістерге ие болуы керек?
Ресурс түрі, біз оны іздейміз (ConfigMap немесе Secret).
Аттар кеңістігінің тізімі, онда ресурстар орналасуы керек.
Селектор, ол арқылы біз аттар кеңістігіндегі ресурстарды іздейміз.
Дайын! Енді біз қандай да бір жолмен біздің ережеміз туралы ақпарат алуымыз керек. Кластердің API серверіне сұрауларды өзіміз жазбайтынымызды бірден ескертемін. Ол үшін дайын Python кітапханасын қолданамыз kubernetes-клиент:
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')}
Осы кодты іске қосу нәтижесінде біз келесіні аламыз:
Тамаша: біз операторға ережені ала алдық. Ең бастысы, біз Кубернетес жолы деп аталатын нәрсені жасадық.
Қоршаған ортаның айнымалылары немесе жалаушалары? Біз бәрін аламыз!
Негізгі оператор конфигурациясына көшейік. Қолданбаларды конфигурациялаудың екі негізгі тәсілі бар:
пәрмен жолы опцияларын пайдалану;
ортаның айнымалы мәндерін пайдаланыңыз.
Пәрмен жолы опциялары деректер түрін қолдау және тексеру арқылы параметрлерді икемді оқуға мүмкіндік береді. Python стандартты кітапханасында модуль бар argparser, біз оны қолданамыз. Оның мүмкіндіктерінің егжей-тегжейлері мен мысалдары мына жерде қол жетімді ресми құжаттама.
Біздің жағдайда, пәрмен жолының жалаушаларын оқуды орнатудың мысалы келесідей болады:
Екінші жағынан, Kubernetes ішіндегі орта айнымалы мәндерін пайдалана отырып, контейнер ішіндегі подкаст туралы қызмет ақпаратын оңай тасымалдауға болады. Мысалы, біз подкаст келесі конструкциямен жұмыс істейтін аттар кеңістігі туралы ақпаратты ала аламыз:
ConfigMap және Secret бағдарламаларымен жұмыс істеу әдістерін қалай бөлу керектігін түсіну үшін біз арнайы карталарды қолданамыз. Сонда объектіні қадағалау және жасау үшін қандай әдістер қажет екенін түсіне аламыз:
Одан кейін API серверінен оқиғаларды алу керек. Оны келесідей жүзеге асырайық:
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)
Оқиғаны алғаннан кейін біз оны өңдеудің негізгі логикасына көшеміз:
# Типы событий, на которые будем реагировать
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)
Негізгі логика дайын! Енді осының барлығын бір Python пакетіне жинау керек. Біз файлды дайындаймыз setup.py, онда жоба туралы мета ақпаратты жазыңыз:
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: Python үшін kubernetes клиентінің өз нұсқасы бар. Клиент нұсқалары мен Kubernetes нұсқалары арасындағы үйлесімділік туралы қосымша ақпаратты мына жерден табуға болады үйлесімділік матрицалары.
Енді жобамыз келесідей көрінеді:
copyrator
├── copyrator
│ ├── cli.py # Логика работы с командной строкой
│ ├── constant.py # Константы, которые мы приводили выше
│ ├── load_crd.py # Логика загрузки CRD
│ └── operator.py # Основная логика работы оператора
└── setup.py # Оформление пакета
Докер және Хельм
Dockerfile өте қарапайым болады: негізгі питон-альпі кескінін алыңыз және біздің пакетті орнатыңыз. Оны оңтайландыруды жақсырақ уақытқа қалдырайық:
FROM python:3.7.3-alpine3.9
ADD . /app
RUN pip3 install /app
ENTRYPOINT ["copyrator"]
Осылайша, біз қорқынышсыз, сөгіссіз немесе Go қолданбасын үйренбей, Python-да Kubernetes үшін өз операторымызды құра алдық. Әрине, оның әлі де өсетін орны бар: болашақта ол бірнеше ережелерді өңдей алады, бірнеше ағындарда жұмыс істей алады, CRD өзгерістерін тәуелсіз бақылай алады...
Сізге кодты жақынырақ қарау үшін біз оны енгіздік қоғамдық репозиторий. Егер сіз Python көмегімен іске асырылатын күрделі операторлардың мысалдарын алғыңыз келсе, mongodb қолдану үшін екі операторға назар аудара аласыз (первый и секунд).
PS Егер сіз Kubernetes оқиғаларымен айналысуға тым жалқау болсаңыз немесе сіз Bash-ті қолдануға үйреніп алсаңыз, біздің әріптестер пішінде дайын шешім дайындады. қабық операторы (Біз жарияланды сәуірде).