Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Ове године, главна европска Кубернетес конференција - КубеЦон + ЦлоудНативеЦон Еуропе 2020 - била је виртуелна. Међутим, таква промена формата нас није спречила да предамо наш дуго планирани извештај „Идемо? Басх! Упознајте Схелл-оператора“ посвећеног нашем пројекту отвореног кода схелл-оператор.

Овај чланак, инспирисан разговором, представља приступ поједностављивању процеса креирања оператора за Кубернетес и показује како можете да направите сопствени уз минималан напор користећи схелл-оператор.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Представљамо видео извештаја (~23 минута на енглеском, приметно информативнији од чланка) и главни извод из њега у текстуалном облику. Иди!

У Фланту стално све оптимизујемо и аутоматизујемо. Данас ћемо причати о још једном узбудљивом концепту. Сусрет: скриптовање љуске у изворном облаку!

Међутим, почнимо са контекстом у коме се све ово дешава: Кубернетес.

Кубернетес АПИ и контролери

АПИ у Кубернетесу може бити представљен као нека врста сервера датотека са директоријумима за сваки тип објекта. Објекти (ресурси) на овом серверу су представљени ИАМЛ датотекама. Поред тога, сервер има основни АПИ који вам омогућава да урадите три ствари:

  • да прими ресурс по својој врсти и називу;
  • промена ресурс (у овом случају сервер чува само „исправне“ објекте - сви погрешно формирани или намењени другим директоријумима се одбацују);
  • пратити за ресурс (у овом случају корисник одмах добија његову тренутну/ажурирану верзију).

Дакле, Кубернетес делује као нека врста сервера датотека (за ИАМЛ манифесте) са три основна метода (да, заправо постоје и други, али ћемо их за сада изоставити).

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Проблем је у томе што сервер може да чува само информације. Да би то функционисало потребно вам је контролор - други најважнији и фундаментални концепт у свету Кубернетеса.

Постоје две главне врсте контролера. Први узима информације из Кубернетеса, обрађује их према угнежђеној логици и враћа их К8с. Други преузима информације из Кубернетеса, али, за разлику од првог типа, мења стање неких екстерних ресурса.

Хајде да детаљније погледамо процес креирања примене у Кубернетес-у:

  • Контролор примене (укључен у kube-controller-manager) прима информације о имплементацији и креира РеплицаСет.
  • РеплицаСет креира две реплике (два модула) на основу ових информација, али ти модули још увек нису заказани.
  • Планер распоређује подове и додаје информације о чворовима њиховим ИАМЛ-овима.
  • Кубелетс прави промене на спољном ресурсу (рецимо Доцкер).

Затим се цео овај низ понавља обрнутим редоследом: кубелет проверава контејнере, израчунава статус модула и шаље га назад. РеплицаСет контролер прима статус и ажурира стање скупа реплика. Иста ствар се дешава са контролором имплементације и корисник коначно добија ажурирани (тренутни) статус.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Схелл-оператор

Испоставило се да је Кубернетес заснован на заједничком раду различитих контролора (Кубернетес оператери су такође контролори). Поставља се питање, како направити свог оператера уз минималан напор? И овде у помоћ долази онај који смо развили схелл-оператор. Омогућава администраторима система да креирају сопствене изјаве користећи познате методе.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Једноставан пример: копирање тајни

Погледајмо једноставан пример.

Рецимо да имамо Кубернетес кластер. Има именски простор default са неком Тајном mysecret. Поред тога, у кластеру постоје и други именски простори. Неки од њих имају посебну етикету. Наш циљ је да копирамо Сецрет у просторе имена са ознаком.

Задатак је компликован чињеницом да се у кластеру могу појавити нови простори имена, а неки од њих могу имати ову ознаку. С друге стране, када се ознака обрише, треба избрисати и Сецрет. Поред овога, сама тајна се такође може променити: у овом случају, нова тајна мора бити копирана у све просторе имена са ознакама. Ако се Сецрет случајно избрише у било ком именском простору, наш оператер треба да га одмах врати.

Сада када је задатак формулисан, време је да почнемо да га имплементирамо користећи схелл-оператор. Али прво вреди рећи неколико речи о самом схелл-оператору.

Како ради схелл-оператор

Као и друга радна оптерећења у Кубернетесу, схелл-оператор се покреће у сопственом под-у. У овој подлози у директоријуму /hooks извршне датотеке се чувају. То могу бити скрипте у Басх, Питхон, Руби итд. Такве извршне датотеке називамо кукицама (куке).

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Схелл-оператор се претплаћује на Кубернетес догађаје и покреће ове куке као одговор на оне догађаје који су нам потребни.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Како схелл-оператер зна коју удицу да покрене и када? Поента је да свака удица има две фазе. Током покретања, схелл-оператор покреће све куке са аргументом --config Ово је фаза конфигурације. А након тога, куке се покрећу на нормалан начин - као одговор на догађаје за које су везане. У последњем случају, кука прима контекст везивања (обавезујући контекст) - подаци у ЈСОН формату, о чему ћемо детаљније говорити у наставку.

Прављење оператора у Басху

Сада смо спремни за имплементацију. Да бисмо то урадили, морамо да напишемо две функције (успут, препоручујемо библиотека схелл_либ, што увелико поједностављује писање кукица у Басху):

  • први је потребан за фазу конфигурације - приказује контекст везивања;
  • други садржи главну логику куке.

#!/bin/bash

source /shell_lib.sh

function __config__() {
  cat << EOF
    configVersion: v1
    # BINDING CONFIGURATION
EOF
}

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Следећи корак је да одлучимо који су нам објекти потребни. У нашем случају, морамо да пратимо:

  • тајна извора за промене;
  • сви простори имена у кластеру, тако да знате који имају прикачену ознаку;
  • циљне тајне како би се осигурало да су све синхронизоване са изворном тајном.

Претплатите се на тајни извор

Конфигурација везивања за то је прилично једноставна. Називом означавамо да смо заинтересовани за Сецрет mysecret у именском простору default:

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

function __config__() {
  cat << EOF
    configVersion: v1
    kubernetes:
    - name: src_secret
      apiVersion: v1
      kind: Secret
      nameSelector:
        matchNames:
        - mysecret
      namespace:
        nameSelector:
          matchNames: ["default"]
      group: main
EOF

Као резултат тога, кука ће се покренути када се промени изворна тајна (src_secret) и примите следећи обавезујући контекст:

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Као што видите, садржи име и цео објекат.

Праћење именских простора

Сада морате да се претплатите на именске просторе. Да бисмо то урадили, наводимо следећу конфигурацију везивања:

- name: namespaces
  group: main
  apiVersion: v1
  kind: Namespace
  jqFilter: |
    {
      namespace: .metadata.name,
      hasLabel: (
       .metadata.labels // {} |  
         contains({"secret": "yes"})
      )
    }
  group: main
  keepFullObjectsInMemory: false

Као што видите, у конфигурацији се појавило ново поље са именом јкФилтер. Као што му име говори, jqFilter филтрира све непотребне информације и креира нови ЈСОН објекат са пољима која нас занимају. Хоок са сличном конфигурацијом ће добити следећи контекст везивања:

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Садржи низ filterResults за сваки именски простор у кластеру. Боолеан променљива hasLabel означава да ли је ознака придружена датом именском простору. Селектор keepFullObjectsInMemory: false указује да нема потребе да се комплетни објекти чувају у меморији.

Праћење тајни мета

Претплаћујемо се на све Тајне које имају наведену напомену managed-secret: "yes" (ово су наша мета dst_secrets):

- name: dst_secrets
  apiVersion: v1
  kind: Secret
  labelSelector:
    matchLabels:
      managed-secret: "yes"
  jqFilter: |
    {
      "namespace":
        .metadata.namespace,
      "resourceVersion":
        .metadata.annotations.resourceVersion
    }
  group: main
  keepFullObjectsInMemory: false

У овом случају, jqFilter филтрира све информације осим именског простора и параметра resourceVersion. Последњи параметар је прослеђен напомени приликом креирања тајне: омогућава вам да упоредите верзије тајни и да их ажурирате.

Овако конфигурисана кука ће, када се изврши, примити три горе описана контекста везивања. Они се могу сматрати неком врстом снимка (снимак) кластер.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

На основу свих ових информација може се развити основни алгоритам. Итерира преко свих именских простора и:

  • ако hasLabel питања true за тренутни именски простор:
    • упоређује глобалну тајну са локалном:
      • ако су исти, то не чини ништа;
      • ако се разликују – извршава kubectl replace или create;
  • ако hasLabel питања false за тренутни именски простор:
    • осигурава да Сецрет није у датом именском простору:
      • ако је локална тајна присутна, обришите је користећи kubectl delete;
      • ако локална тајна није откривена, не ради ништа.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Имплементација алгоритма у Басху можете преузети у нашој спремишта са примерима.

Тако смо успели да направимо једноставан Кубернетес контролер користећи 35 линија ИАМЛ конфигурације и отприлике исту количину Басх кода! Посао оператера је да их повеже.

Међутим, копирање тајни није једина област примене услужног програма. Ево још неколико примера који показују за шта је способан.

Пример 1: Уношење промена у ЦонфигМап

Хајде да погледамо Деплоимент који се састоји од три модула. Подови користе ЦонфигМап за чување неке конфигурације. Када су подови покренути, ЦонфигМап је био у одређеном стању (назовимо га в.1). Сходно томе, сви подови користе ову конкретну верзију ЦонфигМап-а.

Сада претпоставимо да се ЦонфигМап променио (в.2). Међутим, подови ће користити претходну верзију ЦонфигМап-а (в.1):

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Како могу да их натерам да пређу на нову ЦонфигМап (в.2)? Одговор је једноставан: користите шаблон. Хајде да додамо напомену контролне суме у одељак template Конфигурације примене:

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Као резултат тога, ова контролна сума ће бити регистрована у свим подовима, и биће иста као и за Деплоимент. Сада само треба да ажурирате напомену када се ЦонфигМап промени. И схелл-оператор је у овом случају од користи. Све што треба да урадите је да програмирате кука која ће се претплатити на ЦонфигМап и ажурирати контролни збир.

Ако корисник изврши промене у ЦонфигМап-у, љуска-оператер ће их приметити и поново израчунати контролни збир. Након чега ће се укључити магија Кубернетеса: оркестратор ће убити капсулу, створити нову, сачекати да постане Ready, и прелази на следећу. Као резултат тога, Деплоимент ће се синхронизовати и пребацити на нову верзију ЦонфигМап-а.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Пример 2: Рад са прилагођеним дефиницијама ресурса

Као што знате, Кубернетес вам омогућава да креирате прилагођене типове објеката. На пример, можете креирати врсту MysqlDatabase. Рецимо да овај тип има два параметра метаподатака: name и namespace.

apiVersion: example.com/v1alpha1
kind: MysqlDatabase
metadata:
  name: foo
  namespace: bar

Имамо Кубернетес кластер са различитим именским просторима у којима можемо да креирамо МиСКЛ базе података. У овом случају, схелл-оператор се може користити за праћење ресурса MysqlDatabase, повезујући их са МиСКЛ сервером и синхронизујући жељена и посматрана стања кластера.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Пример 3: Надгледање мреже кластера

Као што знате, коришћење пинга је најједноставнији начин за надгледање мреже. У овом примеру ћемо показати како да имплементирамо такав надзор користећи схелл-оператор.

Пре свега, мораћете да се претплатите на чворове. Оператору љуске је потребно име и ИП адреса сваког чвора. Уз њихову помоћ, он ће пинговати ове чворове.

configVersion: v1
kubernetes:
- name: nodes
  apiVersion: v1
  kind: Node
  jqFilter: |
    {
      name: .metadata.name,
      ip: (
       .status.addresses[] |  
        select(.type == "InternalIP") |
        .address
      )
    }
  group: main
  keepFullObjectsInMemory: false
  executeHookOnEvent: []
schedule:
- name: every_minute
  group: main
  crontab: "* * * * *"

Параметар executeHookOnEvent: [] спречава покретање куке као одговор на било који догађај (то јест, као одговор на промену, додавање, брисање чворова). Међутим, он ће покренути (и ажурирање листе чворова) Planirano - сваког минута, како прописује терен schedule.

Сада се поставља питање, како тачно знамо о проблемима као што је губитак пакета? Хајде да погледамо код:

function __main__() {
  for i in $(seq 0 "$(context::jq -r '(.snapshots.nodes | length) - 1')"); do
    node_name="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.name')"
    node_ip="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.ip')"
    packets_lost=0
    if ! ping -c 1 "$node_ip" -t 1 ; then
      packets_lost=1
    fi
    cat >> "$METRICS_PATH" <<END
      {
        "name": "node_packets_lost",
        "add": $packets_lost,
        "labels": {
          "node": "$node_name"
        }
      }
END
  done
}

Итерирамо кроз листу чворова, добијамо њихова имена и ИП адресе, пингујемо их и шаљемо резултате Прометеју. Схелл-оператор може да извози метрику у Прометхеус, чувајући их у датотеци која се налази у складу са путањом наведеном у променљивој окружења $METRICS_PATH.

Тако можете направити оператера за једноставно праћење мреже у кластеру.

Механизам чекања

Овај чланак би био непотпун без описа другог важног механизма уграђеног у схелл-оператор. Замислите да извршава неку врсту куке као одговор на догађај у кластеру.

  • Шта се дешава ако се у исто време нешто деси у кластеру? још једно догађај?
  • Хоће ли схелл-оператор покренути још једну инстанцу куке?
  • Шта ако се, рецимо, у кластеру догоди пет догађаја одједном?
  • Хоће ли их схелл-оператер обрадити паралелно?
  • Шта је са потрошеним ресурсима као што су меморија и ЦПУ?

На срећу, схелл-оператор има уграђени механизам чекања. Сви догађаји се налазе у реду чекања и обрађују се узастопно.

Хајде да то илуструјемо примерима. Рецимо да имамо две куке. Први догађај иде на прву удицу. Када се обрада заврши, ред се креће напред. Следећа три догађаја се преусмеравају на другу куку - уклањају се из реда и уносе у њега „у групи“. То је кука прима низ догађаја — или, тачније, низ обавезујућих контекста.

Такође и ове догађаји се могу комбиновати у једну велику. За ово је одговоран параметар group у конфигурацији везивања.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Можете креирати било који број редова/кукица и њихове различите комбинације. На пример, један ред може да ради са две куке, или обрнуто.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Све што треба да урадите је да конфигуришете поље у складу са тим queue у конфигурацији везивања. Ако име реда није наведено, кука се покреће на подразумеваном реду (default). Овај механизам чекања вам омогућава да у потпуности решите све проблеме управљања ресурсима када радите са кукицама.

Закључак

Објаснили смо шта је схелл-оператор, показали како се може користити за брзо и лако креирање Кубернетес оператора и навели неколико примера његове употребе.

Детаљне информације о схелл-оператору, као и брзи водич о томе како га користити, доступни су у одговарајућем спремишта на ГитХуб-у. Не устручавајте се да нас контактирате са питањима: о њима можете разговарати у посебном Телеграм група (на руском) или у овај форум (на енглеском).

И ако вам се свидело, увек смо срећни да видимо нова издања/ПР/звезде на ГитХуб-у, где, иначе, можете пронаћи друге занимљивих пројеката. Међу њима вреди истаћи аддон оператор, који је велики брат схелл-оператора. Овај услужни програм користи Хелмове графиконе за инсталирање додатака, може да испоручује ажурирања и надгледа различите параметре/вредности графикона, контролише процес инсталације графикона, а такође може да их мења као одговор на догађаје у кластеру.

Иди? Басх! Упознајте схелл-оператера (преглед и видео извештај са КубеЦон ЕУ'2020)

Видео снимци и слајдови

Видео са наступа (~23 минута):

Пусти видео

Презентација извештаја:

ПС

Прочитајте и на нашем блогу:

Извор: ввв.хабр.цом