Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

Na našom blogu už o tom boli články možnosti operátora v Kubernetes a ako napíšte si jednoduchý operátor sami. Tentokrát by sme vám radi predstavili naše Open Source riešenie, ktoré posúva tvorbu operátorov na super jednoduchú úroveň – pozrite si shell-operátor!

Prečo?

Myšlienka shell-operátora je pomerne jednoduchá: prihláste sa na odber udalostí z objektov Kubernetes a po prijatí týchto udalostí spustite externý program, ktorý mu poskytne informácie o udalosti:

Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

Potreba vznikla, keď sa počas prevádzky klastrov začali objavovať drobné úlohy, ktoré sme naozaj chceli automatizovať tým správnym spôsobom. Všetky tieto malé úlohy boli vyriešené pomocou jednoduchých bash skriptov, aj keď, ako viete, je lepšie písať operátory v Golangu. Je zrejmé, že investovanie do komplexného rozvoja operátora pre každú takúto malú úlohu by bolo neúčinné.

Operátor do 15 minút

Pozrime sa na príklad toho, čo sa dá automatizovať v klastri Kubernetes a ako môže pomôcť operátor shellu. Príklad by mohol byť nasledujúci: replikácia tajného kľúča na prístup k registru dockerov.

Moduly, ktoré používajú obrázky zo súkromného registra, musia vo svojom manifeste obsahovať odkaz na tajomstvo s údajmi na prístup do registra. Toto tajomstvo musí byť vytvorené v každom mennom priestore pred vytvorením modulov. Dá sa to urobiť ručne, ale ak nastavíme dynamické prostredia, menný priestor pre jednu aplikáciu bude veľa. A ak nie sú ani 2-3 aplikácie... počet tajomstiev sa stáva veľmi veľkým. A ešte jedna vec k tajomstvám: z času na čas by som chcel zmeniť kľúč na prístup do registra. nakoniec manuálne operácie ako riešenie úplne neúčinné — potrebujeme automatizovať vytváranie a aktualizáciu tajomstiev.

Jednoduchá automatizácia

Napíšme shell skript, ktorý sa spustí raz za N sekúnd a skontroluje menné priestory na prítomnosť tajomstva, a ak žiadne tajomstvo neexistuje, potom sa vytvorí. Výhodou tohto riešenia je, že vyzerá ako shell skript v crone – klasický a pre každého zrozumiteľný prístup. Nevýhodou je, že v intervale medzi jeho spustením môže byť vytvorený nový menný priestor a nejaký čas zostane bez tajomstva, čo povedie k chybám pri spúšťaní modulov.

Automatizácia pomocou shell-operátora

Aby náš skript fungoval správne, klasické spustenie cronu je potrebné nahradiť spustením, keď sa pridá priestor názvov: v tomto prípade môžete pred jeho použitím vytvoriť tajomstvo. Pozrime sa, ako to implementovať pomocou shell-operátora.

Najprv sa pozrime na scenár. Skripty v podmienkach shell-operátora sa nazývajú háčiky. Každý hák pri behu s vlajkou --config informuje prevádzkovateľa škrupiny o svojich väzbách, t.j. o akých udalostiach by sa mal spustiť. V našom prípade použijeme onKubernetesEvent:

#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
  { "kind": "namespace",
    "event":["add"]
  }
]}
EOF
fi

Tu je popísané, že máme záujem pridať udalosti (add) objekty typu namespace.

Teraz musíte pridať kód, ktorý sa spustí, keď nastane udalosť:

#!/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

Skvelé! Výsledkom bol malý, krásny scenár. Na jeho „oživenie“ zostávajú dva kroky: pripraviť obrázok a spustiť ho v klastri.

Príprava obrázka s háčikom

Ak sa pozriete na skript, môžete vidieť, že príkazy sa používajú kubectl и jq. To znamená, že obrázok musí mať nasledujúce veci: náš hák, operátor shellu, ktorý bude monitorovať udalosti a spúšťať hák, a príkazy používané hákom (kubectl a jq). Hub.docker.com už má hotový obrázok, v ktorom sú zabalené shell-operator, kubectl a jq. Ostáva už len pridať jednoduchý háčik Dockerfile:

$ cat Dockerfile
FROM flant/shell-operator:v1.0.0-beta.1-alpine3.9
ADD namespace-hook.sh /hooks

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

Beh v klastri

Pozrime sa ešte raz na háčik a tentoraz si napíšme, aké akcie a s akými objektmi v klastri vykonáva:

  1. prihlasuje sa k udalostiam vytvárania menného priestoru;
  2. vytvorí tajomstvo v inom mennom priestore, ako je ten, v ktorom je spustený.

Ukázalo sa, že modul, v ktorom sa spustí náš obrázok, musí mať povolenia na vykonanie týchto akcií. Môžete to urobiť vytvorením vlastného ServiceAccount. Povolenie musí byť vykonané vo forme ClusterRole a ClusterRoleBinding, pretože nás zaujímajú objekty z celého zhluku.

Konečný popis v YAML bude vyzerať asi takto:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitor-namespaces-acc

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: monitor-namespaces
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "patch"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: monitor-namespaces
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: monitor-namespaces
subjects:
  - kind: ServiceAccount
    name: monitor-namespaces-acc
    namespace: example-monitor-namespaces

Zostavený obraz môžete spustiť ako jednoduché nasadenie:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1
      serviceAccountName: monitor-namespaces-acc

Pre pohodlie sa vytvorí samostatný priestor názvov, kde sa spustí operátor shell a použijú sa vytvorené manifesty:

$ kubectl create ns example-monitor-namespaces
$ kubectl -n example-monitor-namespaces apply -f rbac.yaml
$ kubectl -n example-monitor-namespaces apply -f deployment.yaml

To je všetko: shell-operátor sa spustí, prihlási sa na udalosti vytvárania menného priestoru a spustí hák, keď je to potrebné.

Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

To znamená, že jednoduchý shell skript sa zmenil na skutočný operátor pre Kubernetes a funguje ako súčasť klastra. A to všetko bez zložitého procesu vývoja operátorov v Golang:

Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

V tejto veci je ešte jeden príklad...Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

Jeho význam prezradíme podrobnejšie v niektorej z nasledujúcich publikácií.

filtrovanie

Sledovanie objektov je dobré, ale často je potrebné reagovať zmena niektorých vlastností objektu, napríklad zmeniť počet replík v Nasadení alebo zmeniť označenia objektov.

Keď príde udalosť, operátor shellu prijme manifest JSON objektu. Môžeme vybrať vlastnosti, ktoré nás zaujímajú v tomto JSON a spustiť hák iba keď sa zmenia. Je tu na to pole jqFilter, kde musíte zadať výraz jq, ktorý sa použije na manifest JSON.

Ak chcete napríklad reagovať na zmeny v návestiach objektov nasadenia, musíte pole filtrovať labels mimo poľa metadata. Konfigurácia bude takáto:

cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "deployment",
  "event":["update"],
  "jqFilter": ".metadata.labels"
}
]}
EOF

Tento výraz jqFilter zmení dlhý manifest JSON Deployment na krátky JSON s menovkami:

Predstavujeme shell-operátor: vytváranie operátorov pre Kubernetes je teraz jednoduchšie

shell-operátor spustí hák iba vtedy, keď sa tento krátky JSON zmení, a zmeny ostatných vlastností budú ignorované.

Kontext spustenia háku

Konfigurácia háku vám umožňuje určiť niekoľko možností pre udalosti - napríklad 2 možnosti pre udalosti z Kubernetes a 2 plány:

{"onKubernetesEvent":[
  {"name":"OnCreatePod",
  "kind": "pod",
  "event":["add"]
  },
  {"name":"OnModifiedNamespace",
  "kind": "namespace",
  "event":["update"],
  "jqFilter": ".metadata.labels"
  }
],
"schedule": [
{ "name":"every 10 min",
  "crontab":"* */10 * * * *"
}, {"name":"on Mondays at 12:10",
"crontab": "* 10 12 * * 1"
]}

Malá odbočka: áno, podpora operátorov shellu spúšťanie skriptov v štýle crontab. Viac podrobností nájdete v dokumentáciu.

Aby bolo možné rozlíšiť, prečo bol hák spustený, shell-operátor vytvorí dočasný súbor a odovzdá cestu k nemu v premennej háku BINDING_CONTEXT_TYPE. Súbor obsahuje JSON popis dôvodu spustenia háku. Napríklad každých 10 minút sa spustí hák s nasledujúcim obsahom:

[{ "binding": "every 10 min"}]

...a v pondelok to začne takto:

[{ "binding": "every 10 min"}, { "binding": "on Mondays at 12:10"}]

pre onKubernetesEvent Bude viac spúšťačov JSON, pretože obsahuje popis objektu:

[
 {
 "binding": "onCreatePod",
 "resourceEvent": "add",
 "resourceKind": "pod",
 "resourceName": "foo",
 "resourceNamespace": "bar"
 }
]

Obsah polí možno pochopiť z ich názvov a ďalšie podrobnosti si môžete prečítať dokumentáciu. Príklad získania názvu zdroja z poľa resourceName použitie jq sa už ukázalo v háku, ktorý replikuje tajomstvá:

jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH

Podobným spôsobom môžete získať ďalšie polia.

Čo bude ďalej?

V projektovom úložisku, v /examples adresáre, existujú príklady hákov, ktoré sú pripravené na spustenie v klastri. Pri písaní vlastných háčikov ich môžete použiť ako základ.

Existuje podpora pre zhromažďovanie metrík pomocou Prometheus – dostupné metriky sú popísané v časti METRIKA.

Ako asi tušíte, shell-operátor je napísaný v Go a distribuovaný pod licenciou Open Source (Apache 2.0). Budeme vďační za každú rozvojovú pomoc projekt na GitHub: a hviezdy, problémy a požiadavky na stiahnutie.

Po odstránení závoja tajomstva vás budeme informovať aj o tom, že škrupinový operátor je malý súčasť nášho systému, ktorá dokáže aktualizovať doplnky nainštalované v klastri Kubernetes a vykonávať rôzne automatické akcie. Prečítajte si viac o tomto systéme povedal doslova v pondelok na HighLoad++ 2019 v Petrohrade - video a prepis tejto reportáže čoskoro zverejníme.

Máme v pláne otvoriť zvyšok systému: operátora doplnkov a našu zbierku háčikov a modulov. Mimochodom, addon-operátor už je k dispozícii na github, ale dokumentácia k nemu je stále na ceste. Vydanie kolekcie modulov je plánované na leto.

Zostaňte naladení!

PS

Prečítajte si aj na našom blogu:

Zdroj: hab.com

Pridať komentár