Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Aurten, Europako Kubernetes konferentzia nagusia - KubeCon + CloudNativeCon Europe 2020 - birtuala izan da. Hala ere, formatu aldaketa horrek ez digu eragotzi aspaldian aurreikusitako β€œGo? Hara! Meet the Shell-operator” gure Open Source proiektuari eskainia shell-operadore.

Artikulu honek, hitzaldian inspiratuta, Kubernetes-en operadoreak sortzeko prozesua sinplifikatzeko ikuspegi bat aurkezten du eta shell-operadore bat erabiliz ahalegin minimoarekin zurea nola egin dezakezun erakusten du.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Aurkezten erreportajearen bideoa (~23 minutu ingelesez, artikulua baino argigarriagoa) eta haren laburpen nagusia testu moduan. Joan!

Flant-en etengabe optimizatzen eta automatizatzen dugu dena. Gaur beste kontzeptu zirraragarri bati buruz hitz egingo dugu. Ezagutu: hodeiko jatorrizko shell script-a!

Hala ere, has gaitezen hori guztia gertatzen den testuingurutik: Kubernetes.

Kubernetes APIa eta kontrolatzaileak

Kubernetes-en APIa fitxategi-zerbitzari moduko bat bezala irudika daiteke, objektu mota bakoitzerako direktorioekin. Zerbitzari honetako objektuak (baliabideak) YAML fitxategien bidez adierazten dira. Horrez gain, zerbitzariak oinarrizko API bat du, hiru gauza egiteko aukera ematen duena:

  • jaso baliabidea bere motaren eta izenaren arabera;
  • aldatu baliabidea (kasu honetan, zerbitzariak objektu "zuzenak" baino ez ditu gordetzen - gaizki eratutakoak edo beste direktorio batzuetarako zuzendutako guztiak baztertzen dira);
  • pista baliabiderako (kasu honetan, erabiltzaileak berehala jasotzen du bere uneko bertsioa/eguneratua).

Horrela, Kubernetes-ek fitxategi-zerbitzari moduko bat bezala jokatzen du (YAML manifestetarako) oinarrizko hiru metodorekin (bai, egia esan, beste batzuk daude, baina oraingoz baztertuko ditugu).

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Arazoa zerbitzariak informazioa soilik gorde dezakeela da. Funtzionatzeko behar duzu controller - Kubernetes munduko bigarren kontzeptu garrantzitsuena eta oinarrizkoena.

Bi kontrolagailu mota nagusi daude. Lehenengoak Kubernetesetik informazioa hartzen du, logikaren habiaratuaren arabera prozesatzen du eta K8ra itzultzen du. Bigarrenak Kubernetes-en informazioa hartzen du, baina, lehenengo motak ez bezala, kanpoko baliabide batzuen egoera aldatzen du.

Ikus ditzagun Kubernetes-en inplementazio bat sortzeko prozesua gertutik:

  • Inplementazio-kontrolatzailea (barne kube-controller-manager) Inplementari buruzko informazioa jasotzen du eta ReplicaSet bat sortzen du.
  • ReplicaSet-ek bi erreplika (bi pod) sortzen ditu informazio horretan oinarrituta, baina oraindik ez daude programatuta.
  • Antolatzaileak pod-ak programatzen ditu eta nodoen informazioa gehitzen die bere YAMLei.
  • Kubelets-ek kanpoko baliabide batean aldaketak egiten ditu (esan Docker).

Ondoren, sekuentzia osoa alderantzizko ordenan errepikatzen da: kubeletak ontziak egiaztatzen ditu, lekaren egoera kalkulatzen du eta itzultzen du. ReplicaSet kontrolagailuak egoera jasotzen du eta erreplika multzoaren egoera eguneratzen du. Gauza bera gertatzen da Deployment Controller-ekin eta erabiltzaileak azkenik eguneratutako (uneko) egoera lortzen du.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Shell-operatzailea

Kubernetes hainbat kontrolatzaileren baterako lanean oinarritzen dela ematen du (Kuberneteseko operadoreak ere kontrolatzaileak dira). Galdera sortzen da, nola sortu zure operadorea ahalegin minimoarekin? Eta hemen garatutakoa erreskatatzera dator shell-operadore. Sistema-administratzaileei beren adierazpenak sortzeko aukera ematen die metodo ezagunak erabiliz.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Adibide sinplea: sekretuak kopiatzea

Ikus dezagun adibide sinple bat.

Demagun Kubernetes kluster bat dugula. Izen-espazio bat du default Sekretu batzuekin mysecret. Horrez gain, beste izen-espazio batzuk daude klusterrean. Horietako batzuek etiketa zehatz bat dute erantsita. Gure helburua da Secret kopiatzea etiketa duten izen-espazioetan.

Egitekoa zaildu egiten da klusterrean izen-espazio berriak ager daitezkeelako eta horietako batzuek etiketa hori izan dezaketelako. Bestalde, etiketa ezabatzen denean, Secret ere ezabatu behar da. Honetaz gain, Sekretua bera ere alda daiteke: kasu honetan, Sekretu berria etiketadun izen-espazio guztietan kopiatu behar da. Secreta edozein izen-espaziotan ustekabean ezabatzen bada, gure operadoreak berehala berrezarri beharko luke.

Orain, zeregina formulatuta dagoenean, shell-operadorea erabiliz inplementatzen hasteko garaia da. Baina lehenik eta behin merezi du shell-operadoreari buruz hitz batzuk esatea.

Nola funtzionatzen duen shell-operadorea

Kubernetes-eko beste lan-kargak bezala, shell-operator bere pod propioan exekutatzen da. Direktorioko pod honetan /hooks fitxategi exekutagarriak gordetzen dira. Hauek Bash, Python, Ruby eta abarreko scriptak izan daitezke. Fitxategi exekutagarri horiei hook deitzen diegu (amu).

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Shell-operadorea Kuberneteseko gertaeretara harpidetzen da eta kako hauek exekutatzen ditu behar ditugun gertaera horiei erantzuteko.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Nola daki shell-operadoreak zein amu exekutatu eta noiz? Kontua da amu bakoitzak bi etapa dituela. Abiaraztean, shell-operadoreak amu guztiak exekutatzen ditu argumentu batekin --config Hau konfigurazio fasea da. Eta horren ondoren, amuak modu normalean abiarazten dira - atxikita dauden gertakariei erantzunez. Azken kasu honetan, amuak lotura-testuingurua jasotzen du (testuinguru loteslea) - datuak JSON formatuan, eta horri buruz xehetasun gehiagoz hitz egingo dugu jarraian.

Bash-en operadore bat egitea

Orain ezartzeko prest gaude. Horretarako, bi funtzio idatzi behar ditugu (bide batez, gomendatzen dugu liburutegia shell_lib, eta horrek asko errazten ditu idazteko amuak Bash-en):

  • lehenengoa konfigurazio faserako beharrezkoa da - lotura-testuingurua erakusten du;
  • bigarrenak amuaren logika nagusia dauka.

#!/bin/bash

source /shell_lib.sh

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

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Hurrengo urratsa zer objektu behar ditugun erabakitzea da. Gure kasuan, jarraipena egin behar dugu:

  • aldaketen iturri sekretua;
  • klusterreko izen-espazio guztiak, zeintzuk duten etiketa erantsita jakin dezazun;
  • xede-sekretuak guztiak iturburu-sekretuarekin sinkronizatuta daudela ziurtatzeko.

Harpidetu iturri sekretuan

Lotura-konfigurazioa nahiko erraza da. Sekretua interesatzen zaigula adierazten dugu izenarekin mysecret izen-eremuan default:

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

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

Ondorioz, amua abiaraziko da iturburuko sekretua aldatzen denean (src_secret) eta hurrengo testuinguru loteslea jaso:

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Ikus dezakezunez, izena eta objektu osoa ditu.

Izen-espazioen jarraipena egitea

Orain izen-espazioetara harpidetu behar duzu. Horretarako, lotura-konfigurazio hau zehazten dugu:

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

Ikus dezakezunez, konfigurazioan eremu berri bat agertu da izenarekin jqIragazkia. Bere izenak dioen bezala, jqFilter beharrezkoa ez den informazio guztia iragazten du eta JSON objektu berri bat sortzen du gure interesekoak diren eremuekin. Antzeko konfigurazioa duen kako batek lotura-testuinguru hau jasoko du:

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Array bat dauka filterResults klusterreko izen-espazio bakoitzeko. Aldagai boolearra hasLabel Emandako izen-espazio bati etiketa bat erantsita dagoen adierazten du. Hautatzailea keepFullObjectsInMemory: false objektu osoak memorian gorde beharrik ez dagoela adierazten du.

Helburu sekretuak jarraitzea

Oharpen bat zehaztuta duten sekretu guztietara harpidetzen gara managed-secret: "yes" (hauek dira gure helburua 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

Kasu honetan jqFilter informazio guztia iragazten du izen-espazioa eta parametroa izan ezik resourceVersion. Azken parametroa oharpenera pasa zen sekretua sortzean: sekretuen bertsioak alderatu eta eguneratuta mantentzeko aukera ematen du.

Horrela konfiguratutako kako batek, exekutatzen denean, goian deskribatutako hiru lotura-testuinguru jasoko ditu. Argazki moduko bat bezala har daitezke (argazkia) multzoa.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Informazio hori guztia oinarri hartuta, oinarrizko algoritmo bat garatu daiteke. Izen-espazio guztietan errepikatzen du eta:

  • bada hasLabel gaietan true egungo izen-espaziorako:
    • sekretu globala tokikoarekin alderatzen du:
      • berdinak badira, ez du ezer egiten;
      • desberdinak badira - exekutatzen kubectl replace edo create;
  • bada hasLabel gaietan false egungo izen-espaziorako:
    • ziurtatzen du Secret ez dagoela emandako izen-espazioan:
      • tokiko Sekretua badago, ezabatu erabiliz kubectl delete;
      • tokiko Sekretua detektatzen ez bada, ez du ezer egiten.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Algoritmoaren ezarpena Bash-en gurean deskargatu dezakezu adibideak dituzten biltegiak.

Horrela sortu ahal izan dugu Kubernetes kontroladore soil bat YAML konfigurazioko 35 lerro erabiliz eta Bash kode kopuru berdina erabiliz! Shell-operadorearen lana elkarrekin lotzea da.

Hala ere, sekretuak kopiatzea ez da erabilgarritasunaren aplikazio eremu bakarra. Hona hemen beste adibide batzuk zertarako gai den erakusteko.

1. adibidea: ConfigMap-en aldaketak egitea

Ikus dezagun hiru podez osatutako Inplementazioa. Pod-ek ConfigMap erabiltzen dute konfigurazio batzuk gordetzeko. Podak abiarazi zirenean, ConfigMap egoera jakin batean zegoen (dei dezagun v.1). Horren arabera, pod guztiek ConfigMap-en bertsio zehatz hau erabiltzen dute.

Orain demagun ConfigMap aldatu egin dela (v.2). Hala ere, podek ConfigMap-en aurreko bertsioa erabiliko dute (v.1):

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Nola lor ditzaket ConfigMap berrira (v.2) aldatzeko? Erantzuna erraza da: erabili txantiloi bat. Gehi diezaiogun checksum-eko ohar bat atalean template Inplementazio konfigurazioak:

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Ondorioz, checksum hau pod guztietan erregistratuko da, eta Inplementazioaren berdina izango da. Orain oharpena eguneratu besterik ez duzu behar ConfigMap aldatzen denean. Eta shell-operadorea ondo dator kasu honetan. Egin behar duzun guztia programatzea da ConfigMap-era harpidetu eta checksum-a eguneratuko duen kako bat.

Erabiltzaileak aldaketak egiten baditu ConfigMap-en, shell-operadoreak ohartuko ditu eta kontrol-batuma berriro kalkulatuko du. Horren ostean, Kubernetesen magia sartuko da jokoan: orkestratzaileak poda hilko du, berri bat sortuko du, hura bihurtu arte itxaron. Ready, eta hurrengora pasatzen da. Ondorioz, Deployment sinkronizatu eta ConfigMap-en bertsio berrira aldatuko da.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

2. adibidea: Baliabideen definizio pertsonalizatuekin lan egitea

Dakizuenez, Kubernetes-ek objektu mota pertsonalizatuak sortzeko aukera ematen dizu. Adibidez, mota sor dezakezu MysqlDatabase. Demagun mota honek bi metadatuen parametro dituela: name ΠΈ namespace.

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

Kubernetes kluster bat dugu izen-espazio ezberdinekin eta bertan MySQL datu-baseak sor ditzakegun. Kasu honetan shell-operator erabil daiteke baliabideen jarraipena egiteko MysqlDatabase, MySQL zerbitzariarekin konektatuz eta klusterraren nahi eta ikusitako egoerak sinkronizatuz.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

3. adibidea: Kluster sarearen jarraipena

Dakizuenez, ping erabiltzea sare bat kontrolatzeko modurik errazena da. Adibide honetan monitorizazio hori nola inplementatu erakutsiko dugu shell-operator erabiliz.

Lehenik eta behin, nodoetara harpidetu beharko zara. Shell operadoreak nodo bakoitzaren izena eta IP helbidea behar ditu. Haien laguntzarekin, nodo hauei ping egingo die.

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: "* * * * *"

Parametroa executeHookOnEvent: [] edozein gertaerari erantzuteko (hau da, nodoak aldatzeari, gehitzeari, ezabatzeari erantzuteko) amua eragozten du. Hala ere, berak korrika egingo du (eta eguneratu nodoen zerrenda) Programatua - minuturo, eremuak agindu bezala schedule.

Orain galdera sortzen da, nola dakigu zehazki pakete-galera bezalako arazoei buruz? Ikus dezagun kodea:

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
}

Nodoen zerrendan errepikatzen dugu, haien izenak eta IP helbideak lortu, ping-a egiten dugu eta emaitzak Prometheus-era bidaltzen ditugu. Shell-operadoreak neurriak esportatu ditzake Prometheus-era, ingurune-aldagaian zehaztutako bidearen arabera kokatutako fitxategi batean gordez $METRICS_PATH.

Horrela sarearen monitorizazio soilerako operadore bat egin dezakezu cluster batean.

Ilaran jartzeko mekanismoa

Artikulu hau osatu gabe egongo litzateke shell-eragilean eraikitako beste mekanismo garrantzitsu bat deskribatu gabe. Imajinatu klusterreko gertaera bati erantzuteko amu moduko bat exekutatzen duela.

  • Zer gertatzen da, aldi berean, klusterrean zerbait gertatzen bada? Bat gehiago ekitaldia?
  • Shell-operatoreak amuaren beste instantzia bat exekutatuko al du?
  • Zer gertatzen da, esate baterako, bost gertaera klusterrean aldi berean gertatzen badira?
  • Shell-operadoreak paraleloki prozesatuko ditu?
  • Zer gertatzen da kontsumitutako baliabideekin, hala nola memoria eta CPU?

Zorionez, shell-operatoreak ilaran jartzeko mekanismo bat dauka. Gertaera guztiak ilaran jartzen dira eta sekuentzialki prozesatzen dira.

Azal dezagun hau adibideekin. Demagun bi kako ditugula. Lehenengo ekitaldia lehen amuari doa. Bere prozesamendua amaitutakoan, ilarak aurrera egiten du. Hurrengo hiru gertaerak bigarren kakora birbideratzen dira - ilaratik kendu eta "sorta" batean sartzen dira. Hori da hook hainbat ekitaldi jasotzen ditu β€” edo, zehatzago esanda, lotura-testuinguru sorta bat.

Hauek ere ekitaldiak handi batean konbina daitezke. Honen arduraduna parametroa da group lotesleen konfigurazioan.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Edozein ilara/kako eta haien konbinazio desberdinak sor ditzakezu. Adibidez, ilara batek bi kakorekin funtziona dezake, edo alderantziz.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Eremua horren arabera konfiguratu besterik ez duzu egin behar queue lotesleen konfigurazioan. Ilara-izen bat zehazten ez bada, kakoa lehenetsitako ilaran exekutatzen da (default). Ilaran jartzeko mekanismo honi esker, baliabideen kudeaketa arazo guztiak guztiz konpon ditzakezu kakoekin lan egiten duzunean.

Ondorioa

Shell-operadorea zer den azaldu genuen, Kubernetes-eko operadoreak azkar eta esfortzurik gabe sortzeko nola erabil daitekeen erakutsi eta erabileraren hainbat adibide eman genituen.

Shell-operadoreari buruzko informazio zehatza, baita hura erabiltzeko moduari buruzko tutorial azkar bat ere dago eskuragarri. biltegiak GitHub-en. Ez izan zalantzarik eta jar zaitez gurekin harremanetan galderak egiteko: berezi batean eztabaida ditzakezu Telegram taldea (errusieraz) edo foro hau (ingelesez).

Eta gustatu bazaizu, beti pozik gaude GitHub-en gai/PR/izar berriak ikusteaz, non, bide batez, beste batzuk aurki ditzakezun proiektu interesgarriak. Horien artean azpimarratzekoa da gehigarri-eragile, shell-operator-en anaia handia dena. Erabilgarritasun honek Helm diagramak erabiltzen ditu gehigarriak instalatzeko, eguneraketak eman ditzake eta diagrama-parametro/balio ezberdinak kontrolatzen ditu, diagramen instalazio-prozesua kontrolatzen du eta klusterreko gertaeren aurrean ere alda ditzake.

Joan? Hara! Ezagutu shell-operatzailea (KubeCon EU'2020-ren berrikuspena eta bideo-txostena)

Bideoak eta diapositibak

Emanaldiko bideoa (~23 minutu):


Txostenaren aurkezpena:

PS

Irakurri ere gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria