Проширување и дополнување на Kubernetes (преглед и видео извештај)

Проширување и дополнување на Kubernetes (преглед и видео извештај)

8 април на конференцијата Saint HighLoad++ 2019 година, како дел од делот „DevOps и операции“, беше даден извештај „Проширување и дополнување на Кубернетес“, во чие создавање учествуваа тројца вработени во компанијата Флант. Во него зборуваме за бројни ситуации во кои сакавме да ги прошириме и надополниме можностите на Kubernetes, но за кои не најдовме готово и едноставно решение. Ги имаме потребните решенија во форма на проекти со отворен код, а на нив е посветен и овој говор.

По традиција, со задоволство ви претставуваме видео од извештајот (50 минути, многу поинформативни од написот) и главното резиме во текстуална форма. Оди!

Јадро и додатоци во K8s

Kubernetes ја менува индустријата и пристапите кон администрацијата кои одамна се воспоставени:

  • Благодарение на него апстракции, повеќе не работиме со концепти како што се поставување конфигурација или извршување команда (Chef, Ansible...), туку користиме групирање на контејнери, услуги итн.
  • Можеме да подготвиме апликации без да размислуваме за нијансите на одредена локација, на кој ќе биде лансиран: гол метал, облак на еден од провајдерите итн.
  • Со K8 никогаш не сте биле попристапни најдобри практики за организирање на инфраструктурата: техники на скалирање, само-заздравување, толеранција на грешки итн.

Сепак, се разбира, сè не е толку мазно: Кубернетес донесе и свои нови предизвици.

Кубернети Нема е комбајн кој ги решава сите проблеми на сите корисници. Јадрото Kubernetes е одговорен само за збир на минимални неопходни функции што се присутни во секој Грозд:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Јадрото на Kubernetes дефинира основен сет на примитиви за групирање контејнери, управување со сообраќајот и така натаму. Разговаравме за нив подетално во извештај пред 2 години.

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Од друга страна, K8s нуди одлични можности за проширување на достапните функции, кои помагаат да се затворат другите - специфичен — потребите на корисниците. Дополнувањата на Kubernetes се одговорност на администраторите на кластерите, кои мора да инсталираат и конфигурираат сè што е потребно за да го добијат нивниот кластер „во вистинската форма“ [за да ги решат нивните специфични проблеми]. Какви додатоци се овие? Ајде да погледнеме неколку примери.

Примери на додатоци

Откако го инсталиравме Kubernetes, може да бидеме изненадени што вмрежувањето што е толку неопходно за интеракцијата на подови и во јазол и помеѓу јазли не функционира самостојно. Јадрото Kubernetes не ги гарантира потребните врски, наместо тоа, ја одредува мрежата интерфејсот (ЦНИ) за додатоци од трета страна. Мора да инсталираме еден од овие додатоци, кој ќе биде одговорен за конфигурацијата на мрежата.

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Близок пример се решенијата за складирање податоци (локален диск, мрежен блок уред, Ceph...). Првично тие беа во јадрото, но со доаѓањето CSI ситуацијата се менува на нешто слично на веќе опишаното: интерфејсот е во Kubernetes, а неговата имплементација е во модули од трети страни.

Други примери вклучуваат:

  • Целосно-контролори (видете го нивниот преглед во нашата неодамнешна статија).
  • сертификат-менаџер:

    Проширување и дополнување на Kubernetes (преглед и видео извештај)

  • Оператори е цела класа на додатоци (која го вклучува споменатиот серт-менаџер), тие дефинираат примитив(и) и контролер(и). Логиката на нивната работа е ограничена само од нашата имагинација и ни овозможува готовите инфраструктурни компоненти (на пример, DBMS) да ги претвориме во примитивци, со кои е многу полесна за работа (отколку со сет на контејнери и нивните поставки). Напишани се огромен број оператори - дури и ако многу од нив сè уште не се подготвени за производство, тоа е само прашање на време:

    Проширување и дополнување на Kubernetes (преглед и видео извештај)

  • Метрика - уште една илустрација за тоа како Kubernetes го одвои интерфејсот (Metrics API) од имплементацијата (додатоци од трета страна како што е адаптерот Prometheus, агентот за кластер на Datadog...).
  • За мониторинг и статистика, каде што во пракса не само што се потребни Прометеј и Графана, но и kube-state-metrics, node-exporter итн.

И ова не е комплетна листа на додатоци... На пример, во компанијата Флант што моментално ја инсталираме 29 дополнувања (сите создаваат вкупно 249 објекти на Кубернет). Едноставно кажано, не можеме да го видиме животот на кластерот без додатоци.

Автоматизација

Операторите се дизајнирани да ги автоматизираат рутинските операции со кои се среќаваме секој ден. Еве реални примери за кои пишувањето оператор би било одлично решение:

  1. Постои приватен (т.е. бара најава) регистар со слики за апликацијата. Се претпоставува дека на секој pod му е доделена посебна тајна што овозможува автентикација во регистарот. Наша задача е да се погрижиме оваа тајна да се најде во именскиот простор за да може да преземаат слики. Може да има многу апликации (од кои на секоја и е потребна тајна), а корисно е редовно да се ажурираат самите тајни, така што опцијата за рачно поставување тајни е елиминирана. Ова е местото каде што операторот доаѓа на помош: создаваме контролер кој ќе чека да се појави именскиот простор и, врз основа на овој настан, ќе додаде тајна во именскиот простор.
  2. Дозволете стандардно пристапот од pods до Интернет е забранет. Но, понекогаш може да се бара: логично е механизмот за дозвола за пристап да работи едноставно, без да бара специфични вештини, на пример, со присуство на одредена ознака во именскиот простор. Како може операторот да ни помогне овде? Се креира контролер кој чека етикетата да се појави во именскиот простор и ја додава соодветната политика за пристап до Интернет.
  3. Слична ситуација: да претпоставиме дека требаше да додадеме одредено дамка, ако има слична ознака (со некој вид на префикс). Дејствата со операторот се очигледни...

Во секој кластер, рутинските задачи мора да се решаваат, и правилно ова може да се направи со помош на оператори.

Сумирајќи ги сите опишани приказни, дојдовме до заклучок дека за удобна работа во Кубернетес ви треба: А) инсталирајте додатоци, б) развиваат оператори (за решавање на секојдневни администраторски задачи).

Како да напишете изјава за Kubernetes?

Во принцип, шемата е едноставна:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

... но потоа излегува дека:

  • Kubernetes API е прилично нетривијална работа што бара многу време за да се совлада;
  • програмирањето исто така не е за секого (јазикот Go е избран како префериран јазик бидејќи има посебна рамка за него - Оператор SDK);
  • Слична е ситуацијата и со самата рамка.

Во крајна линија: да напише контролер (оператор) мора трошат значителни ресурси да учат материјал. Ова би било оправдано за „големите“ оператори - да речеме, за MySQL DBMS. Но, ако се сетиме на примерите опишани погоре (откривање тајни, пристап до мешунките на Интернет...), што исто така сакаме да го направиме правилно, тогаш ќе разбереме дека вложениот труд ќе го надмине резултатот што ни треба сега:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Општо земено, се наметнува дилема: потроши многу ресурси и пронајдете ја вистинската алатка за пишување изјави или направете го тоа на старомоден начин (но брзо). За да го решиме - да најдеме компромис помеѓу овие крајности - создадовме сопствен проект: школка-оператор (види и неговиот неодамнешна објава на центар).

Шел-оператор

Како работи тој? Кластерот има подлога што содржи Go бинарно со школка-оператор. До него е збир на куки (повеќе детали за нив - видете подолу). Самиот школка-оператор се претплати на одредени случувања во Kubernetes API, по чие појавување ги лансира соодветните куки.

Како операторот на школка знае кои куки да ги повика на кои настани? Овие информации се пренесуваат до операторот на школка од самите куки, а тие го прават тоа многу едноставно.

Кука е скрипта Bash или која било друга извршна датотека што прифаќа еден аргумент --config и одговара со JSON. Последново одредува кои објекти се од интерес за него и на кои настани (за овие објекти) треба да се одговори:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Ќе ја илустрирам имплементацијата на школка-оператор на еден од нашите примери - разложување тајни за пристап до приватен регистар со слики од апликации. Се состои од две фази.

Вежбајте: 1. Напишете кука

Пред сè, во куката што ќе ја обработиме --config, што укажува дека сме заинтересирани за именските простори, и конкретно, моментот на нивното создавање:

[[ $1 == "--config" ]] ; then
  cat << EOF
{
  "onKubernetesEvent": [
    {
      "kind": "namespace",
      "event": ["add"]
    }
  ]
}
EOF
…

Како би изгледала логиката? Исто така прилично едноставно:

…
else
  createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
  kubectl create -n ${createdNamespace} -f - << EOF
Kind: Secret
...
EOF
fi

Првиот чекор е да откриете кој именски простор е создаден, а вториот е да го креирате користејќи го kubectl тајна за овој именски простор.

Вежбајте: 2. Склопување на сликата

Останува само да се пренесе креираната кука до операторот на школка - како да го направите ова? Самиот оператор на школка доаѓа како слика на Docker, така што нашата задача е да ја додадеме куката во посебен директориум на оваа слика:

FROM flant/shell-operator:v1.0.0-beta.1
ADD my-handler.sh /hooks

Останува само да го составиме и туркаме:

$ docker build -t registry.example.com/my-operator:v1 .
$ docker push registry.example.com/my-operator:v1

Последниот допир е да се распореди сликата во кластерот. За да го направите ова, ајде да напишеме распоредување:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1 # 1
      serviceAccountName: my-operator              # 2

Постојат две точки на кои треба да се обрне внимание:

  1. означување на новосоздадената слика;
  2. Ова е системска компонента на која (на минимум) и се потребни права за да се претплати на настани во Kubernetes и да ги распределува тајните на просторите со имиња, така што создаваме ServiceAccount (и збир на правила) за куката.

Резултат - го решивме нашиот проблем роднини за Kubernetes на начин што создава оператор за разложување тајни.

Други карактеристики на школка-оператор

За да ги ограничите предметите од избраниот тип со кои ќе работи куката, тие можат да се филтрираат, избирање според одредени ознаки (или користење matchExpressions):

"onKubernetesEvent": [
  {
    "selector": {
      "matchLabels": {
        "foo": "bar",
       },
       "matchExpressions": [
         {
           "key": "allow",
           "operation": "In",
           "values": ["wan", "warehouse"],
         },
       ],
     }
     …
  }
]

Обезбедено механизам за дедупликација, кој - користејќи jq филтер - ви овозможува да конвертирате големи JSON објекти во мали, каде што остануваат само оние параметри што сакаме да ги следиме за промени.

Кога ќе се повика кука, операторот на школка ја поминува податоци за објектот, кој може да се користи за секоја потреба.

Настаните што ги активираат куките не се ограничени само на настаните на Кубернетес: операторот на школка обезбедува поддршка за повикувајќи куки по време (слично на crontab во традиционален распоредувач), како и посебен настан на стартување. Сите овие настани може да се комбинираат и да се доделат на истата кука.

И уште две карактеристики на операторот на школка:

  1. Функционира асинхроно. Со оглед на тоа што е примен настан на Kubernetes (како објект што се создава), може да се случат други настани (како што е истиот објект што се брише) во кластерот, а куките треба да го земат предвид ова. Ако куката е извршена со грешка, тогаш стандардно ќе биде повторно повикување до успешно завршување (ова однесување може да се промени).
  2. Извезува метрика за Prometheus, со кој можете да разберете дали работи операторот на школка, дознајте го бројот на грешки за секоја кука и моменталната големина на редот.

Да го резимираме овој дел од извештајот:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Инсталирање додатоци

За удобна работа со Kubernetes, беше спомната и потребата од инсталирање додатоци. Ќе ви кажам за тоа користејќи го примерот на патот на нашата компанија до тоа како го правиме тоа сега.

Почнавме да работиме со Kubernetes со неколку кластери, чиј единствен додаток беше Ingress. Требаше да се инсталира различно во секој кластер и направивме неколку YAML конфигурации за различни средини: гол метал, AWS...

Како што имаше повеќе кластери, имаше повеќе конфигурации. Покрај тоа, ние самите ги подобривме овие конфигурации, како резултат на што тие станаа доста хетерогени:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

За да ставиме сè во ред, почнавме со скрипта (install-ingress.sh), кој го зеде како аргумент типот на кластерот на кој ќе го распоредиме, ја генерира потребната конфигурација YAML и ја префрли на Kubernetes.

Накратко, нашиот понатамошен пат и расудувањето поврзано со него беа како што следува:

  • за работа со YAML конфигурации, потребен е мотор на шаблон (во првите фази ова е едноставно sed);
  • со зголемувањето на бројот на кластери, дојде и потребата за автоматско ажурирање (најрано решение беше да се стави скриптата во Git, да се ажурира со помош на cron и да се изврши);
  • слична скрипта беше потребна за Прометеј (install-prometheus.sh), сепак, забележливо е што бара многу повеќе влезни податоци, како и нивно складирање (на добар начин - централизирано и во кластер), а некои податоци (лозинки) би можеле автоматски да се генерираат:

    Проширување и дополнување на Kubernetes (преглед и видео извештај)

  • ризикот да се префрли нешто погрешно на се поголем број кластери постојано растеше, па сфативме дека инсталатерите (т.е. две скрипти: за Ingress и Prometheus) беше потребно поставување (неколку гранки во Git, неколку крони за да се ажурираат во соодветните: стабилни или тест кластери);
  • с kubectl apply стана тешко да се работи со него бидејќи не е декларативен и може само да создава објекти, но не и да донесува одлуки за нивниот статус/бришење;
  • Ни недостигаа некои функции што воопшто не ги имплементиравме во тоа време:
    • целосна контрола врз резултатот од ажурирањата на кластерот,
    • автоматско определување на некои параметри (влез за скрипти за инсталација) врз основа на податоци што може да се добијат од кластерот (откривање),
    • неговиот логичен развој во форма на континуирано откривање.

Сето ова акумулирано искуство го реализиравме во рамките на нашиот друг проект - додаток-оператор.

Додаток-оператор

Се заснова на веќе споменатиот школка-оператор. Целиот систем изгледа вака:

Следното е додадено на куките за ракување со школка:

  • складирање на вредности,
  • Табела на кормилото,
  • компонента која ја следи продавницата за вредности и - во случај на какви било промени - бара Хелм повторно да ја преврти табелата.

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Така, можеме да реагираме на настан во Kubernetes, да лансираме кука и од оваа кука можеме да направиме промени во складиштето, по што табелата повторно ќе се преземе. Во добиениот дијаграм, го одделуваме множеството куки и графиконот во една компонента, која ја нарекуваме модул:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

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

Сега, кога нешто се случува во Кубернетес, можеме да реагираме на тоа користејќи глобална кука и да промениме нешто во глобалната продавница. Оваа промена ќе биде забележана и ќе предизвика сите модули во кластерот да се исфрлат:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Оваа шема ги задоволува сите барања за инсталирање додатоци кои беа наведени погоре:

  • Хелм е одговорен за шаблонот и декларативноста.
  • Прашањето за автоматско ажурирање беше решено со помош на глобална кука, која оди во регистарот по распоред и, ако таму види нова системска слика, ја прикажува (т.е. „самиот“).
  • Зачувувањето на поставките во кластерот се спроведува со користење ConfigMap, кој ги содржи примарните податоци за складиштата (при стартување тие се вчитуваат во складиштата).
  • Проблемите со генерирање лозинка, откривање и континуирано откривање беа решени со помош на куки.
  • Станирањето се постигнува благодарение на ознаките, кои Docker ги поддржува надвор од кутијата.
  • Резултатот се следи со помош на метрика со која можеме да го разбереме статусот.

Целиот овој систем е имплементиран во форма на единствена бинарна верзија во Go, која се нарекува додаток-оператор. Ова го прави дијаграмот да изгледа поедноставен:

Проширување и дополнување на Kubernetes (преглед и видео извештај)

Главната компонента на овој дијаграм е збир на модули (означено со сиво подолу). Сега можеме да напишеме модул за потребниот додаток со малку труд и да бидеме сигурни дека ќе се инсталира во секој кластер, ќе се ажурира и ќе одговара на настаните што му се потребни во кластерот.

"Flant" користи додаток-оператор на 70+ кластери Кубернетес. Сегашен статус - алфа верзија. Сега подготвуваме документација за издавање на бета верзијата, но засега во складиштето достапни примери, врз основа на кој можете да креирате сопствен додаток.

Каде можам да ги добијам модулите за дополнителен оператор? Објавувањето на нашата библиотека е следната фаза за нас; планираме да го направиме ова во текот на летото.

Видеа и слајдови

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

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

PS

Други извештаи на нашиот блог:

Може да ве интересираат и следните публикации:

Извор: www.habr.com

Додадете коментар