Идејата за школка-оператор е прилично едноставна: претплатете се на настани од објекти на Kubernetes и кога ќе ги примите овие настани, стартувајте надворешна програма, обезбедувајќи му информации за настанот:
Потребата за тоа се појави кога за време на работата на кластерите почнаа да се појавуваат мали задачи кои навистина сакавме да ги автоматизираме на вистински начин. Сите овие мали задачи беа решени со користење на едноставни баш скрипти, иако, како што знаете, подобро е да пишувате оператори во Golang. Очигледно, инвестирањето во целосен развој на оператор за секоја таква мала задача би било неефикасно.
Оператор за 15 минути
Ајде да погледнеме пример за тоа што може да се автоматизира во кластерот Kubernetes и како операторот на школка може да помогне. Пример би бил следниов: реплицирање тајна за пристап до регистарот на докер.
Подовите што користат слики од приватен регистар мора да содржат во својот манифест врска до тајна со податоци за пристап до регистарот. Оваа тајна мора да се креира во секој именски простор пред да се креираат подлоги. Ова може да се направи рачно, но ако поставиме динамични средини, тогаш именскиот простор за една апликација ќе стане многу. И ако исто така нема 2-3 апликации... бројот на тајни станува многу голем. И уште нешто за тајните: би сакал одвреме-навреме да го менувам клучот за пристап до регистарот. На крајот, рачни операции како решение целосно неефикасни — треба да го автоматизираме создавањето и ажурирањето на тајните.
Едноставна автоматизација
Ајде да напишеме скрипта за школка која работи еднаш на секои N секунди и ги проверува именските простори за присуство на тајна, а ако нема тајна, тогаш таа се креира. Предноста на ова решение е што изгледа како скрипта на школка во cron - класичен и разбирлив пристап за секого. Негативната страна е што во интервалот помеѓу неговите лансирања може да се создаде нов именски простор и некое време ќе остане без тајна, што ќе доведе до грешки при стартување на подлоги.
Автоматизација со школка-оператор
За нашата скрипта да работи правилно, класичното стартување на cron треба да се замени со стартување кога ќе се додаде именски простор: во овој случај, можете да креирате тајна пред да ја користите. Ајде да видиме како да го имплементираме ова користејќи школка-оператор.
Прво, да го погледнеме сценариото. Скриптите во услови на школка-оператор се нарекуваат куки. Секоја кука кога работи со знаменце --config го известува операторот на школка за неговите врзувања, т.е. за тоа кои настани треба да биде лансирана. Во нашиот случај ќе користиме onKubernetesEvent:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
fi
Овде е опишано дека сме заинтересирани за додавање настани (add) објекти од типот namespace.
Сега треба да го додадете кодот што ќе се изврши кога ќе се случи настанот:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
# конфигурация
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
else
# реакция:
# узнать, какой namespace появился
createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
# создать в нём нужный секрет
kubectl create -n ${createdNamespace} -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
...
data:
...
EOF
fi
Одлично! Резултатот беше мало, убаво сценарио. За да го „оживеете“, остануваат уште два чекори: подгответе ја сликата и стартувајте ја во кластерот.
Подготовка на слика со кука
Ако ја погледнете скриптата, можете да видите дека се користат командите kubectl и jq. Ова значи дека сликата мора да ги има следниве работи: нашата кука, школка-оператор што ќе ги следи настаните и ќе ја извршува куката и командите што ги користи куката (kubectl и jq). Hub.docker.com веќе има готова слика во која се спакувани shell-operator, kubectl и jq. Останува само да се додаде едноставна кука Dockerfile:
Ајде повторно да ја погледнеме куката и овојпат да запишеме какви дејства и со какви предмети врши во кластерот:
се претплати на настани за создавање именски простор;
создава тајна во именски простори различни од оној каде што е лансиран.
Излегува дека подлогата во која ќе биде лансирана нашата слика мора да има дозволи да ги прави овие дејства. Ова може да се направи со креирање на сопствена сметка за услуги. Дозволата мора да се направи во форма на ClusterRole и ClusterRoleBinding, бидејќи ние сме заинтересирани за објекти од целиот кластер.
Тоа е сè: операторот на школка ќе започне, ќе се претплати на настани за создавање именски простор и ќе ја стартува куката кога е потребно.
Така, едноставна скрипта за школка се претвори во вистински оператор за Kubernetes и работи како дел од кластер. И сето тоа без сложениот процес на развој на оператори во Голанг:
Има уште една илустрација за ова прашање...
Неговото значење подетално ќе го откриеме во една од следните публикации.
филтрирање
Следењето на објекти е добро, но често има потреба да се реагира менување на некои својства на објектот, на пример, за да го промените бројот на реплики во Deployment или да ги промените етикетите на објектите.
Кога ќе пристигне настан, операторот на школка го прима JSON манифестот на објектот. Можеме да ги избереме својствата што не интересираат во овој JSON и да ја стартуваме куката само кога се менуваат. Има поле за ова jqFilter, каде што треба да го наведете изразот jq што ќе се примени на JSON манифестот.
На пример, за да одговорите на промените во етикетите за објектите за распоредување, треба да го филтрирате полето labels надвор од теренот metadata. Конфигурацијата ќе биде вака:
Мала дигресија: да, поддржува школка-оператор водење на скрипти во стилот на кронтаб. Повеќе детали може да се најдат во документација.
За да се направи разлика зошто куката е лансирана, операторот на школка создава привремена датотека и ја пренесува патеката до неа во променлива до куката BINDING_CONTEXT_TYPE. Датотеката содржи JSON опис на причината за вклучување на куката. На пример, на секои 10 минути куката ќе работи со следнава содржина:
Содржината на полињата може да се разбере од нивните имиња, а повеќе детали може да се прочитаат во документација. Пример за добивање име на ресурс од поле resourceName користењето на jq веќе е прикажано во кука која реплицира тајни:
jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH
Можете да добиете и други полиња на сличен начин.
Што е следно?
Во проектното складиште, во /примери директориуми, има примери на куки кои се подготвени да работат на кластер. Кога пишувате свои куки, можете да ги користите како основа.
Постои поддршка за собирање метрика со помош на Прометеј - достапните метрики се опишани во делот МЕТРИКИ.
Како што може да претпоставите, школка-операторот е напишан во Go и дистрибуиран под лиценца со отворен код (Apache 2.0). Ќе бидеме благодарни за секаква развојна помош проект на GitHub: и ѕвезди, и прашања, и повлекување барања.
Подигнувајќи го превезот на тајноста, ќе ве информираме и дека школка-оператор е мал дел од нашиот систем што може да ги ажурира инсталираните додатоци во кластерот Кубернетес и да врши различни автоматски дејства. Прочитајте повеќе за овој систем раскажано буквално во понеделник на HighLoad++ 2019 во Санкт Петербург - наскоро ќе ги објавиме видеото и транскриптот од овој извештај.
Имаме план да го отвориме остатокот од овој систем: додатниот оператор и нашата колекција куки и модули. Патем, додаток-оператор е веќе достапно на github, но документацијата за тоа е се уште на пат. Издавањето на колекцијата на модули е планирано за лето.