indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Taun ieu, konperénsi Kubernetes Éropa utama - KubeCon + CloudNativeCon Europe 2020 - virtual. Nanging, parobihan format sapertos kitu henteu ngahalangan kami pikeun ngirimkeun laporan anu direncanakeun lami urang "Go? Bash! Minuhan Shell-operator" dedicated ka proyék Open Source kami cangkang-operator.

Artikel ieu, diideuan ku omongan, nampilkeun pendekatan pikeun nyederhanakeun prosés nyiptakeun operator pikeun Kubernetes sareng nunjukkeun kumaha anjeun tiasa ngadamel nyalira kalayan usaha minimal nganggo cangkang-operator.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Nepangkeun video laporan (~ 23 menit dina basa Inggris, noticeably leuwih informatif ti artikel) jeung ekstrak utama ti dinya dina wangun téks. indit!

Di Flant kami terus-terusan ngaoptimalkeun sareng ngajadikeun otomatis sadayana. Dinten ieu kami bakal ngobrol ngeunaan konsép seru sejen. Papanggih: skrip cangkang asli awan!

Nanging, hayu urang mimitian ku kontéks dimana sadaya ieu kajantenan: Kubernetes.

Kubernetes API jeung controller

API dina Kubernetes bisa digambarkeun salaku jenis server file kalawan diréktori pikeun tiap jenis objék. Objék (sumberdaya) dina server ieu digambarkeun ku file YAML. Salaku tambahan, server ngagaduhan API dasar anu ngamungkinkeun anjeun ngalakukeun tilu hal:

  • pikeun nampa sumberdaya ku jenis sarta ngaran;
  • robih sumberdaya (dina hal ieu, server ngan nyimpen obyék "bener" - sadayana salah kabentuk atawa dimaksudkeun pikeun directories séjén dipiceun);
  • lagu pikeun sumberdaya (dina hal ieu, pamaké geuwat narima versi na ayeuna / diropéa).

Ku kituna, Kubernetes tindakan minangka jenis server file (pikeun YAML manifests) kalawan tilu métode dasar (enya, sabenerna aya batur, tapi urang bakal ngaleungitkeun aranjeunna pikeun ayeuna).

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Masalahna nyaeta server ngan bisa nyimpen informasi. Pikeun nyieun jalan anjeun peryogi controller - konsép kadua pangpentingna sarta fundamental di dunya Kubernetes.

Aya dua jenis utama controller. Kahiji nyokot informasi ti Kubernetes, ngolah eta nurutkeun logika nested, sarta balik deui ka K8s. Anu kadua nyandak inpormasi ti Kubernetes, tapi, teu sapertos jinis anu kahiji, ngarobih kaayaan sababaraha sumber éksternal.

Hayu urang tingali langkung caket kana prosés nyiptakeun Deployment di Kubernetes:

  • Deployment Controller (kaasup dina kube-controller-manager) nampi inpormasi ngeunaan Deployment sareng nyiptakeun ReplicaSet.
  • ReplicaSet nyiptakeun dua réplika (dua pods) dumasar kana inpormasi ieu, tapi pods ieu teu acan dijadwalkeun.
  • Penjadwal ngajadwalkeun pod sareng nambihan inpormasi node kana YAML na.
  • Kubelets nyieun parobahan kana sumberdaya éksternal (sebutkeun Docker).

Lajeng sakabeh runtuyan ieu diulang dina urutan sabalikna: kubelet mariksa wadahna, ngitung status pod sarta ngirimkeunana deui. Controller ReplicaSet nampi status sareng ngapdet kaayaan set replika. Hal anu sami kajadian sareng Deployment Controller sareng pangguna tungtungna nampi status anu diropéa (ayeuna).

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Cangkang-operator

Tétéla yén Kubernetes dumasar kana gawé babarengan rupa-rupa controller (operator Kubernetes ogé controller). Patarosan timbul, kumaha carana nyieun operator sorangan kalawan usaha minimal? Sareng di dieu anu kami kembangkeun sumping ka nyalametkeun cangkang-operator. Hal ieu ngamungkinkeun administrator sistem nyieun pernyataan sorangan ngagunakeun métode akrab.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Conto basajan: nyalin rusiah

Hayu urang nempo conto basajan.

Anggap urang gaduh klaster Kubernetes. Cai mibanda ngaranspasi default kalawan sababaraha Rahasia mysecret. Sajaba ti éta, aya spasi ngaran séjén dina klaster. Sababaraha di antarana boga labél husus napel aranjeunna. Tujuanana urang nyalin Rahasia kana namespaces kalawan labél.

Tugasna nyusahkeun ku kanyataan yén rohangan ngaran anyar tiasa muncul dina kluster, sareng sababaraha di antarana tiasa gaduh labél ieu. Di sisi anu sanés, nalika labélna dihapus, Rahasia ogé kedah dihapus. Salaku tambahan, Rahasia sorangan ogé tiasa robih: dina hal ieu, Rahasia énggal kedah disalin ka sadaya rohangan ngaran anu nganggo labél. Upami Rahasia teu kahaja dihapus dina rohangan ngaran mana waé, operator kami kedah langsung ngabalikeunana.

Ayeuna tugasna parantos dirumuskeun, waktosna pikeun ngamimitian ngalaksanakeunana nganggo cangkang-operator. Tapi mimitina eta sia nyebutkeun sababaraha kecap ngeunaan cangkang-operator sorangan.

Kumaha cangkang-operator jalan

Sapertos beban kerja sanés dina Kubernetes, operator cangkang jalan dina pod sorangan. Dina pod ieu dina diréktori /hooks file laksana disimpen. Ieu tiasa janten skrip dina Bash, Python, Ruby, jsb. Urang nyebut file laksana sapertos hook (pancing).

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Shell-operator ngalanggan acara Kubernetes tur ngajalankeun hook ieu dina respon kana eta acara nu urang peryogi.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Kumaha cangkang-operator nyaho mana hook ngajalankeun sarta iraha? Intina nyaéta unggal hook gaduh dua tahap. Salila ngamimitian, cangkang-operator ngajalankeun sagala hook kalawan argumen --config Ieu tahap konfigurasi. Sareng saatosna, kait diluncurkeun ku cara biasa - pikeun ngaréspon kana kajadian anu aranjeunna napel. Dina kasus dimungkinkeun, hook nu narima konteks mengikat (konteks mengikat) - data dina format JSON, nu urang bakal ngobrol ngeunaan leuwih jéntré di handap.

Nyieun operator di Bash

Ayeuna kami siap pikeun palaksanaan. Jang ngalampahkeun ieu, urang kudu nulis dua fungsi (ku jalan kitu, urang nyarankeun perpustakaan shell_lib, nu greatly simplifies nulis kait di Bash):

  • kahiji diperlukeun pikeun tahap konfigurasi - eta mintonkeun konteks mengikat;
  • kadua ngandung logika utama hook nu.

#!/bin/bash

source /shell_lib.sh

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

function __main__() {
  # THE LOGIC
}

hook::run "$@"

Lengkah saterusna nyaeta mutuskeun naon objék urang kudu. Dina kasus urang, urang kedah ngalacak:

  • rusiah sumber pikeun parobahan;
  • kabéh ngaranspasi dina kluster, ku kituna anjeun terang nu leuwih mibanda labél napel aranjeunna;
  • rusiah sasaran pikeun mastikeun yén maranéhanana kabéh sinkron jeung rusiah sumber.

Ngalanggan sumber rusiah

Konfigurasi mengikat keur eta cukup basajan. Kami nunjukkeun yén kami museurkeun Rusiah kalayan nami mysecret dina spasi ngaran default:

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti 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

Hasilna, hook bakal dipicu nalika rusiah sumber robah (src_secret) sareng nampi kontéks ngariung di handap ieu:

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Sakumaha anjeun tiasa tingali, éta ngandung nami sareng sadayana obyék.

Ngalacak ngaranspasi

Ayeuna anjeun kedah ngalanggan namespaces. Jang ngalampahkeun ieu, urang tangtukeun konfigurasi mengikat handap:

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

Sakumaha anjeun tiasa tingali, médan anyar parantos muncul dina konfigurasi kalayan nami jqFilter. Sakumaha ngaranna nunjukkeun, jqFilter nyaring sadaya inpormasi anu teu dipikabutuh sareng nyiptakeun objék JSON énggal kalayan widang anu dipikaresep ku urang. Hook sareng konfigurasi anu sami bakal nampi kontéks ngariung di handap ieu:

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Ieu ngandung hiji Asép Sunandar Sunarya filterResults pikeun tiap spasi ngaran dina klaster. Variabel Boolean hasLabel nunjukkeun naha labél digantelkeun kana ngaranspasi dibikeun. Pamilih keepFullObjectsInMemory: false nunjukkeun yén teu perlu nyimpen objék lengkep dina mémori.

Nyukcruk rusiah target

Urang ngalanggan ka sadaya Rahasia nu boga annotation dieusian managed-secret: "yes" (ieu tujuan urang 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

Dina hal ieu jqFilter nyaring kaluar kabeh informasi iwal ngaranspasi jeung parameter resourceVersion. Parameter anu terakhir disalurkeun kana anotasi nalika nyiptakeun rusiah: ngamungkinkeun anjeun pikeun ngabandingkeun versi rusiah sareng tetep diropéa.

A hook ngonpigurasi cara kieu bakal, nalika dieksekusi, narima tilu konteks mengikat ditétélakeun di luhur. Éta bisa dianggap salaku jenis snapshot (snapshot) klaster.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Dumasar kana sadaya inpormasi ieu, algoritma dasar tiasa dikembangkeun. Ieu iterates leuwih sagala namespaces jeung:

  • upami hasLabel urusan true pikeun ngaranspasi ayeuna:
    • ngabandingkeun rusiah global jeung hiji lokal:
      • lamun maranehna sarua, teu nanaon;
      • lamun aranjeunna béda - executes kubectl replace atawa create;
  • upami hasLabel urusan false pikeun ngaranspasi ayeuna:
    • mastikeun yén Rahasia henteu aya dina rohangan ngaran anu dipasihkeun:
      • lamun Rusiah lokal hadir, ngahapus eta ngagunakeun kubectl delete;
      • lamun Rahasia lokal teu kauninga, teu nanaon.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Palaksanaan algoritma dina Bash Anjeun tiasa ngundeur di urang repositories kalawan conto.

Éta kumaha urang bisa nyieun hiji kontroler Kubernetes basajan ngagunakeun 35 garis YAML config sarta ngeunaan jumlah sarua kode Bash! Tugas cangkang-operator nyaéta ngahubungkeun éta babarengan.

Nanging, nyalin rahasia sanés ngan ukur daérah aplikasi utilitas. Ieu sababaraha conto deui pikeun nunjukkeun naon anu anjeunna sanggup.

Conto 1: Nyieun parobahan ConfigMap

Hayu urang tingali hiji Deployment diwangun ku tilu pods. Pods nganggo ConfigMap pikeun nyimpen sababaraha konfigurasi. Nalika pods diluncurkeun, ConfigMap dina kaayaan anu tangtu (nyaéta v.1). Sasuai, sadaya pods nganggo versi ConfigMap khusus ieu.

Ayeuna hayu urang nganggap yén ConfigMap geus robah (v.2). Sanajan kitu, pods bakal ngagunakeun versi saméméhna tina ConfigMap (v.1):

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Kumaha carana abdi tiasa ngalih ka ConfigMap anyar (v.2)? Dina jawaban eta basajan: ngagunakeun citakan. Hayu urang tambahkeun annotation checksum kana bagian template Konfigurasi panyebaran:

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Hasilna, checksum ieu bakal kadaptar dina sakabéh pods, sarta eta bakal sarua jeung nu Deployment. Ayeuna anjeun ngan ukur kedah ngapdet annotation nalika ConfigMap robih. Jeung cangkang-operator asalna di gunana dina hal ieu. Sadaya anu anjeun kedah laksanakeun nyaéta program a hook nu bakal ngalanggan ConfigMap tur ngamutahirkeun checksum.

Lamun pamaké nyieun parobahan ConfigMap, cangkang-operator bakal perhatikeun aranjeunna sarta recalculate checksum nu. Saatos éta sihir Kubernetes bakal dimaénkeun: orkestra bakal maéhan pod, nyiptakeun anu énggal, ngantosan éta janten. Ready, sarta ngaléngkah ka nu salajengna. Hasilna, Deployment bakal nyingkronkeun sareng pindah ka versi anyar ConfigMap.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Conto 2: Gawe sareng Watesan Sumberdaya Adat

Sakumaha anjeun terang, Kubernetes ngamungkinkeun anjeun nyiptakeun jinis objék khusus. Contona, Anjeun bisa nyieun jenis MysqlDatabase. Anggap jinis ieu ngagaduhan dua parameter metadata: name и namespace.

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

Kami gaduh klaster Kubernetes sareng ruang ngaran anu béda-béda dimana urang tiasa nyiptakeun database MySQL. Dina hal ieu cangkang-operator bisa dipaké pikeun ngalacak sumberdaya MysqlDatabase, nyambungkeun aranjeunna ka server MySQL tur nyingkronkeun kaayaan nu dipikahoyong tur observasi tina klaster.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Conto 3: Pangimeutan Jaringan Kluster

Sakumaha anjeun terang, nganggo ping mangrupikeun cara pangbasajanna pikeun ngawas jaringan. Dina conto ieu kami bakal nunjukkeun kumaha nerapkeun ngawaskeun sapertos nganggo cangkang-operator.

Anu mimiti, anjeun kedah ngalanggan node. Operator cangkang peryogi nami sareng alamat IP unggal titik. Kalayan pitulung maranéhanana, anjeunna bakal ping titik ieu.

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

parameter executeHookOnEvent: [] nyegah hook ngajalankeun dina respon kana acara naon (nyaéta, dina respon kana ngarobah, nambahkeun, mupus titik). Sanajan kitu, anjeunna bakal ngajalankeun (sareng ngapdet daptar simpul) Dijadwalkeun - unggal menit, sakumaha prescribed ku lapangan schedule.

Ayeuna timbul patarosan, kumaha persisna urang terang ngeunaan masalah sapertos pakét leungitna? Hayu urang tingali kodeu:

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
}

Urang iterate ngaliwatan daptar titik, meunang ngaran maranéhanana sarta alamat IP, ping aranjeunna sarta ngirimkeun hasil ka Prometheus. Shell-operator tiasa ékspor metrics ka Prometheus, nyimpen kana file lokasina nurutkeun jalur dieusian dina variabel lingkungan $METRICS_PATH.

kawas kieu anjeun tiasa ngadamel operator pikeun ngawaskeun jaringan basajan dina klaster.

Mékanisme antrian

Artikel ieu bakal lengkep tanpa ngajelaskeun mékanisme penting séjén diwangun kana cangkang-operator. Bayangkeun yén éta ngalaksanakeun sababaraha jinis pancing pikeun ngaréspon kana acara dina kluster.

  • Naon anu lumangsung upami, dina waktos anu sami, aya kajadian dina kluster? hiji deui acara?
  • Bakal cangkang-operator ngajalankeun conto sejen tina hook nu?
  • Kumaha upami, sebutkeun, lima kajadian dina kluster sakaligus?
  • Naha cangkang-operator bakal ngolah aranjeunna paralel?
  • Kumaha upami sumber anu dikonsumsi sapertos mémori sareng CPU?

Untungna, cangkang-operator boga mékanisme antrian diwangun-di. Sadaya acara antrian sareng diolah sacara berurutan.

Hayu urang ngagambarkeun ieu ku conto. Anggap urang gaduh dua kait. Acara kahiji mana anu ka hook kahiji. Saatos ngolahna parantos réngsé, antrian maju. Tilu acara salajengna dialihkeun ka hook kadua - aranjeunna dikaluarkeun tina antrian jeung diasupkeun kana eta "dina bets". nyaeta hook narima Asép Sunandar Sunarya ti acara - atanapi, langkung tepatna, sakumpulan kontéks anu ngariung.

Ogé ieu acara bisa digabungkeun jadi hiji badag. Parameter tanggung jawab ieu group dina konfigurasi mengikat.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Anjeun tiasa nyieun sababaraha antrian / kait sarta sagala rupa kombinasi maranéhna. Salaku conto, hiji antrian tiasa dianggo sareng dua kait, atanapi sabalikna.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Sadaya anu anjeun kedah laksanakeun nyaéta ngonpigurasikeun lapangan sasuai queue dina konfigurasi mengikat. Lamun ngaran antrian teu dieusian, hook dijalankeun dina antrian standar (default). Mékanisme antrian ieu ngamungkinkeun anjeun pikeun ngabéréskeun sadayana masalah manajemén sumberdaya nalika damel sareng kait.

kacindekan

Kami ngajelaskeun naon cangkang-operator, nunjukkeun kumaha éta tiasa dianggo pikeun gancang sareng gampang nyiptakeun operator Kubernetes, sareng masihan sababaraha conto panggunaanana.

Inpormasi anu lengkep ngeunaan cangkang-operator, ogé tutorial gancang ngeunaan cara ngagunakeunana, sayogi dina saluyu. repositories on GitHub. Ulah ragu ngahubungan kami kalawan patarosan: anjeun tiasa ngabahas aranjeunna dina husus Grup telegram (dina Rusia) atanapi di forum ieu (dina Basa Inggris).

Sareng upami anjeun resep, kami teras-terasan ningali masalah anyar / PR / béntang dina GitHub, dimana, ku jalan kitu, anjeun tiasa mendakan anu sanés. proyék metot. Di antarana patut nyorot addon-operator, nu mangrupakeun lanceukna badag tina cangkang-operator. Utilitas ieu ngagunakeun grafik Helm pikeun masang tambihan, tiasa nganteurkeun apdet sareng ngawaskeun rupa-rupa parameter / nilai bagan, ngatur prosés pamasangan grafik, sareng ogé tiasa ngarobih aranjeunna pikeun ngaréspon kana kajadian dina kluster.

indit? Bash! Minuhan cangkang-operator (review sareng laporan pidéo ti KubeCon EU'2020)

Video sareng slide

Video tina pagelaran (~ 23 menit):


Presentasi laporan:

PS

Baca ogé dina blog urang:

sumber: www.habr.com

Tambahkeun komentar