Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

Na našem blogu već je bilo članaka koji govore o tome mogućnosti operatera u Kubernetesu i kako sami napišite jednostavan operator. Ovog puta želimo vam predstaviti naše Open Source rješenje, koje kreiranje operatora podiže na super jednostavnu razinu - pogledajte ljuska-operator!

Zašto?

Ideja ljuske-operatora prilično je jednostavna: pretplatite se na događaje iz Kubernetes objekata, a kada se ti događaji prime, pokrenite vanjski program dajući mu informacije o događaju:

Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

Potreba za njim javila se kada su se tijekom rada klastera počeli pojavljivati ​​sitni zadaci koje smo zaista željeli automatizirati na pravi način. Svi ovi mali zadaci riješeni su pomoću jednostavnih bash skripti, iako je, kao što znate, bolje pisati operatore u Golangu. Očito, ulaganje u sveobuhvatni razvoj operatera za svaki tako mali zadatak bilo bi neučinkovito.

Operater za 15 minuta

Pogledajmo primjer onoga što se može automatizirati u Kubernetes klasteru i kako shell-operator može pomoći. Primjer bi bio sljedeći: repliciranje tajne za pristup docker registru.

Podovi koji koriste slike iz privatnog registra moraju u svom manifestu sadržavati poveznicu na tajnu s podacima za pristup registru. Ova tajna mora biti kreirana u svakom prostoru imena prije stvaranja mahuna. To se može učiniti ručno, ali ako postavimo dinamička okruženja, tada će imenski prostor za jednu aplikaciju postati velik. A ako nema 2-3 prijave... broj tajni postaje jako velik. I još nešto o tajnama: želio bih povremeno promijeniti ključ za pristup registru. Eventualno, ručne operacije kao rješenje potpuno neučinkovito — moramo automatizirati stvaranje i ažuriranje tajni.

Jednostavna automatizacija

Napišimo shell skriptu koja se pokreće jednom svakih N sekundi i provjerava prostore imena za prisustvo tajne, a ako tajne nema, onda se ona kreira. Prednost ovog rješenja je što izgleda kao shell skripta u cron-u - klasičan i svima razumljiv pristup. Loša strana je što se u intervalu između njegovih pokretanja može stvoriti novi imenski prostor i neko će vrijeme ostati bez tajne, što će dovesti do pogrešaka u pokretanju podova.

Automatizacija s shell-operatorom

Da bi naša skripta radila ispravno, klasično pokretanje crona treba zamijeniti pokretanjem kada se doda imenski prostor: u ovom slučaju možete stvoriti tajnu prije nego je upotrijebite. Pogledajmo kako to implementirati pomoću shell-operatora.

Prvo, pogledajmo scenarij. Skripte u smislu operatora ljuske nazivaju se kuke. Svaki hook kada se izvodi sa zastavicom --config obavještava operatera ljuske o svojim vezama, tj. na koje događaje treba pokrenuti. U našem slučaju ćemo koristiti onKubernetesEvent:

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

Ovdje je opisano da smo zainteresirani za dodavanje događaja (add) objekti tipa namespace.

Sada trebate dodati kod koji će se izvršiti kada se događaj dogodi:

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

Sjajno! Rezultat je bio mali, prekrasan scenarij. Za “oživljavanje” preostala su dva koraka: pripremiti sliku i pokrenuti je u klasteru.

Priprema slike s kukom

Ako pogledate skriptu, možete vidjeti da se koriste naredbe kubectl и jq. To znači da slika mora imati sljedeće stvari: našu kuku, operatora ljuske koji će pratiti događaje i pokretati kuku, te naredbe koje koristi kuka (kubectl i jq). Hub.docker.com već ima gotovu sliku u kojoj su upakirani shell-operator, kubectl i jq. Ostaje samo dodati jednostavnu kuku 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

Trčanje u klasteru

Pogledajmo ponovno kuku i ovaj put zapišimo koje akcije i s kojim objektima izvodi u klasteru:

  1. pretplaćuje se na događaje stvaranja prostora imena;
  2. stvara tajnu u prostorima imena osim onog u kojem je pokrenuta.

Ispada da pod u kojem će se pokrenuti naša slika mora imati dopuštenja za obavljanje ovih radnji. To možete učiniti stvaranjem vlastitog ServiceAccount-a. Dozvola mora biti u obliku ClusterRole i ClusterRoleBinding, jer zanimaju nas objekti iz cijelog klastera.

Konačni opis u YAML-u izgledat će otprilike ovako:

---
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

Sastavljenu sliku možete pokrenuti kao jednostavnu implementaciju:

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

Radi praktičnosti, kreiran je zaseban prostor imena gdje će se pokrenuti operator ljuske i primijeniti kreirani manifesti:

$ 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 sve: shell-operator će se pokrenuti, pretplatiti na događaje stvaranja prostora imena i pokrenuti kuku kada je to potrebno.

Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

Dakle, jednostavna shell skripta pretvorena u pravi operator za Kubernetes i radi kao dio klastera. I sve to bez složenog procesa razvoja operatera u Golangu:

Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

Postoji još jedna ilustracija na ovu temu...Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

Njegovo značenje ćemo detaljnije otkriti u jednoj od sljedećih publikacija.

filtriranje

Praćenje objekata je dobro, ali često postoji potreba za reakcijom mijenjanje nekih svojstava objekta, na primjer, za promjenu broja replika u postavljanju ili za promjenu oznaka objekta.

Kada stigne događaj, shell-operator prima JSON manifest objekta. Možemo odabrati svojstva koja nas zanimaju u ovom JSON-u i pokrenuti kuku samo kada se mijenjaju. Postoji polje za ovo jqFilter, gdje trebate navesti jq izraz koji će se primijeniti na JSON manifest.

Na primjer, da biste odgovorili na promjene u oznakama za objekte implementacije, morate filtrirati polje labels izvan polja metadata. Konfiguracija će biti ovakva:

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

Ovaj jqFilter izraz pretvara dugi JSON manifest Deploymenta u kratki JSON s oznakama:

Predstavljamo shell-operator: stvaranje operatora za Kubernetes upravo je postalo lakše

shell-operator pokrenut će kuku samo kada se ovaj kratki JSON promijeni, a promjene ostalih svojstava bit će zanemarene.

Kontekst pokretanja kuke

Konfiguracija kuke omogućuje vam da odredite nekoliko opcija za događaje - na primjer, 2 opcije za događaje iz Kubernetesa i 2 rasporeda:

{"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"
]}

Mala digresija: da, shell-operator podržava pokretanje skripti u stilu crontab. Više detalja možete pronaći u dokumentacija.

Kako bi razlučio zašto je hook pokrenut, shell-operator stvara privremenu datoteku i prosljeđuje stazu do nje u varijabli hooku BINDING_CONTEXT_TYPE. Datoteka sadrži JSON opis razloga pokretanja kuke. Na primjer, svakih 10 minuta kuka će se pokrenuti sa sljedećim sadržajem:

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

...a u ponedjeljak počinje ovim:

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

za onKubernetesEvent Bit će više JSON okidača, jer sadrži opis objekta:

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

Sadržaj polja može se razumjeti iz njihovih naziva, a više detalja možete pročitati u dokumentacija. Primjer dobivanja naziva resursa iz polja resourceName korištenje jq već je prikazano u kuki koja replicira tajne:

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

Na sličan način možete dobiti i druga polja.

Što je sljedeće?

U repozitoriju projekta, u /primjeri imenika, postoje primjeri kuka koje su spremne za pokretanje na klasteru. Kada pišete vlastite hookove, možete ih koristiti kao osnovu.

Postoji podrška za prikupljanje metrika pomoću Prometheusa - dostupne metrike opisane su u odjeljku METRIKA.

Kao što možda pretpostavljate, shell-operator je napisan u Go i distribuiran pod licencom otvorenog koda (Apache 2.0). Bit ćemo zahvalni za svaku razvojnu pomoć projekt na GitHubu: i zvjezdice, i problemi, i zahtjevi za povlačenjem.

Podižući veo tajne, također ćemo vas obavijestiti da je Shell-operator mali dio našeg sustava koji može održavati dodatke instalirane u Kubernetes klasteru ažurnima i izvoditi razne automatske radnje. Pročitajte više o ovom sustavu rekao doslovno u ponedjeljak na HighLoad++ 2019 u St. Petersburgu - uskoro ćemo objaviti video i transkript ovog izvješća.

Imamo plan za otvaranje ostatka ovog sustava: addon-operatora i naše kolekcije kuka i modula. Usput, addon-operator već postoji dostupno na githubu, no dokumentacija za njega je još u pripremi. Izdavanje kolekcije modula planirano je za ljeto.

Ostani u tunelu!

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar