Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Å ogad galvenā Eiropas Kubernetes konference - KubeCon + CloudNativeCon Europe 2020 - bija virtuāla. Taču Ŕādas formāta izmaiņas mums netraucēja sniegt mÅ«su sen plānoto ziņojumu ā€œAiziet? Bash! IepazÄ«stieties ar Shell operatoruā€, kas veltÄ«ts mÅ«su atvērtā koda projektam čaulas operators.

Šajā rakstā, kas ir iedvesmots no sarunas, ir sniegta pieeja Kubernetes operatoru izveides procesa vienkārŔoŔanai un parādīts, kā ar minimālu piepūli varat izveidot savu operatoru, izmantojot čaulas operatoru.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Iepazīstinām reportāžas video (~23 minūtes angļu valodā, manāmi informatīvāks par rakstu) un galvenais izraksts no tā teksta formā. Aiziet!

Uzņēmumā Flant mēs pastāvÄ«gi visu optimizējam un automatizējam. Å odien mēs runāsim par citu aizraujoÅ”u koncepciju. IepazÄ«stieties: mākoņdatoÅ”anas čaulas skriptÄ“Å”ana!

Tomēr sāksim ar kontekstu, kurā tas viss notiek: Kubernetes.

Kubernetes API un kontrolieri

Kubernetes API var attēlot kā sava veida failu serveri ar direktorijiem katram objekta veidam. Objektus (resursus) Å”ajā serverÄ« attēlo YAML faili. Turklāt serverim ir pamata API, kas ļauj veikt trÄ«s darbÄ«bas:

  • saņemt resurss pēc tā veida un nosaukuma;
  • mainÄ«t resurss (Å”ajā gadÄ«jumā serveris glabā tikai ā€œpareizosā€ objektus - visi nepareizi izveidotie vai paredzēti citiem direktorijiem tiek izmesti);
  • trase resursam (Å”ajā gadÄ«jumā lietotājs uzreiz saņem tā paÅ”reizējo/atjaunināto versiju).

Tādējādi Kubernetes darbojas kā sava veida failu serveris (YAML manifestiem) ar trim pamatmetodēm (jā, patiesībā ir arī citas, taču mēs tās pagaidām izlaidīsim).

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Problēma ir tā, ka serveris var uzglabāt tikai informāciju. Lai tas darbotos, jums ir nepiecieÅ”ams kontrolieris - otra svarÄ«gākā un fundamentālākā koncepcija Kubernetes pasaulē.

Ir divi galvenie kontrolieru veidi. Pirmais ņem informāciju no Kubernetes, apstrādā to saskaņā ar ligzdoto loÄ£iku un atgriež K8s. Otrais ņem informāciju no Kubernetes, bet atŔķirÄ«bā no pirmā veida maina dažu ārējo resursu stāvokli.

Sīkāk apskatīsim izvietoŔanas izveides procesu Kubernetes:

  • IzvietoÅ”anas kontrolieris (iekļauts kube-controller-manager) saņem informāciju par izvietoÅ”anu un izveido ReplicaSet.
  • Pamatojoties uz Å”o informāciju, ReplicaSet izveido divas kopijas (divus aplikumus), taču Å”ie aplikumi vēl nav ieplānoti.
  • Plānotājs plāno podi un pievieno mezglu informāciju saviem YAML.
  • Kubelets veic izmaiņas ārējā resursā (teiksim, Docker).

Tad visa Ŕī secÄ«ba tiek atkārtota apgrieztā secÄ«bā: kubelets pārbauda konteinerus, aprēķina pāksts statusu un nosÅ«ta to atpakaļ. ReplicaSet kontrolleris saņem statusu un atjaunina reprodukcijas kopas stāvokli. Tas pats notiek ar izvietoÅ”anas kontrolieri, un lietotājs beidzot iegÅ«st atjaunināto (paÅ”reizējo) statusu.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Apvalka operators

Izrādās, ka Kubernetes pamatā ir dažādu kontrolieru kopÄ«gs darbs (arÄ« Kubernetes operatori ir kontrolieri). Rodas jautājums, kā ar minimālu piepÅ«li izveidot savu operatoru? Un Å”eit palÄ«gā nāk mÅ«su izstrādātais čaulas operators. Tas ļauj sistēmas administratoriem izveidot savus paziņojumus, izmantojot pazÄ«stamas metodes.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

VienkārÅ”s piemērs: noslēpumu kopÄ“Å”ana

ApskatÄ«sim vienkārÅ”u piemēru.

Pieņemsim, ka mums ir Kubernetes klasteris. Tam ir nosaukumvieta default ar kādu noslēpumu mysecret. Turklāt klasterÄ« ir arÄ« citas nosaukumvietas. Dažiem no tiem ir pievienota Ä«paÅ”a etiÄ·ete. MÅ«su mērÄ·is ir kopēt Secret nosaukumu telpās ar etiÄ·eti.

Uzdevumu sarežģī fakts, ka klasterÄ« var parādÄ«ties jaunas nosaukumvietas, un dažām no tām var bÅ«t Ŕī etiÄ·ete. No otras puses, dzÄ“Å”ot etiÄ·eti, ir jādzÄ“Å” arÄ« Secret. Papildus tam var mainÄ«ties arÄ« pats noslēpums: Å”ajā gadÄ«jumā jaunais Secret ir jākopē visās nosaukumvietās ar etiÄ·etēm. Ja Secret tiek nejauÅ”i izdzēsts kādā nosaukumvietā, mÅ«su operatoram tas nekavējoties jāatjauno.

Tagad, kad uzdevums ir formulēts, ir pienācis laiks sākt to Ä«stenot, izmantojot čaulas operatoru. Bet vispirms ir vērts pateikt dažus vārdus par paÅ”u čaulas operatoru.

Kā darbojas čaulas operators

Tāpat kā citas Kubernetes darba slodzes, čaulas operators darbojas savā podā. Å ajā podā direktorijā /hooks izpildāmie faili tiek saglabāti. Tie var bÅ«t skripti valodās Bash, Python, Ruby utt. Mēs Ŕādus izpildāmos failus saucam par āķiem (āķi).

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Shell-operator abonē Kubernetes notikumus un palaiž Å”os āķus, reaģējot uz tiem notikumiem, kas mums nepiecieÅ”ami.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Kā čaulas operators zina, kuru āķi palaist un kad? Lieta tāda, ka katram āķim ir divi posmi. StartÄ“Å”anas laikā čaulas operators palaiž visus āķus ar argumentu --config Å is ir konfigurācijas posms. Un pēc tam āķi tiek palaisti parastajā veidā - reaģējot uz notikumiem, kuriem tie ir pievienoti. Pēdējā gadÄ«jumā āķis saņem saistoÅ”o kontekstu (saistoÅ”s konteksts) - dati JSON formātā, par kuriem mēs sÄ«kāk runāsim tālāk.

Operatora izveide BaŔā

Tagad esam gatavi ievieÅ”anai. Lai to izdarÄ«tu, mums ir jāraksta divas funkcijas (starp citu, mēs iesakām bibliotēka shell_lib, kas ievērojami vienkārÅ”o āķu rakstÄ«Å”anu Bash valodā):

  • pirmais ir nepiecieÅ”ams konfigurācijas posmam - tas parāda saistoÅ”o kontekstu;
  • otrajā ir galvenā āķa loÄ£ika.

#!/bin/bash

source /shell_lib.sh

function __config__() {
  cat << EOF
    configVersion: v1
    # BINDING CONFIGURATION
EOF
}

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Nākamais solis ir izlemt, kādi objekti mums ir nepiecieŔami. Mūsu gadījumā mums ir jāizseko:

  • izmaiņu avota noslēpums;
  • visas klastera nosaukumvietas, lai jÅ«s zinātu, kurām no tām ir pievienota etiÄ·ete;
  • mērÄ·a noslēpumus, lai nodroÅ”inātu, ka tie visi ir sinhronizēti ar avota noslēpumu.

Abonējiet slepeno avotu

IesieÅ”anas konfigurācija tam ir diezgan vienkārÅ”a. Ar nosaukumu norādām, ka interesējam Secret mysecret vārdu telpā default:

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

function __config__() {
  cat << EOF
    configVersion: v1
    kubernetes:
    - name: src_secret
      apiVersion: v1
      kind: Secret
      nameSelector:
        matchNames:
        - mysecret
      namespace:
        nameSelector:
          matchNames: ["default"]
      group: main
EOF

Rezultātā āķis tiks aktivizēts, kad mainÄ«sies avota noslēpums (src_secret) un saņem Ŕādu saistoÅ”u kontekstu:

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Kā redzat, tajā ir nosaukums un viss objekts.

Nosaukumvietu izsekoŔana

Tagad jums ir jāabonē nosaukumvietas. Lai to izdarÄ«tu, mēs norādām Ŕādu saistÄ«Å”anas konfigurāciju:

- name: namespaces
  group: main
  apiVersion: v1
  kind: Namespace
  jqFilter: |
    {
      namespace: .metadata.name,
      hasLabel: (
       .metadata.labels // {} |  
         contains({"secret": "yes"})
      )
    }
  group: main
  keepFullObjectsInMemory: false

Kā redzat, konfigurācijā ir parādÄ«jies jauns lauks ar nosaukumu jqFilter. Kā norāda nosaukums, jqFilter filtrē visu nevajadzÄ«go informāciju un izveido jaunu JSON objektu ar laukiem, kas mÅ«s interesē. Āķis ar lÄ«dzÄ«gu konfigurāciju saņems Ŕādu saistoÅ”o kontekstu:

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Tas satur masÄ«vu filterResults katrai klastera nosaukumvietai. BÅ«la mainÄ«gais hasLabel norāda, vai noteiktai nosaukumvietai ir pievienota etiÄ·ete. AtlasÄ«tājs keepFullObjectsInMemory: false norāda, ka nav nepiecieÅ”ams saglabāt pilnus objektus atmiņā.

MērÄ·a noslēpumu izsekoÅ”ana

Mēs parakstāmies uz visiem Noslēpumiem, kuriem ir norādīta anotācija managed-secret: "yes" (tie ir mūsu mērķis dst_secrets):

- name: dst_secrets
  apiVersion: v1
  kind: Secret
  labelSelector:
    matchLabels:
      managed-secret: "yes"
  jqFilter: |
    {
      "namespace":
        .metadata.namespace,
      "resourceVersion":
        .metadata.annotations.resourceVersion
    }
  group: main
  keepFullObjectsInMemory: false

Šajā gadījumā jqFilter filtrē visu informāciju, izņemot nosaukumvietu un parametru resourceVersion. Pēdējais parametrs tika nodots anotācijai, veidojot noslēpumu: tas ļauj salīdzināt noslēpumu versijas un atjaunināt tās.

Šādi konfigurēts āķis, kad tas tiks izpildÄ«ts, saņems trÄ«s iepriekÅ” aprakstÄ«tos saistoÅ”os kontekstus. Tos var uzskatÄ«t par sava veida momentuzņēmumu (momentuzņēmums) klasteris.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Pamatojoties uz visu Ŕo informāciju, var izstrādāt pamata algoritmu. Tas atkārtojas visās nosaukumvietās un:

  • ja hasLabel jautājumiem true paÅ”reizējai nosaukumvietai:
    • salÄ«dzina globālo noslēpumu ar vietējo:
      • ja tie ir vienādi, tas neko nedara;
      • ja tie atŔķiras - izpilda kubectl replace vai create;
  • ja hasLabel jautājumiem false paÅ”reizējai nosaukumvietai:
    • nodroÅ”ina, ka Secret neatrodas norādÄ«tajā nosaukumvietā:
      • ja vietējais noslēpums ir pieejams, izdzēsiet to, izmantojot kubectl delete;
      • ja vietējais noslēpums netiek atklāts, tas neko nedara.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Algoritma ievieÅ”ana Bash jÅ«s varat lejupielādēt mÅ«su krātuves ar piemēriem.

Tādā veidā mēs varējām izveidot vienkārÅ”u Kubernetes kontrolieri, izmantojot 35 YAML konfigurācijas rindas un aptuveni tikpat daudz Bash koda! Apvalka operatora uzdevums ir tos saistÄ«t kopā.

Tomēr noslēpumu kopÄ“Å”ana nav vienÄ«gā lietderÄ«bas joma. Å eit ir vēl daži piemēri, lai parādÄ«tu, uz ko viņŔ ir spējÄ«gs.

1. piemērs: izmaiņu veikÅ”ana programmā ConfigMap

ApskatÄ«sim izvietoÅ”anu, kas sastāv no trim blokiem. Pods izmanto ConfigMap, lai saglabātu kādu konfigurāciju. Kad podi tika palaisti, ConfigMap bija noteiktā stāvoklÄ« (sauksim to par v.1). AttiecÄ«gi visi podi izmanto Å”o konkrēto ConfigMap versiju.

Tagad pieņemsim, ka ConfigMap ir mainÄ«jies (v.2). Tomēr aplikumos tiks izmantota iepriekŔējā ConfigMap versija (v.1):

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Kā es varu panākt, lai viņi pārslēgtos uz jauno ConfigMap (v.2)? Atbilde ir vienkārÅ”a: izmantojiet veidni. Pievienosim sadaļai kontrolsummas anotāciju template IzvietoÅ”anas konfigurācijas:

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Rezultātā Ŕī kontrolsumma tiks reÄ£istrēta visos podiņos, un tā bÅ«s tāda pati kā izvietoÅ”anas kontrolsumma. Tagad jums vienkārÅ”i jāatjaunina anotācija, kad mainās ConfigMap. Un čaulas operators Å”ajā gadÄ«jumā noder. Viss, kas jums jādara, ir ieprogrammēt āķis, kas abonēs ConfigMap un atjauninās kontrolsummu.

Ja lietotājs veic izmaiņas ConfigMap, čaulas operators tās pamanÄ«s un pārrēķinās kontrolsummu. Pēc tam stāsies spēkā Kubernetes burvÄ«ba: orÄ·estris nogalinās podiņu, izveidos jaunu, gaidÄ«s, kad tas kļūs Ready, un pāriet uz nākamo. Tā rezultātā izvietoÅ”ana tiks sinhronizēta un pārslēgsies uz jauno ConfigMap versiju.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

2. piemērs. Darbs ar pielāgotām resursu definīcijām

Kā zināms, Kubernetes ļauj izveidot pielāgotus objektu tipus. Piemēram, jÅ«s varat izveidot laipnu MysqlDatabase. Pieņemsim, ka Å”im veidam ir divi metadatu parametri: name Šø namespace.

apiVersion: example.com/v1alpha1
kind: MysqlDatabase
metadata:
  name: foo
  namespace: bar

Mums ir Kubernetes klasteris ar dažādām nosaukumu telpām, kurās mēs varam izveidot MySQL datu bāzes. Å ajā gadÄ«jumā resursu izsekoÅ”anai var izmantot čaulas operatoru MysqlDatabase, savienojot tos ar MySQL serveri un sinhronizējot vēlamos un novērotos klastera stāvokļus.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

3. piemērs. Klasteru tīkla pārraudzība

Kā jÅ«s zināt, ping ir vienkārŔākais veids, kā pārraudzÄ«t tÄ«klu. Å ajā piemērā mēs parādÄ«sim, kā Ä«stenot Ŕādu uzraudzÄ«bu, izmantojot čaulas operatoru.

Pirmkārt, jums bÅ«s jāabonē mezgli. Apvalka operatoram ir nepiecieÅ”ams katra mezgla nosaukums un IP adrese. Ar viņu palÄ«dzÄ«bu viņŔ ping Å”os mezglus.

configVersion: v1
kubernetes:
- name: nodes
  apiVersion: v1
  kind: Node
  jqFilter: |
    {
      name: .metadata.name,
      ip: (
       .status.addresses[] |  
        select(.type == "InternalIP") |
        .address
      )
    }
  group: main
  keepFullObjectsInMemory: false
  executeHookOnEvent: []
schedule:
- name: every_minute
  group: main
  crontab: "* * * * *"

Parametrs executeHookOnEvent: [] neļauj āķim darboties, reaģējot uz jebkuru notikumu (tas ir, reaģējot uz mezglu maiņu, pievienoÅ”anu, dzÄ“Å”anu). Tomēr viņŔ skries (un atjauniniet mezglu sarakstu) Plānots - katru minÅ«ti, kā to nosaka laukums schedule.

Tagad rodas jautājums, kā tieÅ”i mēs zinām par tādām problēmām kā pakeÅ”u zudums? ApskatÄ«sim kodu:

function __main__() {
  for i in $(seq 0 "$(context::jq -r '(.snapshots.nodes | length) - 1')"); do
    node_name="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.name')"
    node_ip="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.ip')"
    packets_lost=0
    if ! ping -c 1 "$node_ip" -t 1 ; then
      packets_lost=1
    fi
    cat >> "$METRICS_PATH" <<END
      {
        "name": "node_packets_lost",
        "add": $packets_lost,
        "labels": {
          "node": "$node_name"
        }
      }
END
  done
}

Mēs atkārtojam mezglu sarakstu, iegÅ«stam to nosaukumus un IP adreses, ping tos un nosÅ«tām rezultātus Prometheus. Shell operators var eksportēt metriku uz Prometheus, saglabājot tos failā, kas atrodas atbilstoÅ”i vides mainÄ«gajā norādÄ«tajam ceļam $METRICS_PATH.

Kā Ŕis Jūs varat izveidot operatoru vienkārŔai tīkla uzraudzībai klasterī.

Rindas mehānisms

Šis raksts būtu nepilnīgs, neaprakstot citu svarīgu mehānismu, kas iebūvēts apvalka operatorā. Iedomājieties, ka tas izpilda sava veida āķi, reaģējot uz notikumu klasterī.

  • Kas notiek, ja tajā paŔā laikā kaut kas notiek klasterÄ«? vēl vienu pasākums?
  • Vai čaulas operators palaist citu āķa gadÄ«jumu?
  • Ko darÄ«t, ja klasterÄ« vienlaikus notiek pieci notikumi?
  • Vai čaulas operators tos apstrādās paralēli?
  • Kā ir ar patērētajiem resursiem, piemēram, atmiņu un centrālo procesoru?

Par laimi, čaulas operatoram ir iebūvēts rindas mehānisms. Visi notikumi tiek ievietoti rindā un apstrādāti secīgi.

Ilustrēsim to ar piemēriem. Pieņemsim, ka mums ir divi āķi. Pirmais notikums iet uz pirmo āķi. Kad tā apstrāde ir pabeigta, rinda virzās uz priekÅ”u. Nākamie trÄ«s notikumi tiek novirzÄ«ti uz otro āķi - tie tiek noņemti no rindas un ievadÄ«ti tajā ā€œsaitāā€. Tas ir āķis saņem virkni notikumu ā€” vai, precÄ«zāk, saistoÅ”u kontekstu masÄ«vs.

Arī Ŕīs pasākumus var apvienot vienā lielā. Parametrs ir atbildīgs par to group saistoŔajā konfigurācijā.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Varat izveidot neierobežotu skaitu rindu/āķu un to dažādās kombinācijas. Piemēram, viena rinda var darboties ar diviem āķiem vai otrādi.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Viss, kas jums jādara, ir attiecÄ«gi jākonfigurē lauks queue saistoÅ”ajā konfigurācijā. Ja rindas nosaukums nav norādÄ«ts, āķis darbojas noklusējuma rindā (default). Å is rindas mehānisms ļauj pilnÄ«bā atrisināt visas resursu pārvaldÄ«bas problēmas, strādājot ar āķiem.

Secinājums

Mēs izskaidrojām, kas ir čaulas operators, parādÄ«jām, kā ar to var ātri un bez piepÅ«les izveidot Kubernetes operatorus, kā arÄ« sniedzām vairākus tā izmantoÅ”anas piemērus.

Sīkāka informācija par čaulas operatoru, kā arī ātra apmācība par to, kā to izmantot, ir pieejama atbilstoŔajā GitHub krātuves. Nevilcinieties sazināties ar mums, ja jums ir jautājumi: varat tos apspriest īpaŔā Telegram grupa (krievu valodā) vai in Ŕis forums (angliski).

Un, ja jums patika, mēs vienmēr priecājamies redzēt jaunus izdevumus/PR/zvaigznes vietnē GitHub, kur, starp citu, varat atrast citus interesanti projekti. Starp tiem ir vērts izcelt papildinājumu operators, kas ir čaulas operatora lielais brālis. Å Ä« utilÄ«ta izmanto Helm diagrammas, lai instalētu papildinājumus, var piegādāt atjauninājumus un pārraudzÄ«t dažādus diagrammu parametrus/vērtÄ«bas, kontrolē diagrammu instalÄ“Å”anas procesu un var arÄ« modificēt tās, reaģējot uz notikumiem klasterÄ«.

Iet? Bash! Iepazīstieties ar čaulas operatoru (pārskats un videoreportāža no KubeCon EU'2020)

Videoklipi un slaidi

Video no izrādes (~23 minūtes):


Ziņojuma prezentācija:

PS

Lasi arī mūsu emuārā:

Avots: www.habr.com

Pievieno komentāru