Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

8. travnja na konferenciji Saint HighLoad++ 2019, u sklopu sekcije “DevOps and Operations” održano je izvješće “Expanding and complementing Kubernetes” u čijoj su izradi sudjelovala tri djelatnika tvrtke Flant. U njemu govorimo o brojnim situacijama u kojima smo željeli proširiti i nadopuniti mogućnosti Kubernetesa, ali za koje nismo pronašli gotovo i jednostavno rješenje. Imamo potrebna rješenja u obliku Open Source projekata, a njima je posvećen i ovaj govor.

Po tradiciji, sa zadovoljstvom predstavljamo video izvještaja (50 minuta, mnogo informativnije od članka) i glavni sažetak u obliku teksta. Ići!

Jezgra i dodaci u K8s

Kubernetes mijenja industriju i pristupe administraciji koji su odavno uspostavljeni:

  • Zahvaljujući njemu apstrakcije, više ne radimo s konceptima poput postavljanja konfiguracije ili pokretanja naredbe (Chef, Ansible...), već koristimo grupiranje spremnika, usluga itd.
  • Možemo pripremiti aplikacije bez razmišljanja o nijansama određeno mjesto, na kojem će se pokrenuti: bare metal, cloud nekog od providera itd.
  • Uz K8s nikada niste bili pristupačniji najbolje prakse o organiziranju infrastrukture: tehnike skaliranja, samoiscjeljivanje, tolerancija na pogreške itd.

No, naravno, nije sve tako glatko: Kubernetes je donio i svoje nove izazove.

Kubernetes ne je kombajn koji rješava sve probleme svih korisnika. Jezgra Kubernetes je odgovoran samo za skup minimalno potrebnih funkcija koje su prisutne u svaki Klastera:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Jezgra Kubernetes definira osnovni skup primitiva za grupiranje spremnika, upravljanje prometom i tako dalje. O njima smo detaljnije razgovarali u izvještaj prije 2 godine.

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

S druge strane, K8s nudi velike mogućnosti za proširenje dostupnih funkcija, koje pomažu zatvoriti druge - specifično — potrebe korisnika. Dodaci Kubernetesu odgovornost su administratora klastera, koji moraju instalirati i konfigurirati sve što je potrebno kako bi svoj klaster doveli u “pravu formu” [kako bi riješili svoje specifične probleme]. Kakvi su to dodaci? Pogledajmo neke primjere.

Primjeri dodataka

Nakon što smo instalirali Kubernetes, mogli bismo se iznenaditi da umrežavanje koje je toliko potrebno za interakciju podova unutar čvora i između čvorova ne radi samostalno. Kubernetes kernel ne jamči potrebne veze; umjesto toga, on određuje mrežu sučelje (CNI) za dodatke trećih strana. Moramo instalirati jedan od ovih dodataka, koji će biti odgovoran za konfiguraciju mreže.

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Bliski primjer su rješenja za pohranu podataka (lokalni disk, mrežni blok uređaj, Ceph...). U početku su bili u jezgri, ali s pojavom CSI situacija se mijenja u nešto slično već opisanom: sučelje je u Kubernetesu, a njegova implementacija u modulima trećih strana.

Ostali primjeri uključuju:

  • Ulaz-kontrolori (pogledajte njihovu recenziju u naš nedavni članak).
  • cert-menadžer:

    Proširenje i dopuna Kubernetesa (pregled i video izvješće)

  • operatori je cijela klasa dodataka (koja uključuje i spomenuti cert-manager), oni definiraju primitiv(e) i kontroler(e). Logika njihovog rada ograničena je samo našom maštom i omogućuje nam da gotove infrastrukturne komponente (na primjer, DBMS) pretvorimo u primitivne, s kojima je puno lakše raditi (nego sa skupom spremnika i njihovim postavkama). Napisan je ogroman broj operatera - čak i ako mnogi od njih još nisu spremni za proizvodnju, samo je pitanje vremena:

    Proširenje i dopuna Kubernetesa (pregled i video izvješće)

  • Metrika - još jedna ilustracija kako je Kubernetes odvojio sučelje (Metrics API) od implementacije (third-party add-ons kao što su Prometheus adapter, Datadog cluster agent...).
  • za praćenje i statistika, gdje su u praksi ne samo potrebni Prometej i Grafana, ali i kube-state-metrics, node-exporter itd.

I ovo nije potpuni popis dodataka... Na primjer, u tvrtki Flant trenutno instaliramo 29 dodataka (svi stvaraju ukupno 249 Kubernetes objekata). Jednostavno rečeno, ne možemo vidjeti život klastera bez dodataka.

Automatizacija

Operatori su dizajnirani za automatizaciju rutinskih operacija s kojima se susrećemo svaki dan. Evo primjera iz stvarnog života za koje bi pisanje operatora bilo izvrsno rješenje:

  1. Postoji privatni (tj. koji zahtijeva prijavu) registar sa slikama za aplikaciju. Pretpostavlja se da je svakom modulu dodijeljena posebna tajna koja omogućuje autentifikaciju u registru. Naš je zadatak osigurati da se ta tajna pronađe u prostoru imena kako bi podovi mogli preuzimati slike. Može postojati mnogo aplikacija (svaka od njih treba tajnu), a korisno je redovito ažurirati same tajne, tako da se eliminira mogućnost ručnog postavljanja tajni. Tu u pomoć dolazi operator: kreiramo kontroler koji će čekati da se namespace pojavi i na temelju tog događaja dodati tajnu u imenski prostor.
  2. Neka prema zadanim postavkama pristup Internetu iz mahuna je zabranjen. Ali ponekad može biti potrebno: logično je da mehanizam dopuštenja pristupa radi jednostavno, bez potrebe za određenim vještinama, na primjer, prisutnošću određene oznake u prostoru imena. Kako nam operater tu može pomoći? Stvoren je kontroler koji čeka da se oznaka pojavi u prostoru imena i dodaje odgovarajuću politiku za pristup Internetu.
  3. Slična situacija: pretpostavimo da trebamo dodati određeni zaprljati, ako ima sličnu oznaku (s nekom vrstom prefiksa). Radnje s operaterom su očite...

U svakom klasteru moraju se rješavati rutinski zadaci, i ispravno to se može učiniti pomoću operatora.

Sumirajući sve opisane priče, došli smo do zaključka da za udoban rad u Kubernetesu koji vam je potreban: A) instalirati dodatke, b) razviti operatore (za rješavanje svakodnevnih administratorskih zadataka).

Kako napisati izjavu za Kubernetes?

Općenito, shema je jednostavna:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

... ali onda se ispostavi da:

  • Kubernetes API prilično je netrivijalna stvar za čije svladavanje treba puno vremena;
  • programiranje također nije za svakoga (jezik Go odabran je kao preferirani jezik jer za njega postoji poseban okvir - Operator SDK);
  • Slična je situacija i sa samim okvirom.

Dno crta: napisati kontroler (operator) mora potrošiti značajna sredstva proučavati materijal. To bi bilo opravdano za "velike" operatore - recimo, za MySQL DBMS. Ali ako se prisjetimo gore opisanih primjera (otkrivanje tajni, pristup podovima na Internet...), koje također želimo učiniti ispravno, tada ćemo shvatiti da će uloženi trud nadmašiti rezultat koji nam je sada potreban:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Općenito, postavlja se dilema: potrošiti puno resursa i pronaći pravi alat za pisanje izjava ili to učiniti na staromodan način (ali brzo). Kako bismo to riješili – kako bismo pronašli kompromis između ovih krajnosti – kreirali smo vlastiti projekt: ljuska-operator (vidi također njegov nedavna objava na čvorištu).

Shell-operator

Kako on radi? Klaster ima pod koji sadrži Go binarnu datoteku s operatorom ljuske. Pored njega je set od udice (više detalja o njima - vidi dolje). Sam operator ljuske pretplaćuje se na određene kretanja u Kubernetes API-ju, nakon čega pokreće odgovarajuće hookove.

Kako shell-operator zna koje kuke pozvati na koje događaje? Ove informacije operateru školjke prenose same kuke, a one to rade vrlo jednostavno.

Hook je Bash skripta ili bilo koja druga izvršna datoteka koja prihvaća jedan argument --config i odgovara s JSON-om. Potonji određuje koji su objekti od interesa za njega i na koje događaje (za te objekte) treba odgovoriti:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Ilustrirat ću implementaciju na shell-operatoru jednog od naših primjera - razlaganje tajni za pristup privatnom registru sa slikama aplikacije. Sastoji se od dvije etape.

Vježbajte: 1. Napišite kuku

Prije svega, u kuku koju ćemo obraditi --config, što znači da nas zanimaju prostori imena, točnije trenutak njihovog nastanka:

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

Kako bi izgledala logika? Također vrlo jednostavno:

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

Prvi korak je saznati koji je imenski prostor kreiran, a drugi je kreirati ga pomoću kubectl tajna za ovaj imenski prostor.

Vježbajte: 2. Sastavljanje slike

Sve što preostaje je proslijediti kreiranu kuku operatoru ljuske - kako to učiniti? Sam shell-operator dolazi kao Docker slika, tako da je naš zadatak dodati kuku u poseban direktorij na ovoj slici:

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

Ostaje samo da ga sastavite i gurnete:

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

Posljednji dodir je implementacija slike u klaster. Da bismo to učinili, napišimo razvoj:

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

Postoje dvije točke na koje treba obratiti pozornost:

  1. indikacija novostvorene slike;
  2. Ovo je komponenta sustava koja (najmanje) treba prava za pretplatu na događaje u Kubernetesu i za dodjelu tajni imenskim prostorima, tako da stvaramo ServiceAccount (i skup pravila) za kuku.

Rezultat - riješili smo problem rodbina za Kubernetes na način da stvara operator za razlaganje tajni.

Ostale značajke operatora ljuske

Da biste ograničili objekte odabrane vrste s kojima će kuka raditi, mogu se filtrirati, birajući prema određenim oznakama (ili koristeći matchExpressions):

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

Pod uvjetom mehanizam deduplikacije, koji - pomoću jq filtera - omogućuje pretvaranje velikih JSON objekata u male, gdje ostaju samo oni parametri čije promjene želimo pratiti.

Kada se kuka pozove, shell-operator je prosljeđuje podaci o objektu, koji se može koristiti za sve potrebe.

Događaji koji pokreću kuke nisu ograničeni na Kubernetes događaje: operator ljuske pruža podršku za dozivanje udica po vremenu (slično crontabu u tradicionalnom rasporedu), kao i poseban događaj Na početku. Svi ti događaji mogu se kombinirati i dodijeliti istoj kuki.

I još dvije značajke shell-operatora:

  1. Radi asinkrono. Budući da je primljen Kubernetes događaj (kao što je kreiranje objekta), drugi događaji (kao što je brisanje istog objekta) mogli su se dogoditi u klasteru, a kuke moraju to uzeti u obzir. Ako je kuka izvršena s pogreškom, tada će prema zadanim postavkama biti podsjetiti do uspješnog završetka (ovo se ponašanje može promijeniti).
  2. Izvozi metrika za Prometheus, s kojim možete saznati radi li operator ljuske, saznati broj pogrešaka za svaku kuku i trenutnu veličinu reda čekanja.

Da rezimiramo ovaj dio izvješća:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Instalacija dodataka

Za ugodan rad s Kubernetesom spomenuta je i potreba za instaliranjem dodataka. Reći ću vam o tome na primjeru puta naše tvrtke do načina na koji to sada radimo.

Počeli smo raditi s Kubernetesom s nekoliko klastera kojima je jedini dodatak bio Ingress. Trebalo ga je drugačije instalirati u svaki klaster, a mi smo napravili nekoliko YAML konfiguracija za različita okruženja: bare metal, AWS...

Kako je bilo više klastera, bilo je i više konfiguracija. Osim toga, poboljšali smo same te konfiguracije, zbog čega su postale prilično heterogene:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Da sve posložimo, počeli smo sa skriptom (install-ingress.sh), koji je kao argument uzeo vrstu klastera na koji ćemo se implementirati, generirao potrebnu YAML konfiguraciju i izveo je u Kubernetes.

Ukratko, naš daljnji put i rezoniranje vezano uz njega bili su sljedeći:

  • za rad s YAML konfiguracijama potreban je predložak (u prvim fazama to je jednostavan sed);
  • s povećanjem broja klastera pojavila se potreba za automatskim ažuriranjem (najranije rješenje je bilo staviti skriptu u Git, ažurirati je pomoću crona i pokrenuti);
  • sličan scenarij bio je potreban za Prometej (install-prometheus.sh), međutim, ističe se po tome što zahtijeva puno više ulaznih podataka, kao i njihovu pohranu (u dobrom smislu - centralizirano i klasterski), a neki podaci (lozinke) mogli bi se automatski generirati:

    Proširenje i dopuna Kubernetesa (pregled i video izvješće)

  • rizik od uvođenja nečeg pogrešnog u sve veći broj klastera stalno je rastao, pa smo shvatili da instalateri (tj. dva scenarija: za Ingress i Prometheus) bilo je potrebno staging (nekoliko grana u Gitu, nekoliko cron-ova za ažuriranje u odgovarajućim: stabilnim ili testnim klasterima);
  • с kubectl apply postalo je teško raditi s njim jer nije deklarativan i može samo kreirati objekte, ali ne i donositi odluke o njihovom statusu/brisati ih;
  • Nedostajale su nam neke funkcije koje u to vrijeme uopće nismo implementirali:
    • punu kontrolu nad rezultatom ažuriranja klastera,
    • automatsko određivanje nekih parametara (unos za instalacijske skripte) na temelju podataka koji se mogu dobiti iz klastera (discovery),
    • njegov logičan razvoj u obliku neprekidnog otkrivanja.

Sva ta stečena iskustva implementirali smo u okviru našeg drugog projekta - addon-operator.

Addon-operator

Temelji se na već spomenutom shell-operatoru. Cijeli sustav izgleda ovako:

Sljedeće je dodano kukicama operatora ljuske:

  • pohranjivanje vrijednosti,
  • Shema kormila,
  • komponenta koja prati pohranu vrijednosti i - u slučaju bilo kakvih promjena - traži od Helma da ponovno okrene kartu.

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Dakle, možemo reagirati na događaj u Kubernetesu, pokrenuti kuku, i iz te kuke možemo napraviti promjene u pohrani, nakon čega će se grafikon ponovno preuzeti. U rezultirajućem dijagramu razdvajamo skup kuka i grafikon u jednu komponentu koju nazivamo modul:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Može postojati mnogo modula, a njima dodajemo globalne kuke, globalnu pohranu vrijednosti i komponentu koja nadzire tu globalnu pohranu.

Sada, kada se nešto dogodi u Kubernetesu, možemo na to reagirati koristeći globalnu kuku i promijeniti nešto u globalnoj trgovini. Ova će se promjena primijetiti i uzrokovat će uvođenje svih modula u klasteru:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Ova shema zadovoljava sve zahtjeve za instaliranje dodataka koji su gore navedeni:

  • Helm je odgovoran za šablone i deklarativnost.
  • Problem automatskog ažuriranja riješen je korištenjem globalne kuke, koja odlazi u registar prema rasporedu i, ako tamo vidi novu sliku sustava, izbacuje je (tj. "samu").
  • Pohranjivanje postavki u klaster implementirano je pomoću ConfigMap, koji sadrži primarne podatke za pohranu (pri pokretanju se učitavaju u pohranu).
  • Problemi s generiranjem lozinki, otkrivanjem i kontinuiranim otkrivanjem riješeni su pomoću kuka.
  • Staging se postiže zahvaljujući oznakama koje Docker podržava odmah.
  • Rezultat se prati pomoću metrike pomoću koje možemo razumjeti status.

Cijeli ovaj sustav implementiran je u obliku jedne binarne datoteke u Gou, koja se naziva addon-operator. Ovo čini dijagram jednostavnijim:

Proširenje i dopuna Kubernetesa (pregled i video izvješće)

Glavna komponenta u ovom dijagramu je skup modula (istaknuto sivo ispod). Sada možemo uz malo truda napisati modul za traženi dodatak i biti sigurni da će biti instaliran u svakom klasteru, da će se ažurirati i odgovarati na događaje koji su mu potrebni u klasteru.

"Flant" koristi addon-operator na 70+ Kubernetes klastera. Trenutni status - alfa verzija. Sada pripremamo dokumentaciju za izdavanje beta verzije, ali za sada u repozitoriju dostupni primjeri, na temelju kojeg možete kreirati vlastiti addon.

Gdje mogu nabaviti module za addon-operator? Izdavanje naše biblioteke je za nas sljedeća faza, planiramo to učiniti na ljeto.

Video zapisi i slajdovi

Video s nastupa (~50 minuta):

Prezentacija izvješća:

PS

Ostala izvješća na našem blogu:

Možda će vas zanimati i sljedeće publikacije:

Izvor: www.habr.com

Dodajte komentar