Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

8. aprila na konferenci Saint HighLoad++ 2019, v sklopu sekcije “DevOps and Operations” je bilo podano poročilo “Expanding and complementing Kubernetes”, pri ustvarjanju katerega so sodelovali trije zaposleni v podjetju Flant. V njem govorimo o številnih situacijah, v katerih smo želeli razširiti in dopolniti zmožnosti Kubernetesa, a zanje nismo našli pripravljene in preproste rešitve. Imamo potrebne rešitve v obliki odprtokodnih projektov in tem je namenjen tudi ta govor.

Po tradiciji se z veseljem predstavljamo video poročila (50 minut, veliko bolj informativno kot članek) in glavni povzetek v besedilni obliki. Pojdi!

Jedro in dodatki v K8s

Kubernetes spreminja industrijo in pristope k administraciji, ki so že dolgo uveljavljeni:

  • Zahvaljujoč njemu abstrakcije, ne operiramo več s koncepti, kot je nastavitev konfiguracije ali izvajanje ukaza (Chef, Ansible...), temveč uporabljamo združevanje vsebnikov, storitev itd.
  • Prijave lahko pripravimo, ne da bi razmišljali o niansah določeno spletno mesto, na katerem bo zagnan: bare metal, oblak enega od ponudnikov ipd.
  • S K8s še nikoli niste bili bolj dostopni najboljše prakse o organiziranju infrastrukture: tehnike skaliranja, samozdravljenje, toleranca napak itd.

Vendar seveda ne gre vse tako gladko: Kubernetes je prinesel tudi svoje nove izzive.

Kubernetes ne je kombinat, ki rešuje vse težave vseh uporabnikov. Core Kubernetes je odgovoren samo za nabor minimalno potrebnih funkcij, ki so prisotne v vsak grozd:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Jedro Kubernetes definira osnovni nabor primitivov za združevanje vsebnikov, upravljanje prometa itd. O njih smo podrobneje govorili v poročilo 2 leti nazaj.

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Po drugi strani K8s ponuja odlične možnosti za razširitev razpoložljivih funkcij, ki pomagajo zapreti druge - specifična — potrebe uporabnikov. Za dodatke Kubernetesu so odgovorni skrbniki gruče, ki morajo namestiti in konfigurirati vse, kar je potrebno, da svojo gručo spravijo »v pravo obliko« [za rešitev svojih specifičnih težav]. Kakšni dodatki so to? Poglejmo si nekaj primerov.

Primeri dodatkov

Ko smo namestili Kubernetes, smo morda presenečeni, da omrežno povezovanje, ki je tako potrebno za interakcijo podov znotraj vozlišča in med vozlišči, ne deluje samo. Jedro Kubernetes ne zagotavlja potrebnih povezav, namesto tega določa omrežje vmesnik (CNI) za dodatke tretjih oseb. Namestiti moramo enega od teh dodatkov, ki bo odgovoren za konfiguracijo omrežja.

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Bližnji primer so rešitve za shranjevanje podatkov (lokalni disk, omrežna blokovna naprava, Ceph...). Sprva so bili v jedru, s pojavom pa CSI situacija se spremeni v nekaj podobnega že opisanemu: vmesnik je v Kubernetesu, njegova implementacija pa v modulih tretjih oseb.

Drugi primeri vključujejo:

  • Vstop- krmilniki (glej njihovo oceno v naš nedavni članek).
  • cert-manager:

    Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

  • Operaterji je cel razred dodatkov (kamor spada tudi omenjeni cert-manager), definirajo primitiv(e) in krmilnik(e). Logika njihovega dela je omejena le z našo domišljijo in nam omogoča, da že pripravljene komponente infrastrukture (na primer DBMS) spremenimo v primitive, s katerimi je veliko lažje delati (kot z nizom vsebnikov in njihovih nastavitev). Napisanih je ogromno število operaterjev - tudi če mnogi od njih še niso pripravljeni za proizvodnjo, je samo vprašanje časa:

    Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

  • Metrike - še ena ilustracija, kako je Kubernetes ločil vmesnik (Metrics API) od implementacije (dodatki tretjih oseb, kot je Prometheus adapter, Datadog cluster agent ...).
  • Za spremljanje in statistika, kjer v praksi niso potrebni samo Prometej in Grafana, ampak tudi kube-state-metrics, node-exporter itd.

In to še zdaleč ni popoln seznam dodatkov... Na primer, v podjetju Flant, ki ga trenutno montiramo 29 dodatkov (vsi skupaj ustvarijo 249 objektov Kubernetes). Preprosto povedano, ne moremo videti življenja grozda brez dodatkov.

Avtomatizacija

Operaterji so zasnovani tako, da avtomatizirajo rutinske operacije, s katerimi se srečujemo vsak dan. Tu so primeri iz resničnega življenja, za katere bi bilo pisanje operatorja odlična rešitev:

  1. Obstaja zasebni (tj. zahteva prijavo) register s slikami za aplikacijo. Predpostavlja se, da je vsakemu podu dodeljena posebna skrivnost, ki omogoča avtentikacijo v registru. Naša naloga je zagotoviti, da se ta skrivnost najde v imenskem prostoru, tako da lahko podi prenašajo slike. Aplikacij je lahko veliko (od katerih vsaka potrebuje skrivnost) in koristno je redno posodabljati same skrivnosti, tako da možnost ročnega postavljanja skrivnosti odpade. Tu na pomoč priskoči operater: izdelamo krmilnik, ki bo čakal na prikaz imenskega prostora in bo na podlagi tega dogodka v imenski prostor dodal skrivnost.
  2. Naj je privzeto prepovedan dostop iz podov do interneta. Toda včasih je morda potrebno: logično je, da mehanizem dovoljenj za dostop deluje preprosto, ne da bi zahteval posebne veščine, na primer zaradi prisotnosti določene oznake v imenskem prostoru. Kako nam lahko tukaj pomaga operater? Ustvari se krmilnik, ki čaka, da se oznaka prikaže v imenskem prostoru, in doda ustrezen pravilnik za dostop do interneta.
  3. Podobna situacija: recimo, da moramo dodati določeno madež, če ima podobno oznako (z neko predpono). Dejanja z operaterjem so očitna...

V vsakem grozdu je treba rešiti rutinske naloge in pravilno to je mogoče storiti z uporabo operatorjev.

Če povzamemo vse opisane zgodbe, smo prišli do zaključka, da za udobno delo v Kubernetesu potrebujete: A) namestite dodatke, b) razvijati operaterje (za reševanje vsakodnevnih skrbniških opravil).

Kako napisati izjavo za Kubernetes?

Na splošno je shema preprosta:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

... potem pa se izkaže, da:

  • Kubernetes API je precej netrivialna stvar, ki zahteva veliko časa za obvladovanje;
  • programiranje tudi ni za vsakogar (jezik Go je bil izbran kot prednostni jezik, ker zanj obstaja poseben okvir - SDK operaterja);
  • Podobno je s samim ogrodjem.

Bottom line: napisati krmilnik (operater) mora porabiti znatna sredstva študirati material. To bi bilo upravičeno za "velike" operaterje - recimo za MySQL DBMS. Toda če se spomnimo zgoraj opisanih primerov (razkrivanje skrivnosti, dostop do podov do interneta ...), ki jih prav tako želimo narediti pravilno, potem bomo razumeli, da bo vloženi trud odtehtal rezultat, ki ga zdaj potrebujemo:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Na splošno se pojavi dilema: porabiti veliko sredstev in najti pravi pripomoček za pisanje izjav ali pa to storiti na staromoden način (vendar hitro). Da bi to rešili – da bi našli kompromis med temi skrajnostmi – smo ustvarili lasten projekt: lupina-operater (glej tudi njegovo nedavna objava na vozlišču).

Operater lupine

Kako deluje? Gruča ima pod, ki vsebuje binarno datoteko Go z lupinskim operaterjem. Poleg njega je niz kavlji (več podrobnosti o njih - glej spodaj). Operater lupine se sam naroči na določene dogodki v Kubernetes API, ob pojavu katerega zažene ustrezne kljuke.

Kako lupinski operater ve, katere kljuke naj kliče pri katerih dogodkih? Te informacije upravljavcu lupine posredujejo sami kavlji in to storijo zelo preprosto.

Kavelj je skript Bash ali katera koli druga izvršljiva datoteka, ki sprejme en sam argument --config in odgovori z JSON. Slednji določa, kateri objekti so zanj zanimivi in ​​na katere dogodke (za te objekte) se je treba odzvati:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Ilustriral bom izvedbo na lupinskem operaterju enega od naših primerov - razgradnjo skrivnosti za dostop do zasebnega registra s slikami aplikacije. Sestavljen je iz dveh stopenj.

Vaja: 1. Napišite kavelj

Najprej v kljuki, ki jo bomo obdelali --config, kar pomeni, da nas zanimajo imenski prostori in natančneje trenutek njihovega nastanka:

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

Kakšna bi bila logika? Tudi precej preprosto:

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

Prvi korak je ugotoviti, kateri imenski prostor je bil ustvarjen, drugi pa je, da ga ustvarite z uporabo kubectl skrivnost za ta imenski prostor.

Vaja: 2. Sestavljanje slike

Vse, kar ostane, je, da ustvarjeni kavelj posredujemo operaterju lupine - kako to storiti? Sam operater lupine je na voljo kot Dockerjeva slika, zato je naša naloga dodati kavelj v poseben imenik na tej sliki:

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

Vse kar ostane je, da ga sestavite in potisnete:

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

Zadnji dotik je razmestitev slike v gručo. Če želite to narediti, napišite Deployment:

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

Pozorni morate biti na dve točki:

  1. navedba novo ustvarjene slike;
  2. To je sistemska komponenta, ki (vsaj) potrebuje pravice za naročanje na dogodke v Kubernetesu in za dodeljevanje skrivnosti imenskim prostorom, zato ustvarimo ServiceAccount (in nabor pravil) za kavelj.

Rezultat – rešili smo problem sorodniki za Kubernetes na način, ki ustvari operaterja za razgradnjo skrivnosti.

Druge funkcije lupinskega operaterja

Če želite omejiti predmete vaše izbrane vrste, s katerimi bo kljuka delovala, jih je mogoče filtrirati, izbiranje glede na določene oznake (ali uporabo matchExpressions):

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

Pod pogojem mehanizem deduplikacije, ki – z uporabo filtra jq – omogoča pretvorbo velikih objektov JSON v majhne, ​​kjer ostanejo samo tisti parametri, za katere želimo spremljati spremembe.

Ko je klicana kljuka, jo operater lupine posreduje podatke o predmetu, ki se lahko uporablja za vse potrebe.

Dogodki, ki sprožijo kljuke, niso omejeni na dogodke Kubernetes: operater lupine nudi podporo za klicanje kavljev po času (podobno kot crontab v tradicionalnem razporejevalniku), pa tudi poseben dogodek na začetku. Vse te dogodke je mogoče združiti in dodeliti istemu trnku.

In še dve funkciji lupinskega operaterja:

  1. Deluje asinhrono. Ker je bil prejet dogodek Kubernetes (na primer ustvarjen predmet), so se lahko v gruči zgodili drugi dogodki (na primer izbris istega predmeta) in kavlji morajo to upoštevati. Če je bila kavelj izvedena z napako, bo privzeto tako ponovni klic do uspešnega zaključka (to vedenje je mogoče spremeniti).
  2. Izvaža meritve za Prometheus, s katerim lahko razumete, ali lupinski operater deluje, ugotovite število napak za vsako kavelj in trenutno velikost čakalne vrste.

Če povzamem ta del poročila:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Nameščanje dodatkov

Za udobno delo s Kubernetesom je bila omenjena tudi potreba po namestitvi dodatkov. O tem vam bom povedal na primeru poti našega podjetja do tega, kako to počnemo zdaj.

S Kubernetesom smo začeli delati z več grozdi, edini dodatek k temu je bil Ingress. V vsako gručo ga je bilo treba namestiti drugače in naredili smo več konfiguracij YAML za različna okolja: bare metal, AWS ...

Ker je bilo več gruč, je bilo več konfiguracij. Poleg tega smo izboljšali same te konfiguracije, zaradi česar so postale precej heterogene:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Da bi vse uredili, smo začeli s skriptom (install-ingress.sh), ki je kot argument vzel vrsto gruče, v katero bomo razmestili, ustvaril potrebno konfiguracijo YAML in jo uvedel v Kubernetes.

Skratka, naša nadaljnja pot in sklepanje z njo je bilo sledeče:

  • za delo s konfiguracijami YAML je potreben mehanizem predlog (na prvih stopnjah je to preprost sed);
  • z večanjem števila gruč se je pojavila potreba po samodejnem posodabljanju (najzgodnejša rešitev je bila, da daš skripto v Git, jo posodobiš s cronom in zaženeš);
  • podoben scenarij je bil potreben za Prometheus (install-prometheus.sh), vendar je opazen po tem, da zahteva veliko več vhodnih podatkov, pa tudi njihovega shranjevanja (v dobrem smislu - centralizirano in v gruči), nekateri podatki (gesla) pa bi se lahko samodejno generirali:

    Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

  • tveganje, da bi kaj napačnega uvedli v vedno večje število gruč, je nenehno naraščalo, zato smo ugotovili, da namestitveni (tj. dva scenarija: za Ingress in Prometheus) potrebna je bila uprizoritev (več vej v Gitu, več kronov za posodobitev v ustreznih: stabilnih ali testnih gručah);
  • с kubectl apply z njim je postalo težko delati, ker ni deklarativen in lahko samo ustvarja objekte, ne pa tudi odloča o njihovem statusu/briše jih;
  • Manjkale so nam nekatere funkcije, ki jih takrat sploh nismo izvajali:
    • popoln nadzor nad rezultatom posodobitev gruče,
    • samodejno določanje nekaterih parametrov (vnos za namestitvene skripte) na podlagi podatkov, ki jih je mogoče pridobiti iz gruče (discovery),
    • njegov logičen razvoj v obliki nenehnega odkrivanja.

Vse te nabrane izkušnje smo implementirali v okviru našega drugega projekta - addon-operator.

Addon-operator

Temelji na že omenjenem lupinskem operaterju. Celoten sistem izgleda takole:

Naslednje je dodano kavljem lupinskega operaterja:

  • shranjevanje vrednosti,
  • Shema krmila,
  • komponento, ki spremlja shrambo vrednosti in - v primeru kakršnih koli sprememb - prosi Helma, da ponovno zavrti grafikon.

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Tako se lahko odzovemo na dogodek v Kubernetesu, zaženemo kljuko in iz te kljuke naredimo spremembe v pomnilniku, nakar se grafikon ponovno prenese. V nastalem diagramu ločimo niz kavljev in grafikon v eno komponento, ki jo imenujemo modul:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Modulov je lahko veliko in dodamo jim globalne kljuke, globalno shrambo vrednosti in komponento, ki spremlja to globalno shrambo.

Zdaj, ko se nekaj zgodi v Kubernetesu, se lahko na to odzovemo z globalnim kavljem in nekaj spremenimo v globalni trgovini. Ta sprememba bo opažena in bo povzročila uvedbo vseh modulov v gruči:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Ta shema izpolnjuje vse zahteve za namestitev dodatkov, ki so bile navedene zgoraj:

  • Helm je odgovoren za predloge in deklarativnost.
  • Težava s samodejnim posodabljanjem je bila rešena z uporabo globalnega kljuka, ki gre v register po urniku in, če tam vidi novo sistemsko sliko, jo razgrne (tj. »samo«).
  • Shranjevanje nastavitev v gruči je izvedeno z uporabo ConfigMap, ki vsebuje primarne podatke za pomnilnike (ob zagonu se naložijo v pomnilnike).
  • Težave z generiranjem gesel, odkrivanjem in neprekinjenim odkrivanjem so bile rešene s kavlji.
  • Uprizarjanje je doseženo zahvaljujoč oznakam, ki jih Docker podpira takoj.
  • Rezultat spremljamo z metriko, s katero lahko razumemo stanje.

Ta celoten sistem je implementiran v obliki ene same binarne datoteke v Go, ki se imenuje addon-operator. Zaradi tega je diagram videti preprostejši:

Razširitev in dopolnitev Kubernetesa (pregled in video poročilo)

Glavna komponenta tega diagrama je niz modulov (spodaj označeno s sivo). Sedaj lahko z malo truda napišemo modul za potreben dodatek in smo prepričani, da bo nameščen v vsaki gruči, se bo posodabljal in odzival na dogodke, ki jih potrebuje v gruči.

"Flant" uporablja addon-operator na več kot 70 gruč Kubernetes. Trenutni status - alfa različica. Zdaj pripravljamo dokumentacijo za izdajo beta, vendar za zdaj v repozitoriju na voljo primeri, na podlagi katerega lahko ustvarite svoj dodatek.

Kje lahko dobim module za addon-operator? Založba knjižnice je za nas naslednja faza, to načrtujemo poleti.

Video posnetki in diapozitivi

Video z nastopa (~50 minut):

Predstavitev poročila:

PS

Druga poročila na našem blogu:

Morda vas bodo zanimale tudi naslednje publikacije:

Vir: www.habr.com

Dodaj komentar