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:
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:
Pogledajmo ponovno kuku i ovaj put zapišimo koje akcije i s kojim objektima izvodi u klasteru:
pretplaćuje se na događaje stvaranja prostora imena;
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:
To je sve: shell-operator će se pokrenuti, pretplatiti na događaje stvaranja prostora imena i pokrenuti kuku kada je to potrebno.
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:
Postoji još jedna ilustracija na ovu temu...
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:
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:
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.