Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

Na našem blogu už o tom byly články možnosti operátora v Kubernetes a jak napište jednoduchý operátor sami. Tentokrát bychom vám rádi představili naše Open Source řešení, které posouvá tvorbu operátorů na super-snadnou úroveň – podívejte se shell-operátor!

Proč?

Myšlenka shell-operátora je poměrně jednoduchá: přihlaste se k odběru událostí z objektů Kubernetes, a když jsou tyto události přijaty, spusťte externí program, který mu poskytne informace o události:

Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

Jeho potřeba vyvstala, když se během provozu clusterů začaly objevovat drobné úkoly, které jsme opravdu chtěli automatizovat tím správným způsobem. Všechny tyto malé úkoly byly vyřešeny pomocí jednoduchých bash skriptů, i když, jak víte, je lepší psát operátory v Golangu. Investice do komplexního rozvoje operátora pro každý takový malý úkol by samozřejmě byla neefektivní.

Operátor za 15 minut

Podívejme se na příklad toho, co lze automatizovat v clusteru Kubernetes a jak může pomoci operátor shellu. Příklad by mohl být následující: replikace tajného klíče pro přístup k registru dockerů.

Pody, které používají obrázky ze soukromého registru, musí ve svém manifestu obsahovat odkaz na tajný klíč s daty pro přístup do registru. Toto tajemství musí být vytvořeno v každém jmenném prostoru před vytvořením podů. To lze provést ručně, ale pokud nastavíme dynamická prostředí, jmenný prostor pro jednu aplikaci bude hodně. A pokud také nejsou 2-3 aplikace... počet tajemství bude velmi velký. A ještě něco k tajemstvím: rád bych čas od času změnil klíč pro přístup do registru. Nakonec, manuální operace jako řešení zcela neúčinné — potřebujeme automatizovat vytváření a aktualizaci tajemství.

Jednoduchá automatizace

Pojďme napsat shell skript, který se spustí jednou za N sekund a zkontroluje jmenné prostory na přítomnost tajemství, a pokud žádné tajemství neexistuje, pak se vytvoří. Výhodou tohoto řešení je, že v cronu vypadá jako shell skript – klasický a všem srozumitelný přístup. Nevýhodou je, že v intervalu mezi jeho spuštěním může být vytvořen nový jmenný prostor a nějakou dobu zůstane bez tajemství, což povede k chybám při spouštění modulů.

Automatizace s operátorem shellu

Aby náš skript správně fungoval, je třeba klasické spuštění cronu nahradit spuštěním při přidání jmenného prostoru: v tomto případě můžete před jeho použitím vytvořit tajemství. Podívejme se, jak to implementovat pomocí shell-operator.

Nejprve se podívejme na scénář. Skripty ve smyslu operátora shellu se nazývají háky. Každý háček při běhu s vlajkou --config informuje shell-operátora o svých vazbách, tzn. na jaké akce by měla být zahájena. V našem případě použijeme onKubernetesEvent:

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

Zde je popsáno, že máme zájem přidat události (add) objekty typu namespace.

Nyní musíte přidat kód, který bude spuštěn, když dojde k události:

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

Skvělý! Výsledkem byl malý, krásný scénář. K jeho „oživení“ zbývají dva kroky: připravit obraz a spustit jej v clusteru.

Příprava obrázku s háčkem

Pokud se podíváte na skript, můžete vidět, že příkazy jsou použity kubectl и jq. To znamená, že obrázek musí mít následující věci: náš hook, shell-operátor, který bude monitorovat události a spouštět hook, a příkazy používané hookem (kubectl a jq). Hub.docker.com již má hotový obrázek, ve kterém jsou zabaleny shell-operator, kubectl a jq. Zbývá jen přidat jednoduchý háček 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

Běh v clusteru

Podívejme se znovu na háček a tentokrát si zapišme, jaké akce a s jakými objekty ve shluku provádí:

  1. přihlašuje se k událostem vytváření jmenného prostoru;
  2. vytvoří tajemství v jiných jmenných prostorech, než ve kterých je spuštěn.

Ukázalo se, že pod, ve kterém bude náš obrázek spuštěn, musí mít oprávnění k provádění těchto akcí. To lze provést vytvořením vlastního servisního účtu. Povolení musí být provedeno ve formě ClusterRole a ClusterRoleBinding, protože zajímají nás objekty z celého shluku.

Konečný popis v YAML bude vypadat nějak 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

Sestavený obraz můžete spustit jako jednoduché nasazení:

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

Pro usnadnění je vytvořen samostatný jmenný prostor, kde bude spuštěn shell-operátor a vytvořené manifesty budou použity:

$ 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še: spustí se shell-operátor, přihlásí se k událostem vytváření jmenného prostoru a spustí hák, když je potřeba.

Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

To znamená, že jednoduchý shell skript se pro Kubernetes proměnil ve skutečný operátor a funguje jako součást clusteru. A to vše bez složitého procesu vývoje operátorů v Golangu:

Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

V této věci je další ilustrace...Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

Jeho význam poodhalíme podrobněji v některé z následujících publikací.

filtrování

Sledování objektů je dobré, ale často je potřeba reagovat změna některých vlastností objektu, například změnit počet replik v Deployment nebo změnit popisky objektů.

Když přijde událost, operátor shellu obdrží manifest JSON objektu. Můžeme vybrat vlastnosti, které nás v tomto JSON zajímají, a spustit hák pouze když se změní. Existuje pro to pole jqFilter, kde musíte zadat výraz jq, který bude použit na manifest JSON.

Chcete-li například reagovat na změny štítků pro objekty nasazení, musíte pole filtrovat labels z pole metadata. Konfigurace bude vypadat takto:

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

Tento výraz jqFilter změní dlouhý manifest JSON Deployment na krátký JSON s popisky:

Představujeme shell-operator: vytváření operátorů pro Kubernetes je nyní jednodušší

shell-operator spustí zavěšení pouze tehdy, když se tento krátký JSON změní, a změny ostatních vlastností budou ignorovány.

Kontext spuštění háku

Konfigurace háku vám umožňuje zadat několik možností pro události - například 2 možnosti pro události 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: ano, podpora operátorů shellu spouštění skriptů ve stylu crontab. Více podrobností naleznete v dokumentace.

Aby bylo možné rozlišit, proč byl hák spuštěn, vytvoří operátor shell dočasný soubor a předá cestu k němu v proměnné háku BINDING_CONTEXT_TYPE. Soubor obsahuje JSON popis důvodu spuštění háku. Například každých 10 minut se spustí háček s následujícím obsahem:

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

... a v pondělí to začne takto:

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

pro onKubernetesEvent Bude více spouštěčů JSON, protože obsahuje popis objektu:

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

Obsah polí lze pochopit z jejich názvů a lze si přečíst další podrobnosti dokumentace. Příklad získání názvu zdroje z pole resourceName použití jq již bylo ukázáno v háku, který replikuje tajemství:

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

Podobným způsobem můžete získat další pole.

Co bude dál?

V úložišti projektu, v /examples adresáře, existují příklady háčků, které jsou připraveny ke spuštění na clusteru. Při psaní vlastních háčků je můžete použít jako základ.

Existuje podpora pro shromažďování metrik pomocí Prometheus – dostupné metriky jsou popsány v části METRIKA.

Jak asi tušíte, shell-operátor je napsán v Go a distribuován pod licencí Open Source (Apache 2.0). Budeme vděční za jakoukoli rozvojovou pomoc projekt na GitHubu: a hvězdičky a problémy a požadavky na vytažení.

Po odstranění závoje tajemství vás také informujeme, že shell-operátor je malý součást našeho systému, která dokáže udržovat doplňky nainstalované v clusteru Kubernetes aktuální a provádět různé automatické akce. Přečtěte si více o tomto systému řekl doslova v pondělí na HighLoad++ 2019 v St. Petersburgu - brzy zveřejníme video a přepis této reportáže.

Máme v plánu otevřít zbytek tohoto systému: operátor addonů a naši sbírku háčků a modulů. Mimochodem, addon-operátor už je k dispozici na githubu, ale dokumentace k němu je stále na cestě. Vydání kolekce modulů je plánováno na léto.

Zůstaňte naladěni!

PS

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář