Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Bu il əsas Avropa Kubernetes konfransı - KubeCon + CloudNativeCon Europe 2020 virtual idi. Lakin formatın belə dəyişməsi çoxdan planlaşdırdığımız “Get? Bash! Açıq Mənbə layihəmizə həsr olunmuş Shell-operatoru ilə tanış olun mərmi operatoru.

Söhbətdən ilhamlanan bu məqalə Kubernetes üçün operatorların yaradılması prosesini sadələşdirməyə yanaşmanı təqdim edir və bir shell-operatordan istifadə edərək minimum səylə necə özünüz edə biləcəyinizi göstərir.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Təqdim edir məruzə ilə video (İngilis dilində ~ 23 dəqiqə, məqalədən nəzərəçarpacaq dərəcədə daha informativdir) və ondan mətn şəklində əsas çıxarış. Get!

Flant-da biz daim hər şeyi optimallaşdırır və avtomatlaşdırırıq. Bu gün başqa bir maraqlı konsepsiya haqqında danışacağıq. Tanış: bulud-doğma qabıq skripti!

Ancaq gəlin bütün bunların baş verdiyi kontekstdən başlayaq: Kubernetes.

Kubernetes API və nəzarətçiləri

Kubernetes-dəki API hər bir obyekt növü üçün qovluqları olan bir növ fayl serveri kimi təqdim edilə bilər. Bu serverdəki obyektlər (resurslar) YAML faylları ilə təmsil olunur. Bundan əlavə, server üç şeyi etməyə imkan verən əsas API-yə malikdir:

  • almaq növü və adı ilə resurs;
  • dəyişmək resurs (bu halda server yalnız "düzgün" obyektləri saxlayır - bütün səhv formalaşmış və ya digər qovluqlar üçün nəzərdə tutulmuş obyektlər silinir);
  • təqib edin resurs üçün (bu halda istifadəçi dərhal onun cari/yenilənmiş versiyasını alır).

Beləliklə, Kubernetes üç əsas metodla bir növ fayl serveri (YAML manifestləri üçün) kimi çıxış edir (bəli, əslində başqaları da var, lakin biz onları hələlik buraxacağıq).

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Problem ondadır ki, server yalnız məlumatları saxlaya bilir. İşləmək üçün sizə lazımdır nəzarətçi - Kubernetes dünyasında ikinci ən vacib və əsas konsepsiya.

Nəzarətçilərin iki əsas növü var. Birincisi Kubernetes-dən məlumat alır, onu iç-içə məntiqə uyğun emal edir və K8-lərə qaytarır. İkincisi Kubernetesdən məlumat alır, lakin birinci növdən fərqli olaraq bəzi xarici resursların vəziyyətini dəyişir.

Kubernetes-də Yerləşdirmənin yaradılması prosesinə daha yaxından nəzər salaq:

  • Yerləşdirmə Nəzarətçisi (daxildir kube-controller-manager) Yerləşdirmə haqqında məlumat alır və ReplicaSet yaradır.
  • ReplicaSet bu məlumat əsasında iki replika (iki pod) yaradır, lakin bu podlar hələ planlaşdırılmayıb.
  • Planlayıcı podları planlaşdırır və onların YAML-lərinə qovşaq məlumatı əlavə edir.
  • Kubelets xarici resursda dəyişikliklər edir (deyin Docker).

Sonra bütün bu ardıcıllıq tərs qaydada təkrarlanır: kubelet konteynerləri yoxlayır, podun statusunu hesablayır və onu geri göndərir. ReplicaSet nəzarətçisi statusu alır və replika dəstinin vəziyyətini yeniləyir. Eyni şey Deployment Controller ilə baş verir və istifadəçi nəhayət yenilənmiş (cari) statusu alır.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Shell-operator

Belə çıxır ki, Kubernetes müxtəlif kontrollerlərin birgə işinə əsaslanır (Kubernetes operatorları da nəzarətçilərdir). Sual yaranır, minimal səylə öz operatorunuzu necə yaratmaq olar? Və burada inkişaf etdirdiyimiz köməyə gəlir mərmi operatoru. Bu, sistem administratorlarına tanış metodlardan istifadə edərək öz bəyanatlarını yaratmağa imkan verir.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Sadə misal: sirləri kopyalamaq

Sadə bir misala baxaq.

Tutaq ki, Kubernetes klasterimiz var. Onun ad sahəsi var default bir sirr ilə mysecret. Bundan əlavə, klasterdə başqa ad boşluqları da var. Bəzilərinin üzərinə xüsusi etiket yapışdırılır. Məqsədimiz Secreti etiketlə ad boşluqlarına köçürməkdir.

Tapşırıq ona görə çətinləşir ki, klasterdə yeni ad boşluqları görünə bilər və bəzilərində bu etiket ola bilər. Digər tərəfdən, etiket silinəndə Gizli də silinməlidir. Bundan əlavə, Sirrin özü də dəyişə bilər: bu halda, yeni Gizli etiketləri olan bütün ad boşluqlarına kopyalanmalıdır. Gizli hər hansı bir ad məkanında təsadüfən silinərsə, operatorumuz onu dərhal bərpa etməlidir.

Tapşırıq tərtib edildikdən sonra, shell-operatordan istifadə edərək onu həyata keçirməyə başlamağın vaxtı gəldi. Ancaq əvvəlcə qabıq operatorunun özü haqqında bir neçə söz söyləməyə dəyər.

Shell-operator necə işləyir

Kubernetesdəki digər iş yükləri kimi, shell-operator da öz podunda işləyir. Kataloqdakı bu podda /hooks icra edilə bilən fayllar saxlanılır. Bunlar Bash, Python, Ruby və s.-də skriptlər ola bilər. Biz belə icra edilə bilən faylları qarmaqlar adlandırırıq (qarmaqlar).

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Shell-operator Kubernetes tədbirlərinə abunə olur və ehtiyac duyduğumuz hadisələrə cavab olaraq bu qarmaqları işlədir.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Qabıq operatoru hansı qarmağın və nə vaxt işə salınacağını necə bilir? Məsələ ondadır ki, hər qarmağın iki mərhələsi var. Başlanğıc zamanı shell-operator bütün qarmaqları arqumentlə işlədir --config Bu konfiqurasiya mərhələsidir. Və ondan sonra qarmaqlar normal şəkildə işə salınır - bağlandıqları hadisələrə cavab olaraq. Sonuncu halda, çəngəl bağlama kontekstini alır (məcburi kontekst) - aşağıda daha ətraflı danışacağımız JSON formatında məlumatlar.

Bash-da operator etmək

İndi biz həyata keçirməyə hazırıq. Bunun üçün iki funksiya yazmalıyıq (yeri gəlmişkən, tövsiyə edirik kitabxana shell_lib, Bash-də yazı qarmaqlarını çox asanlaşdırır):

  • birincisi konfiqurasiya mərhələsi üçün lazımdır - o, bağlama kontekstini göstərir;
  • ikincisi qarmağın əsas məntiqini ehtiva edir.

#!/bin/bash

source /shell_lib.sh

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

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Növbəti addım hansı obyektlərə ehtiyacımız olduğuna qərar verməkdir. Bizim vəziyyətimizdə izləməliyik:

  • dəyişikliklər üçün mənbə sirri;
  • klasterdəki bütün ad boşluqları, beləliklə hansıların onlara etiket əlavə edildiyini biləsiniz;
  • onların hamısının mənbə sirri ilə sinxron olmasını təmin etmək üçün hədəf sirləri.

Gizli mənbəyə abunə olun

Bunun üçün bağlama konfiqurasiyası olduqca sadədir. Adı ilə Secret ilə maraqlandığımızı bildiririk mysecret ad məkanında default:

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

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

Nəticədə, mənbə sirri dəyişdikdə çəngəl işə salınacaq (src_secret) və aşağıdakı məcburi konteksti qəbul edin:

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Gördüyünüz kimi, adı və bütün obyekti ehtiva edir.

Ad boşluqlarının izlənməsi

İndi ad boşluqlarına abunə olmalısınız. Bunu etmək üçün aşağıdakı bağlama konfiqurasiyasını təyin edirik:

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

Gördüyünüz kimi, adla konfiqurasiyada yeni bir sahə meydana çıxdı jqFilter. Adından da göründüyü kimi, jqFilter bütün lazımsız məlumatları filtrləyir və bizi maraqlandıran sahələrlə yeni JSON obyekti yaradır. Bənzər konfiqurasiyaya malik çəngəl aşağıdakı bağlama kontekstini alacaq:

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

O, bir sıra ehtiva edir filterResults klasterdəki hər ad sahəsi üçün. Boolean dəyişəni hasLabel etiketin verilmiş ad sahəsinə əlavə edilib-edilmədiyini göstərir. Seçici keepFullObjectsInMemory: false tam obyektləri yaddaşda saxlamağa ehtiyac olmadığını göstərir.

Hədəf sirlərini izləmək

Annotasiyası olan bütün sirlərə abunə oluruq managed-secret: "yes" (bunlar bizim hədəfimizdir 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

Bu vəziyyətdə jqFilter ad sahəsi və parametrdən başqa bütün məlumatları süzür resourceVersion. Sonuncu parametr sirri yaratarkən annotasiyaya keçdi: o, sirlərin versiyalarını müqayisə etməyə və onları aktual saxlamağa imkan verir.

Bu şəkildə konfiqurasiya edilmiş çəngəl, icra edildikdə, yuxarıda təsvir edilən üç bağlama kontekstini alacaq. Onlar bir növ snapshot kimi düşünülə bilər (snapshot) klaster.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Bütün bu məlumatlara əsaslanaraq əsas alqoritm hazırlana bilər. Bütün ad boşluqlarında təkrarlanır və:

  • əgər hasLabel məsələlər true cari ad sahəsi üçün:
    • qlobal sirri yerli ilə müqayisə edir:
      • əgər onlar eynidirsə, heç nə etmir;
      • fərqlidirlərsə - icra edir kubectl replace və ya create;
  • əgər hasLabel məsələlər false cari ad sahəsi üçün:
    • Secretin verilmiş ad məkanında olmadığına əmin olur:
      • yerli sirr varsa, istifadə edərək onu silin kubectl delete;
      • yerli sirr aşkar olunmazsa, heç nə etmir.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Bash-da alqoritmin həyata keçirilməsi saytımızdan yükləyə bilərsiniz nümunələri ilə depolar.

Beləliklə, 35 sətir YAML konfiqurasiyasından və təxminən eyni miqdarda Bash kodundan istifadə edərək sadə Kubernetes nəzarətçisi yarada bildik! Qabıq-operatorun işi onları bir-birinə bağlamaqdır.

Bununla belə, sirləri kopyalamaq yardım proqramının yeganə tətbiq sahəsi deyil. Onun nəyə qadir olduğunu göstərmək üçün daha bir neçə misal göstərmək olar.

Nümunə 1: ConfigMap-a dəyişikliklərin edilməsi

Üç poddan ibarət Yerləşdirməyə baxaq. Podlar bəzi konfiqurasiyaları saxlamaq üçün ConfigMap-dən istifadə edir. Podlar işə salındıqda, ConfigMap müəyyən bir vəziyyətdə idi (gəlin onu v.1 adlandıraq). Müvafiq olaraq, bütün podlar ConfigMap-in bu xüsusi versiyasını istifadə edir.

İndi fərz edək ki, ConfigMap dəyişib (v.2). Bununla belə, podlar ConfigMap-in (v.1) əvvəlki versiyasından istifadə edəcək:

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Onları yeni ConfigMap-a (v.2) keçməyə necə nail ola bilərəm? Cavab sadədir: şablondan istifadə edin. Bölməyə yoxlama məbləği annotasiyası əlavə edək template Yerləşdirmə konfiqurasiyaları:

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Nəticə olaraq, bu yoxlama cəmi bütün podlarda qeydə alınacaq və Yerləşdirmə ilə eyni olacaq. İndi yalnız ConfigMap dəyişdikdə annotasiyanı yeniləməlisiniz. Və bu vəziyyətdə shell-operator kömək edir. Sizə lazım olan tək şey proqramdır ConfigMap-a abunə olacaq və yoxlama məbləğini yeniləyəcək çəngəl.

İstifadəçi ConfigMap-da dəyişikliklər edərsə, shell-operator onları görəcək və yoxlama məbləğini yenidən hesablayacaq. Bundan sonra Kubernetesin sehri işə düşəcək: orkestr podu öldürəcək, yenisini yaradacaq və onun olmasını gözləyəcək. Ready, və növbəti birinə keçir. Nəticədə, Deployment sinxronlaşdırılacaq və ConfigMap-in yeni versiyasına keçəcək.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Nümunə 2: Xüsusi Resurs Tərifləri ilə işləmək

Bildiyiniz kimi, Kubernetes sizə fərdi növ obyektlər yaratmağa imkan verir. Məsələn, növ yarada bilərsiniz MysqlDatabase. Tutaq ki, bu növün iki metadata parametri var: name и namespace.

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

MySQL verilənlər bazası yarada biləcəyimiz müxtəlif ad boşluqları olan Kubernetes klasterimiz var. Bu halda shell-operator resursları izləmək üçün istifadə edilə bilər MysqlDatabase, onları MySQL serverinə qoşmaq və klasterin arzu olunan və müşahidə olunan vəziyyətlərini sinxronlaşdırmaq.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Nümunə 3: Klaster Şəbəkəsinin Monitorinqi

Bildiyiniz kimi, ping-dən istifadə şəbəkəyə nəzarət etməyin ən sadə yoludur. Bu nümunədə shell-operator istifadə edərək belə monitorinqin necə həyata keçiriləcəyini göstərəcəyik.

Əvvəlcə qovşaqlara abunə olmalısınız. Shell operatoru hər bir qovşağın adına və IP ünvanına ehtiyac duyur. Onların köməyi ilə o, bu qovşaqlara ping atacaq.

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

Parametr executeHookOnEvent: [] hər hansı bir hadisəyə cavab olaraq (yəni qovşaqların dəyişdirilməsinə, əlavə edilməsinə, silinməsinə cavab olaraq) çəngəl işləməsinin qarşısını alır. Bununla belə, o qaçacaq (və qovşaqların siyahısını yeniləyin) Planlaşdırılıb - sahənin müəyyən etdiyi kimi hər dəqiqə schedule.

İndi sual yaranır ki, biz paket itkisi kimi problemləri necə dəqiq bilirik? Koda nəzər salaq:

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
}

Biz qovşaqların siyahısını təkrarlayırıq, onların adlarını və IP ünvanlarını alırıq, onlara ping edirik və nəticələri Prometeyə göndəririk. Shell-operator ölçüləri Prometheus-a ixrac edə bilər, onları mühit dəyişənində göstərilən yola uyğun olaraq yerləşən faylda saxlamaq $METRICS_PATH.

Burada belədir klasterdə sadə şəbəkə monitorinqi üçün operator edə bilərsiniz.

Növbə mexanizmi

Shell-operatora daxil edilmiş başqa bir vacib mexanizmi təsvir etmədən bu məqalə natamam olardı. Təsəvvür edin ki, o, klasterdəki bir hadisəyə cavab olaraq bir növ qarmaq yerinə yetirir.

  • Eyni zamanda klasterdə bir şey baş verərsə nə olar? Başqası hadisə?
  • Shell-operator çəngəlin başqa bir nümunəsini işlədəcəkmi?
  • Bəs, deyək ki, klasterdə eyni anda beş hadisə baş verərsə?
  • Shell-operator onları paralel olaraq emal edəcəkmi?
  • Yaddaş və CPU kimi istehlak resursları haqqında nə demək olar?

Xoşbəxtlikdən, shell-operator daxili növbə mexanizminə malikdir. Bütün hadisələr növbəyə qoyulur və ardıcıllıqla işlənir.

Bunu misallarla izah edək. Tutaq ki, bizdə iki qarmaq var. İlk hadisə ilk qarmağa gedir. Onun işlənməsi başa çatdıqdan sonra növbə irəliləyir. Növbəti üç hadisə ikinci çəngələ yönləndirilir - onlar növbədən çıxarılır və "paketə" daxil edilir. Yəni hook bir sıra hadisələr qəbul edir — və ya daha dəqiq desək, bağlayan kontekstlər massivi.

Həm də bunlar hadisələr bir böyük hadisədə birləşdirilə bilər. Parametr buna cavabdehdir group bağlama konfiqurasiyasında.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

İstənilən sayda növbə/qarmaq və onların müxtəlif kombinasiyalarını yarada bilərsiniz. Məsələn, bir növbə iki qarmaq ilə işləyə bilər və ya əksinə.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Sizə lazım olan tək şey sahəni müvafiq olaraq konfiqurasiya etməkdir queue bağlama konfiqurasiyasında. Əgər növbə adı göstərilməyibsə, çəngəl standart növbədə işləyir (default). Bu növbə mexanizmi qarmaqlarla işləyərkən bütün resursların idarə edilməsi problemlərini tamamilə həll etməyə imkan verir.

Nəticə

Biz shell-operatorun nə olduğunu izah etdik, ondan tez və asanlıqla Kubernetes operatorlarını yaratmaq üçün necə istifadə oluna biləcəyini göstərdik və onun istifadəsinə dair bir neçə nümunə verdik.

Shell-operator haqqında ətraflı məlumat, eləcə də ondan necə istifadə olunacağına dair sürətli təlimat müvafiq bölmədə mövcuddur. GitHub-da depolar. Suallarınız üçün bizimlə əlaqə saxlamaqdan çəkinməyin: onları xüsusi müzakirələrdə müzakirə edə bilərsiniz Telegram qrupu (rus dilində) və ya dildə bu forum (ingilis dilində).

Bəyəndinizsə, GitHub-da yeni buraxılışları/PR/ulduzları görməkdən həmişə şad olarıq, yeri gəlmişkən, başqalarını da tapa bilərsiniz. maraqlı layihələr. Onların arasında vurğulamağa dəyər addon-operator, shell-operatorun böyük qardaşıdır. Bu yardım proqramı əlavələri quraşdırmaq üçün Helm diaqramlarından istifadə edir, yeniləmələri çatdıra və müxtəlif diaqram parametrlərinə/dəyərlərinə nəzarət edə bilər, diaqramların quraşdırılması prosesinə nəzarət edir və həmçinin klasterdəki hadisələrə cavab olaraq onları dəyişdirə bilər.

Get? Bash! Qabıq operatoru ilə tanış olun (KubeCon EU'2020-dən baxış və video hesabat)

Videolar və slaydlar

Tamaşadan video (~23 dəqiqə):

Videonu çalın

Hesabat təqdimatı:

PS

Bloqumuzda da oxuyun:

Mənbə: www.habr.com

DDoS mühafizəsi, VPS VDS serverləri olan saytlar üçün etibarlı hostinq alın 🔥 DDoS qorunması, VPS VDS serverləri ilə etibarlı veb sayt hostinqi alın | ProHoster