Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Vê salê, konferansa sereke ya Kubernetes a Ewropî - KubeCon + CloudNativeCon Europe 2020 - virtual bû. Lê belê, guhertineke bi vî rengî ya di formatê de nehişt ku em raporta xwe ya ji mêj ve plansazkirî pêşkêş bikin “Go? Bash! Meet the Shell-operator” ji projeya meya Çavkaniya Vekirî re hatî veqetandin shell-operator.

Ev gotar, ku ji axaftinê hatî îlhama kirin, nêzîkatiyek ji bo hêsankirina pêvajoya afirandina operatorên ji bo Kubernetes pêşkêşî dike û destnîşan dike ku hûn çawa dikarin bi hewildanek hindiktirîn bi karanîna kargêrek shell re xwe çêbikin.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Nasandin vîdyoya raporê (~ 23 hûrdeman bi Englishngilîzî, ji gotarê pir agahdartir e) û jêdera sereke ji wê di forma nivîsê de. Ajotin!

Li Flant em bi berdewamî her tiştî xweşbîn û otomatîk dikin. Îro em ê li ser têgehek din a balkêş biaxivin. Lihevrasthatin: skrîpta şêlê ewr-xwecihî!

Lêbelê, em bi çarçoweya ku ev hemî diqewime dest pê bikin: Kubernetes.

Kubernetes API û kontrolker

API-ya di Kubernetes de dikare wekî celebek serverek pelê bi pelrêçan ji bo her cûre tiştan were destnîşan kirin. Tiştên (çavkaniyên) li ser vê serverê bi pelên YAML têne destnîşan kirin. Wekî din, server xwedan API-ya bingehîn e ku dihêle hûn sê tiştan bikin:

  • stendin çavkaniyek bi celeb û navê xwe;
  • gûherrandinî çavkanî (di vê rewşê de, server tenê tiştên "rast" hildide - hemî yên ku bi xeletî hatine çêkirin an jî ji bo pelrêçikên din têne avêtin têne avêtin);
  • şop ji bo çavkaniyê (di vê rewşê de, bikarhêner yekser guhertoya xweya heyî / nûvekirî distîne).

Ji ber vê yekê, Kubernetes wekî celebek serverek pelê (ji bo diyardeyên YAML) bi sê rêbazên bingehîn tevdigere (erê, bi rastî yên din jî hene, lê em ê heya niha wan ji holê rakin).

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Pirsgirêk ev e ku server tenê dikare agahdarî hilîne. Ji bo ku hûn bixebitin hûn hewce ne kontrolker - di cîhana Kubernetes de têgeha duyemîn ya herî girîng û bingehîn.

Du celebên sereke yên kontrolker hene. Ya yekem agahdariya ji Kubernetes digire, li gorî mentiqê hêlînê pêvajo dike, û vedigerîne K8s. Ya duyemîn ji Kubernetes agahdarî digire, lê, berevajî celebê yekem, rewşa hin çavkaniyên derveyî diguhezîne.

Ka em hûrgulî li pêvajoya afirandina Dabeşkirinek li Kubernetes binêrin:

  • Kontrolkerê Dabeşkirinê (di nav de ye kube-controller-manager) di derbarê Deployment de agahdarî distîne û ReplicaSet diafirîne.
  • ReplicaSet li ser bingeha vê agahiyê du kopiyan (du pods) diafirîne, lê ev pod hêj nehatine plansaz kirin.
  • Rêvebir podan destnîşan dike û agahdariya nodê li YAML-yên wan zêde dike.
  • Kubelets di çavkaniyek derveyî de guhertinan çêdike (bibêjin Docker).

Dûv re ev rêzik tev bi rêza berevajî tê dubare kirin: Kubelet konteynir kontrol dike, rewşa podê hesab dike û paşde dişîne. Kontrolkerê ReplicaSet statûyê distîne û rewşa koma replica nûve dike. Heman tişt bi Kontrolkerê Dabeşkirinê re diqewime û bikarhêner di dawiyê de statûya nûvekirî (niha) werdigire.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Shell-operator

Derket holê ku Kubernetes li ser bingeha xebata hevbeş a kontrolkerên cihêreng (operatorên Kubernetes jî kontrolker in) pêk tê. Pirs derdikeve holê, meriv çawa bi hewildanek hindiktirîn operatorê xwe biafirîne? Û di vir de yê ku me pêş xistiye tê rizgariyê shell-operator. Ew dihêle rêvebirên pergalê bi karanîna rêbazên naskirî daxuyaniyên xwe biafirînin.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Mînaka hêsan: kopîkirina razan

Ka em li mînakek hêsan binêrin.

Ka em bibêjin komeke Kubernetes me heye. Navekî wê heye default bi hin Secret mysecret. Ji bilî vê, navên din ên di komê de hene. Hin ji wan etîketek taybetî bi wan ve girêdayî ne. Armanca me ew e ku em Veşartî li nav navan bi etîketekê kopî bikin.

Kar ji ber vê yekê tevlihev e ku cîhên navên nû dikarin di komê de xuya bibin, û dibe ku hin ji wan xwedî vê etîketê bin. Ji aliyê din ve, dema ku etîket were jêbirin, divê Veşartî jî were jêbirin. Digel vê yekê, Veşartî bixwe jî dikare biguhere: Di vê rewşê de, Pêdivî ye ku Veşarta nû li hemî navên bi etîketan were kopî kirin. Ger Veşartî bi xeletî di nav cîhek navekî de were jêbirin, divê operatorê me tavilê wê sererast bike.

Naha ku peywir hate formule kirin, ew dem e ku meriv wê bi karanîna shell-operatorê dest pê bike. Lê pêşî hêja ye ku çend peyvan li ser şell-operator bixwe jî bê gotin.

Çawa shell-operator dixebite

Mîna barkêşên din ên li Kubernetes, shell-operator di podê xwe de dimeşe. Di vê pod di pelrêça /hooks pelên îcrakar têne hilanîn. Ev dikarin skrîptên li Bash, Python, Ruby, hwd bin. Em ji van pelên îcrakar re dibêjin hook (hooks).

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Shell-operator aboneyê bûyerên Kubernetes dibe û di bersivdana wan bûyerên ku ji me re hewce ne re van çengelan dimeşîne.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Meriv çawa şell-operator dizane ku kîjan çengelê bixebite û kengê? Mesele ev e ku her çengek du qonax hene. Di dema destpêkirinê de, shell-operator hemî çengelan bi argumanan dimeşîne --config Ev qonaxa veavakirinê ye. Û piştî wê, çeng bi awayê normal têne destpêkirin - di bersiva bûyerên ku ew pê ve girêdayî ne. Di rewşa paşîn de, çengelê çarçoweya girêdanê distîne (çarçoveya girêdanê) - Daneyên bi formata JSON, ku em ê li jêr bi hûrgulî li ser biaxivin.

Çêkirina operator li Bash

Niha em ji bo pêkanînê amade ne. Ji bo vê yekê, divê em du fonksiyonan binivîsin (bi awayê, em pêşniyar dikin pirtûkxane shell_lib, ku nivîsandina çengelên li Bash pir hêsan dike):

  • ya yekem ji bo qonaxa veavakirinê hewce ye - ew çarçoveya girêdanê nîşan dide;
  • ya duyemîn mantiqa sereke ya çengelê dihewîne.

#!/bin/bash

source /shell_lib.sh

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

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Pêngava paşîn ev e ku em biryar bidin ka em çi tiştên hewce ne. Di doza me de, divê em bişopînin:

  • çavkaniyê veşartî ji bo guhertinan;
  • hemû cîhên navan ên di komê de, da ku hûn zanibin kîjan etîketek bi wan ve hatiye girêdan;
  • sirên armanc bikin da ku pê ewle bibin ku ew hemî bi dizî çavkaniyê re hevdeng in.

Subscribe li çavkaniya veşartî

Veavakirina girêdanê ji bo wê pir hêsan e. Em destnîşan dikin ku em bi navê Secret re eleqedar in mysecret di navan de default:

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji 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

Wekî encamek, gava ku çavkaniyek veşartî biguhere, çengelê dê were veguheztin (src_secret) û çarçoveya girêdana jêrîn bistînin:

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Wekî ku hûn dikarin bibînin, ew nav û tevahiya tiştan dihewîne.

Şopandina cîhên navan

Naha hûn hewce ne ku bibin abone li cîhên navan. Ji bo vê yekê, em veavakirina girêdana jêrîn diyar dikin:

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

Wekî ku hûn dibînin, di veavakirinê de bi navê qadeke nû derketiye jqFilter. Wekî ku ji navê wê diyar dike, jqFilter Hemî agahdariya nepêwist fîlter dike û bi qadên ku ji me re eleqedar in re tiştek JSON-ya nû diafirîne. Çêçek bi veavakirinek wekhev dê çarçoweya girêdana jêrîn werbigire:

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Di nav de array heye filterResults ji bo her navekî di komê de. Guherbara Boolean hasLabel nîşan dide ka etîketek bi navekî diyarkirî ve girêdayî ye yan na. Hilbijêr keepFullObjectsInMemory: false nîşan dide ku ne hewce ye ku tiştên temam di bîrê de bihêlin.

Şopandina sirên hedef

Em dibin aboneya hemî Veşartiyên ku annotasyonek wan diyar kiriye managed-secret: "yes" (Ev armanca me ne 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

Di vê rewşê de jqFilter Ji xeynî cîhê nav û parametreyê hemî agahdarî fîlter dike resourceVersion. Parametreya paşîn di dema afirandina sirê de ji şîrovekirinê re derbas bû: ew dihêle hûn guhertoyên razan bidin ber hev û wan nûve bikin.

Çêlekek ku bi vî rengî hatî mîheng kirin, dema ku were darve kirin, dê sê çarçeweyên girêdanê yên ku li jor hatine destnîşan kirin werbigire. Ew dikarin wekî celebek wêneyek bête hesibandin (snapshot) kom.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Li ser bingeha van hemî agahdarî, algorîtmayek bingehîn dikare were pêşve xistin. Ew li ser hemî cîhên navan dubare dike û:

  • heke hasLabel di mijarên true ji bo cîhê navê heyî:
    • raza gerdûnî bi ya herêmî re berhev dike:
      • eger ew yek bin, ew tiştek nake;
      • heke ew ji hev cuda bin - pêk tîne kubectl replace an create;
  • heke hasLabel di mijarên false ji bo cîhê navê heyî:
    • piştrast dike ku Veşartî ne di cîhê navî de ye:
      • heke Secret herêmî hebe, wê bikar bînin jêbirin kubectl delete;
      • heke Sira herêmî neyê dîtin, ew tiştek nake.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Pêkanîna algorîtmayê li Bash hûn dikarin li me dakêşin depoyên bi mînakan.

Bi vî rengî me karî kontrolkerek Kubernetes a hêsan bi karanîna 35 rêzikên veavakirina YAML û bi heman hejmarê koda Bash-ê biafirînin! Karê shell-operator ew e ku wan bi hev ve girêbide.

Lêbelê, kopîkirina sirên ne tenê qada serîlêdanê ya karûbar e. Li vir çend mînakên din hene ku nîşan bide ka ew çi jêhatî ye.

Mînak 1: Çêkirina guhertinên li ConfigMap

Werin em li Pêvekek ku ji sê podan pêk tê binêrin. Pods ConfigMap bikar tînin da ku hin veavakirinê hilînin. Dema ku pod hatin destpêkirin, ConfigMap di rewşek diyar de bû (ka em jê re bibêjin v.1). Li gorî vê yekê, hemî pod vê guhertoya taybetî ya ConfigMap bikar tînin.

Niha em bihesibînin ku ConfigMap hatiye guhertin (v.2). Lêbelê, pod dê guhertoya berê ya ConfigMap (v.1) bikar bînin:

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Ez çawa dikarim wan biçim ku derbasî ConfigMap-a nû (v.2) bibin? Bersiv hêsan e: şablonek bikar bînin. Ka em li beşê annotasyonek kontrolê zêde bikin template Veavakirinên sazkirinê:

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Wekî encamek, ev checksum dê di hemî podan de were tomar kirin, û ew ê wekî ya Deployment be. Naha hûn tenê hewce ne ku gava ku ConfigMap diguhezîne annotationê nûve bikin. Û şêl-operator di vê rewşê de bi kêr tê. Ya ku hûn hewce ne bikin bername ye çengek ku dê beşdarî ConfigMap bibe û kontrolê nûve bike.

Ger bikarhêner di ConfigMap-ê de guhertinan çêbike, operator-şell dê wan ferq bike û jimareya kontrolê ji nû ve hesab bike. Piştî ku dê sêrbaziya Kubernetes bikeve lîstikê: orkestrator dê pod bikuje, yek nû biafirîne, li bendê bimîne ku ew bibe Ready, û diçe ya din. Wekî encamek, Deployment dê guhertoya nû ya ConfigMap-ê hevdem bike û veguherîne.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Mînak 2: Bi pênaseyên Çavkaniyên Xweser re xebitîn

Wekî ku hûn dizanin, Kubernetes dihêle hûn celebên xwerû yên tiştan biafirînin. Ji bo nimûne, hûn dikarin celebek çêbikin MysqlDatabase. Em bêjin ev celeb du pîvanên metadata hene: name и namespace.

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

Me komek Kubernetes bi navên cihêreng heye ku tê de em dikarin databasên MySQL biafirînin. Di vê rewşê de, shell-operator dikare ji bo şopandina çavkaniyan were bikar anîn MysqlDatabase, wan bi servera MySQL ve girêdide û dewletên xwestî û çavdêrîkirî yên komê hevdeng dike.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Mînak 3: Şopandina Tora Komê

Wekî ku hûn dizanin, karanîna ping awayê herî hêsan e ku meriv çavdêriya torê bike. Di vê nimûneyê de em ê nîşan bidin ka meriv çawa bi karanîna shell-operatorê çavdêriyek wusa pêk tîne.

Berî her tiştî, hûn ê hewce bibin ku bibin abone li nodeyan. Operatorê şêlê nav û navnîşana IP ya her girêk hewce dike. Bi alîkariya wan, ew ê van girêkan ping bike.

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

Parîsê executeHookOnEvent: [] nahêle ku hook di bersiva her bûyerekê de bimeşe (ango, di bersivdana guhertin, zêdekirin, jêbirina girêkan). Lêbelê, ew dê birevin (û navnîşa girêkan nûve bikin) Scheduled - her deqîqe, wekî ku ji hêla zeviyê ve hatî destnîşan kirin schedule.

Naha pirs derdikeve holê, em çawa bi rastî di derheqê pirsgirêkên mîna windabûna pakêtê de dizanin? Ka em li kodê binêrin:

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
}

Em di navnîşa girêkan de dubare dikin, nav û navnîşanên IP-ya wan digirin, wan ping dikin û encaman ji Prometheus re dişînin. Operator Shell dikare metrîkan ji Prometheus re hinarde bike, wan li pelek ku li gorî riya ku di guhêrbara jîngehê de hatî destnîşan kirin hilîne $METRICS_PATH.

Va ye hûn dikarin operatorek ji bo şopandina torê ya hêsan di komekê de çêbikin.

Mekanîzmaya rêzgirtinê

Dê ev gotar bêyî danasîna mekanîzmayek din a girîng a ku di nav-operatorê de hatî çêkirin netemam be. Bifikirin ku ew di bersivdana bûyerek di komê de cûreyek çengelê pêk tîne.

  • Ger di heman demê de tiştek di komê de çêbibe çi dibe? yeka dinê bûyer?
  • Ma shell-operator dê mînakek din a hookê bimeşîne?
  • Ger, bêje, pênc bûyer di komê de yekcar biqewimin?
  • Ma operator-şell dê wan bi paralelî pêvajoyê bike?
  • Li ser çavkaniyên vexwarinê yên wekî bîranîn û CPU çi ye?

Bi bextewarî, shell-operator xwedan mekanîzmayek rêzê ya çêkirî ye. Hemî bûyer li rêzê têne rêz kirin û li pey hev têne pêvajo kirin.

Werin em vê yekê bi mînakan diyar bikin. Dibêjin du çengên me hene. Bûyera yekem diçe hookê yekem. Dema ku pêvajoyek wê qediya, rêz pêşde diçe. Sê bûyerên paşîn berbi çengê duyemîn ve têne rêve kirin - ew ji rêzê têne derxistin û di "bundle" de têkevin nav wê. Ku heye hook komek bûyerên distîne - an, bi rastî, rêzek çarçoveyên girêdanê.

Her weha van bûyer dikarin di yek mezin de bêne hev kirin. Parametre ji bo vê yekê berpirsiyar e group di veavakirina girêdanê de.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Hûn dikarin her jimarek dorê / çeng û hevbendên wan ên cihêreng biafirînin. Mînakî, yek rêzek dikare bi du çengan re bixebite, an berevajî.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Tişta ku hûn hewce ne bikin ev e ku qadê li gorî xwe mîheng bikin queue di veavakirina girêdanê de. Ger navek dorê neyê diyar kirin, hook li ser rêza xwerû dimeşe (default). Vê mekanîzmaya rêzgirtinê dihêle hûn dema ku bi çengelan re dixebitin hemî pirsgirêkên rêveberiya çavkaniyê bi tevahî çareser bikin.

encamê

Me rave kir ku şel-operator çi ye, nîşan da ku ew çawa dikare were bikar anîn da ku bi lez û bez operatorên Kubernetes biafirîne, û çend mînakên karanîna wê dan.

Agahiyên hûrgulî di derbarê shell-operatorê de, û her weha dersek bilez a li ser meriv çawa bikar tîne, di pêwendiya têkildar de heye. depoyên li ser GitHub. Dudilî nebin ku hûn bi pirsan bi me re têkilî daynin: hûn dikarin wan bi taybetî nîqaş bikin Koma Telegram (bi rûsî) an bi vê forûmê (bi Îngilîzî).

Û heke we jê hez kir, em her gav kêfxweş in ku pirsgirêkên nû / PR / stêrk li ser GitHub bibînin, ku, bi awayê, hûn dikarin yên din bibînin projeyên balkêş. Di nav wan de hêjayî balkişandinê ye addon-operator, ku birayê mezin ê shell-operator e. Vê karûbar nexşeyên Helm bikar tîne da ku pêvekan saz bike, dikare nûvekirinan radest bike û pîvanên / nirxên cihêreng ên nexşeyê bişopîne, pêvajoya sazkirina nexşeyan kontrol dike, û di heman demê de dikare wan di bersiva bûyerên di komê de biguhezîne.

Ajotin? Bash! Bi shell-operatorê re hevdîtin bikin (vekolîn û raporta vîdyoyê ji KubeCon EU'2020)

Vîdyo û slaytên

Vîdyo ji performansê (~ 23 hûrdem):


Pêşkêşkirina raporê:

PS

Li ser bloga me jî bixwînin:

Source: www.habr.com

Add a comment