Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

Jixwe li ser bloga me gotarên ku li ser diaxivin hene kapasîteyên operator li Kubernetes û çawa bi xwe operatorek hêsan binivîse. Vê carê em dixwazin çareseriya xweya Çavkaniya Vekirî, ya ku afirandina operatoran digihîje astek pir-hêsan pêşkêşî we bikin - binihêrin shell-operator!

Çima?

Fikra şêl-operatorek pir hêsan e: bibin aboneyên bûyerên ji tiştên Kubernetes, û gava ku ev bûyer têne wergirtin, bernameyek derveyî bidin destpêkirin, jê re agahdarî li ser bûyerê peyda bikin:

Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

Pêdivîbûna wê rabû dema ku, di dema xebata koman de, karên piçûk dest pê kirin ku me bi rastî dixwest ku bi awayek rast otomatîk bikin. Hemî van karên piçûk bi karanîna nivîsarên bash ên hêsan hatin çareser kirin, her çend, wekî ku hûn dizanin, çêtir e ku meriv operatoran li Golang binivîsîne. Eşkere ye, veberhênana di pêşkeftina tev-pîvek a operatorek ji bo her karekî wusa piçûk dê bêbandor be.

Operator di 15 deqîqeyan de

Ka em li mînakek binihêrin ka çi dikare di komikek Kubernetes de were otomatîk kirin û çawa operator-şell dikare alîkariyê bike. Nimûneyek dê jêrîn be: dubarekirina razek ji bo gihîştina qeydkirina docker.

Podên ku wêneyên ji qeydek taybet bikar tînin divê di manîfestoya xwe de girêdanek bi dizî bi daneyan re ji bo gihîştina tomarê vehewînin. Divê ev veşartî di her navekî de berî çêkirina pods were afirandin. Ev dikare bi destan were kirin, lê heke em hawîrdorên dînamîkî saz bikin, wê hingê cîhê navan ji bo yek serîlêdanê dê pir bibe. Û heke 2-3 serîlêdan jî nebin ... hejmara razan pir mezin dibe. Û tiştek din di derbarê razan de: Ez dixwazim mifteyê biguherim da ku dem bi dem bigihîjim qeydê. Paştirîn, operasyonên manual wek çareserî bi temamî bêbandor - Pêdivî ye ku em afirandin û nûvekirina razan otomatîk bikin.

automation Simple

Werin em skrîptek şêlê binivîsin ku her N saniyeyekê carekê dimeşe û cîhên navan ji bo hebûna razekê kontrol dike, û heke nepenî tune be, wê hingê ew tê afirandin. Feydeya vê çareseriyê ev e ku ew wekî skrîptek şêlê di cron de xuya dike - ji her kesî re nêzîkatiyek klasîk û têgihîştî. Nerazîbûn ev e ku di navbera di navbera destpêkirina wê de navekî nû dikare were afirandin û ji bo demekê ew ê bê veşartî bimîne, ku dê bibe sedema xeletiyên di destpêkirina potan de.

Otomasyon bi shell-operatorê

Ji bo ku skrîpta me rast bixebite, gava ku navek tê zêdekirin pêdivî ye ku destpêkirina krona klasîk bi destpêkek were guheztin: Di vê rewşê de, hûn dikarin berî ku wê bikar bînin veşariyek biafirînin. Ka em bibînin ka meriv çawa vê bi karanîna shell-operatorê bicîh tîne.

Pêşî, em li senaryoyê binêrin. Skrîptên di şertên şêl-operatorê de jê re hook têne gotin. Her hook dema ku bi ala run --config şêl-operatorê li ser girêdanên xwe agahdar dike, yanî. li ser kîjan bûyeran divê were destpêkirin. Di rewşa me de em ê bikar bînin onKubernetesEvent:

#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
  { "kind": "namespace",
    "event":["add"]
  }
]}
EOF
fi

Li vir tê diyar kirin ku em dixwazin bûyeran zêde bikin (add) tiştên cureyê namespace.

Naha hûn hewce ne ku koda ku dê dema bûyer çêbibe lê zêde bikin:

#!/bin/bash
if [[ $1 == "--config" ]] ; then
  # конфигурация
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
  "event":["add"]
}
]}
EOF
else
  # реакция:
  # узнать, какой namespace появился
  createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
  # создать в нём нужный секрет
  kubectl create -n ${createdNamespace} -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  ...
data:
  ...
EOF
fi

Ecêb! Di encamê de senaryoyek piçûk û bedew bû. Ji bo "vejîna" wê, du gav mane: wêneyê amade bikin û wê di komê de bidin destpêkirin.

Amadekirina wêneyek bi çengelê

Ger hûn li skrîptê binêrin, hûn dikarin bibînin ku ferman têne bikar anîn kubectl и jq. Ev tê wê wateyê ku wêne divê van tiştan hebin: hookê me, şel-operatorê ku dê bûyeran bişopîne û çengelê bimeşîne, û fermanên ku ji hêla hook ve têne bikar anîn (kubectl û jq). Hub.docker.com jixwe wêneyek amade ye ku tê de shell-operator, kubectl û jq têne pak kirin. Tiştê ku dimîne ev e ku meriv hookek hêsan lê zêde bike Dockerfile:

$ cat Dockerfile
FROM flant/shell-operator:v1.0.0-beta.1-alpine3.9
ADD namespace-hook.sh /hooks

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

Di komekê de diherike

Ka em careke din li çengê binerin û vê carê binivîsin ka ew di komê de çi kiryaran û bi kîjan tiştan dike:

  1. dibe abone li bûyerên çêkirina cîhê navan;
  2. di nav navan de ji xeynî cîhê ku lê lê hatiye vekirin, sirekî diafirîne.

Derket holê ku podê ku dê wêneya me tê de were destpêkirin divê destûr hebe ku van çalakiyan bike. Ev dikare bi afirandina Hesabê Xizmeta xweya xwe were kirin. Pêdivî ye ku destûr di forma ClusterRole û ClusterRoleBinding de were kirin, ji ber em bi tiştên ji tevahiya komê re eleqedar dibin.

Danasîna paşîn a di YAML de dê bi vî rengî xuya bike:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitor-namespaces-acc

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: monitor-namespaces
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "patch"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: monitor-namespaces
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: monitor-namespaces
subjects:
  - kind: ServiceAccount
    name: monitor-namespaces-acc
    namespace: example-monitor-namespaces

Hûn dikarin wêneya berhevkirî wekî Pêvekek hêsan dest pê bikin:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1
      serviceAccountName: monitor-namespaces-acc

Ji bo rehetiyê, cîhek navekî cihê tê afirandin ku li wir şell-operator dê were destpêkirin û diyardeyên çêkirî dê werin sepandin:

$ kubectl create ns example-monitor-namespaces
$ kubectl -n example-monitor-namespaces apply -f rbac.yaml
$ kubectl -n example-monitor-namespaces apply -f deployment.yaml

Hemî ev e: operatorê şêl dê dest pê bike, bibe abone li bûyerên çêkirina cîhê navan û gava ku hewce bike çengelê bimeşîne.

Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

Bi vî awayî, skrîptek şêlê ya hêsan ji bo Kubernetes veguherî operatorek rastîn û wekî beşek ji komekê dixebite. Û ev hemî bêyî pêvajoya tevlihev a pêşveçûna operatorên li Golang:

Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

Di vê mijarê de mînakek din jî heye...Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

Em ê di yek ji weşanên jêrîn de wateya wê bi hûrgulî eşkere bikin.

Fîlterkirin

Şopandina tiştan baş e, lê pir caran hewcedarî bi bertek heye guhertina hin taybetiyên object, bo nimûne, ji bo guhertina hejmara kopiyên di Deployment de an jî ji bo guhertina etîketên object.

Dema ku bûyerek tê, şell-operator manîfestoya JSON ya objektê distîne. Em dikarin taybetmendiyên ku me di vê JSON-ê de eleqedar dikin hilbijêrin û hookê bimeşînin bi tenê gava ku ew diguherin. Qadeke vê yekê heye jqFilter, ku hûn hewce ne ku jq îfadeya ku dê li ser diyardeya JSON-ê were sepandin diyar bikin.

Mînakî, ji bo bersivdana guheztinên etîketan ji bo tiştên Dabeşkirinê, hûn hewce ne ku zeviyê fîlter bikin labels ji qadê metadata. Mîheng dê bi vî rengî be:

cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "deployment",
  "event":["update"],
  "jqFilter": ".metadata.labels"
}
]}
EOF

Ev îfadeya jqFilter nîşana JSON-ya dirêj a Deployment bi etîketan vediguherîne JSON-ya kurt:

Nasandina shell-operator: afirandina operatoran ji bo Kubernetes hêsantir bû

shell-operator dê tenê gava ku ev JSON-ya kurt biguhezîne hookê bixebitîne, û guhertinên li taybetmendiyên din dê bêne paşguh kirin.

Çarçoveya destpêkirina Hook

Veavakirina hook dihêle hûn ji bo bûyeran çend vebijarkan diyar bikin - mînakî, 2 vebijarkên ji bo bûyerên ji Kubernetes û 2 bername:

{"onKubernetesEvent":[
  {"name":"OnCreatePod",
  "kind": "pod",
  "event":["add"]
  },
  {"name":"OnModifiedNamespace",
  "kind": "namespace",
  "event":["update"],
  "jqFilter": ".metadata.labels"
  }
],
"schedule": [
{ "name":"every 10 min",
  "crontab":"* */10 * * * *"
}, {"name":"on Mondays at 12:10",
"crontab": "* 10 12 * * 1"
]}

Vekêşînek piçûk: erê, shell-operator piştgirî dike skrîptên şêwaza crontab dimeşîne. Zêdetir hûrgulî dikarin di nav de werin dîtin belgekirin.

Ji bo ku ferq bike ka çima çengelê hatiye destpêkirin, şell-operator pelek demkî diafirîne û rê li ber wê di guhêrbarekê de ji hookê re derbas dike. BINDING_CONTEXT_TYPE. Di pelê de ravekek JSON ya sedema xebitandina hook heye. Mînakî, her 10 hûrdeman çeng dê bi naveroka jêrîn bimeşe:

[{ "binding": "every 10 min"}]

... û roja duşemê ew ê bi vê dest pê bike:

[{ "binding": "every 10 min"}, { "binding": "on Mondays at 12:10"}]

bo onKubernetesEvent Dê bêtir teşeyên JSON hebin, ji ber ew danasîna objektê dihewîne:

[
 {
 "binding": "onCreatePod",
 "resourceEvent": "add",
 "resourceKind": "pod",
 "resourceName": "foo",
 "resourceNamespace": "bar"
 }
]

Naveroka zeviyan ji navên wan têne fêm kirin, û hûrguliyên bêtir dikarin tê de bixwînin belgekirin. Mînaka wergirtina navek çavkaniyek ji zeviyek resourceName bikaranîna jq jixwe di hookek ku sirên dubare dike de hatîye xuyang kirin:

jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH

Hûn dikarin zeviyên din bi rengek wekhev bistînin.

Çi ye?

Di depoya projeyê de, di /mînakên pelrêçan, Nimûneyên çengelan hene ku amade ne ku li ser komekê bixebitin. Dema ku çengelên xwe dinivîsin, hûn dikarin wan wekî bingehek bikar bînin.

Ji bo berhevkirina metrîkan bi karanîna Prometheus piştgirî heye - metrîkên berdest di beşê de têne diyar kirin Metrîk.

Wekî ku hûn texmîn dikin, operatorê şêl li Go-yê hatî nivîsandin û di bin lîsansek Çavkaniya Vekirî (Apache 2.0) de tê belav kirin. Em ê ji bo her alîkariyek pêşveçûnê spasdar bin projeya li ser GitHub: û stêrk, û pirsgirêk, û daxwazên xwe bikişînin.

Perdeya nepenîtiyê rakin, em ê jî we agahdar bikin ku şel-operator e biçûk beşek ji pergala me ya ku dikare pêvekên ku di koma Kubernetes-ê de hatî saz kirin nûve bike û çalakiyên cihêreng ên otomatîkî pêk bîne. Li ser vê pergalê bêtir bixwînin vegotin bi rastî roja Duşemê li HighLoad++ 2019 li St.

Me planek heye ku em mayî ya vê pergalê vekin: addon-operator û berhevoka meya çeng û modulan. Bi awayê, addon-operator jixwe heye li ser github heye, lê belgeyên ji bo wê hîn jî di rê de ne. Serbestberdana berhevoka modulan ji bo havînê tê plansaz kirin.

Bi rê ve bimînin!

PS

Li ser bloga me jî bixwînin:

Source: www.habr.com

Add a comment