行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

今幎、欧州の䞻芁な Kubernetes カンファレンスである KubeCon + CloudNativeCon Europe 2020 はバヌチャルで開催されたした。 しかし、このような圢匏の倉曎によっお、長幎蚈画しおいたレポヌト「Go?」の提䟛が劚げられるこずはありたせんでした。 バッシュ オヌプン゜ヌス プロゞェクトに特化した「シェル オペレヌタヌの玹介」 シェルオペレヌタヌ.

この蚘事は講挔に觊発されお、Kubernetes のオペレヌタヌ䜜成プロセスを簡玠化するアプロヌチを玹介し、シェル オペレヌタヌを䜿甚しお最小限の劎力で独自のオペレヌタヌを䜜成する方法を瀺したす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

導入 レポヌトのビデオ (英語で玄 23 分、蚘事よりも明らかに有益です) ずその䞻芁な抜粋をテキスト圢匏で瀺したす。 行く

Flant では、あらゆるものを垞に最適化し、自動化しおいたす。 今日は別の゚キサむティングなコンセプトに぀いおお話したす。 䌚う クラりドネむティブのシェルスクリプト!

ただし、これすべおが発生するコンテキスト、぀たり Kubernetes から始めたしょう。

Kubernetes API ずコントロヌラヌ

Kubernetes の API は、オブゞェクトの皮類ごずにディレクトリを備えた䞀皮のファむル サヌバヌずしお衚すこずができたす。 このサヌバヌ䞊のオブゞェクト (リ゜ヌス) は YAML ファむルで衚されたす。 さらに、サヌバヌには基本的な API があり、次の XNUMX ぀のこずを実行できたす。

  • 受け取る リ゜ヌスの皮類ず名前による。
  • 倉化する リ゜ヌス (この堎合、サヌバヌは「正しい」オブゞェクトのみを保管したす。間違っお圢成されたオブゞェクトや他のディレクトリヌを察象ずしたオブゞェクトはすべお砎棄されたす)。
  • フォロヌする リ゜ヌスの堎合 (この堎合、ナヌザヌは珟圚の/曎新されたバヌゞョンをすぐに受け取りたす)。

したがっお、Kubernetes は XNUMX ぀の基本メ゜ッドを備えた (YAML マニフェスト甚の) 䞀皮のファむル サヌバヌずしお機胜したす (はい、実際には他にもメ゜ッドがありたすが、ここでは省略したす)。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

問題は、サヌバヌは情報しか保存できないこずです。 それを機胜させるために必芁なのは コントロヌラ - Kubernetes の䞖界で XNUMX 番目に重芁か぀基本的な抂念。

コントロヌラヌには䞻に 8 ぀のタむプがありたす。 XNUMX ぀目は、Kubernetes から情報を取埗し、ネストされたロゞックに埓っお凊理し、KXNUMXs に返したす。 XNUMX 番目のタむプは Kubernetes から情報を取埗したすが、最初のタむプずは異なり、䞀郚の倖郚リ゜ヌスの状態を倉曎したす。

Kubernetes でデプロむメントを䜜成するプロセスを詳しく芋おみたしょう。

  • デプロむメントコントロヌラヌ (以䞋に含たれたす) kube-controller-manager) デプロむメントに関する情報を受け取り、ReplicaSet を䜜成したす。
  • ReplicaSet はこの情報に基づいお XNUMX ぀のレプリカ (XNUMX ぀のポッド) を䜜成したすが、これらのポッドはただスケゞュヌルされおいたせん。
  • スケゞュヌラはポッドをスケゞュヌルし、ノヌド情報を YAML に远加したす。
  • Kubelet は倖郚リ゜ヌス (Docker など) に倉曎を加えたす。

次に、このシヌケンス党䜓が逆の順序で繰り返されたす。kubelet はコンテナヌをチェックし、ポッドのステヌタスを蚈算しお送り返したす。 ReplicaSet コントロヌラヌはステヌタスを受信し、レプリカ セットの状態を曎新したす。 同じこずがデプロむメント コントロヌラヌでも発生し、ナヌザヌは最終的に曎新された (珟圚の) ステヌタスを取埗したす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

シェルオペレヌタヌ

Kubernetes はさたざたなコントロヌラヌの共同䜜業に基づいおいるこずがわかりたす (Kubernetes オペレヌタヌもコントロヌラヌです)。 最小限の劎力で独自のオペレヌタヌを䜜成するにはどうすればよいかずいう疑問が生じたす。 ここで私たちが開発したものが圹に立ちたす シェルオペレヌタヌ。 これにより、システム管理者は䜿い慣れた方法を䜿甚しお独自のステヌトメントを䜜成できたす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

簡単な䟋: シヌクレットのコピヌ

簡単な䟋を芋おみたしょう。

Kubernetes クラスタヌがあるずしたす。 名前空間がありたす default 秘密を持っお mysecret。 さらに、クラスタヌ内には他の名前空間もありたす。 それらの䞭には、特定のラベルが付けられおいるものもありたす。 私たちの目暙は、Secret をラベル付きの名前空間にコピヌするこずです。

新しい名前空間がクラスタヌ内に出珟し、それらの䞀郚にこのラベルが付いおいる可胜性があるため、タスクは耇雑になりたす。 䞀方、ラベルを削陀する堎合は、Secret も削陀する必芁がありたす。 これに加えお、Secret 自䜓も倉曎される可胜性がありたす。この堎合、新しい Secret をラベル付きのすべおの名前空間にコピヌする必芁がありたす。 Secret が名前空間で誀っお削陀された堎合、圓瀟のオペレヌタヌは盎ちにそれを埩元する必芁がありたす。

タスクが定匏化されたので、シェル オペレヌタヌを䜿甚しお実装を開始したす。 しかし、その前に、シェル オペレヌタヌ自䜓に぀いお少し述べおおく䟡倀がありたす。

シェルオペレヌタヌの仕組み

Kubernetes の他のワヌクロヌドず同様に、shell-operator は独自のポッドで実行されたす。 このポッド内のディレクトリ内 /hooks 実行可胜ファむルが保存されたす。 これらは、Bash、Python、Ruby などのスクリプトにするこずができたす。 このような実行可胜ファむルをフックず呌びたす (フック).

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

シェルオペレヌタヌは Kubernetes むベントをサブスクラむブし、必芁なむベントに応答しおこれらのフックを実行したす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

シェルオペレヌタヌはどのフックをい぀実行するかをどのようにしお知るのでしょうか? ポむントは、すべおのフックが XNUMX 段階あるこずです。 起動䞭、シェルオペレヌタヌは匕数を指定しおすべおのフックを実行したす。 --config これは構成段階です。 その埌、フックは通垞の方法で、フックが接続されおいるむベントに応じお起動されたす。 埌者の堎合、フックはバむンディング コンテキスト (バむンディングコンテキスト) - JSON 圢匏のデヌタ。これに぀いおは以䞋で詳しく説明したす。

Bash で挔算子を䜜成する

これで実装の準備が敎いたした。 これを行うには、XNUMX ぀の関数を蚘述する必芁がありたす (ちなみに、 図曞通 シェルラむブラリこれにより、Bash でのフックの䜜成が倧幅に簡玠化されたす)。

  • XNUMX ぀目は構成段階で必芁です。これはバむンディング コンテキストを衚瀺したす。
  • XNUMX 番目にはフックのメむン ロゞックが含たれおいたす。

#!/bin/bash

source /shell_lib.sh

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

function __main__() {
  # THE LOGIC
}

hook::run "$@"

次のステップは、必芁なオブゞェクトを決定するこずです。 私たちの堎合、以䞋を远跡する必芁がありたす。

  • 倉曎の゜ヌスシヌクレット。
  • クラスタヌ内のすべおの名前空間。どの名前空間にラベルが付いおいるかがわかりたす。
  • タヌゲット シヌクレットを䜿甚しお、それらがすべお゜ヌス シヌクレットず同期しおいるこずを確認したす。

秘密の゜ヌスを賌読する

そのバむンド蚭定は非垞に簡単です。 Secret に興味があるこずを名前で瀺したす mysecret 名前空間内 default:

行く バッシュ シェル オペレヌタヌの玹介 (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

その結果、゜ヌスシヌクレットが倉曎されるずフックがトリガヌされたす(src_secret) し、次のバむンディング コンテキストを受け取りたす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

ご芧のずおり、名前ずオブゞェクト党䜓が含たれおいたす。

名前空間を远跡する

次に、名前空間をサブスクラむブする必芁がありたす。 これを行うには、次のバむンディング構成を指定したす。

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

ご芧のずおり、構成に次の名前の新しいフィヌルドが衚瀺されおいたす。 jqフィルタヌ。 その名の通り、 jqFilter 䞍芁な情報をすべお陀倖し、関心のあるフィヌルドを含む新しい JSON オブゞェクトを䜜成したす。 同様の構成のフックは、次のバむンディング コンテキストを受け取りたす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

配列が含たれおいたす filterResults クラスタヌ内の名前空間ごずに。 ブヌル倉数 hasLabel ラベルが指定された名前空間にアタッチされおいるかどうかを瀺したす。 セレクタ keepFullObjectsInMemory: false 完党なオブゞェクトをメモリ内に保持する必芁がないこずを瀺したす。

タヌゲットシヌクレットの远跡

アノテヌションが指定されたすべおの Secret をサブスクラむブしたす managed-secret: "yes" (これらが私たちの目暙です 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

この堎合 jqFilter 名前空間ずパラメヌタを陀くすべおの情報をフィルタリングしたす。 resourceVersion。 最埌のパラメヌタは、シヌクレットの䜜成時にアノテヌションに枡されたした。これにより、シヌクレットのバヌゞョンを比范し、最新の状態に保぀こずができたす。

このように構成されたフックは、実行されるず、䞊で説明した XNUMX ぀のバむンディング コンテキストを受け取りたす。 これらは䞀皮のスナップショットず考えるこずができたす (スナップショット 集たる。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

これらすべおの情報に基づいお、基本的なアルゎリズムを開発できたす。 すべおの名前空間を反埩凊理し、次のこずを行いたす。

  • 堎合 hasLabel 事項 true 珟圚の名前空間の堎合:
    • グロヌバル シヌクレットずロヌカル シヌクレットを比范したす。
      • それらが同じである堎合、䜕も行われたせん。
      • 異なる堎合 - 実行したす kubectl replace たたは create;
  • 堎合 hasLabel 事項 false 珟圚の名前空間の堎合:
    • Secret が指定された名前空間に存圚しないこずを確認したす。
      • ロヌカル シヌクレットが存圚する堎合は、次を䜿甚しお削陀したす。 kubectl delete;
      • ロヌカル シヌクレットが怜出されない堎合は、䜕も行われたせん。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

Bash でのアルゎリズムの実装 匊瀟でダりンロヌドできたす 䟋のあるリポゞトリ.

このようにしお、35 行の YAML 構成ずほが同量の Bash コヌドを䜿甚しお、シンプルな Kubernetes コントロヌラヌを䜜成するこずができたした。 シェルオペレヌタヌの仕事は、それらをリンクするこずです。

ただし、このナヌティリティの適甚範囲はシヌクレットのコピヌだけではありたせん。 圌の胜力を瀺す䟋をさらにいく぀か挙げたす。

䟋 1: ConfigMap に倉曎を加える

1 ぀のポッドで構成されるデプロむメントを芋おみたしょう。 ポッドは ConfigMap を䜿甚しお䞀郚の構成を保存したす。 ポッドが起動されたずき、ConfigMap は特定の状態 (v.XNUMX ず呌びたす) にありたした。 したがっお、すべおのポッドはこの特定のバヌゞョンの ConfigMap を䜿甚したす。

ここで、ConfigMap が倉曎されたず仮定したす (v.2)。 ただし、ポッドは以前のバヌゞョンの ConfigMap (v.1) を䜿甚したす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

新しい ConfigMap (v.2) に切り替えるにはどうすればよいですか? 答えは簡単です。テンプレヌトを䜿甚するのです。 セクションにチェックサムの泚釈を远加したしょう template 展開構成:

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

その結果、このチェックサムはすべおの Pod に登録され、Deployment のチェックサムず同じになりたす。 これで、ConfigMap が倉曎されたずきに泚釈を曎新するだけで枈みたす。 この堎合、シェル挔算子が圹に立ちたす。 必芁なのはプログラムするこずだけです ConfigMap をサブスクラむブし、チェックサムを曎新するフック.

ナヌザヌが ConfigMap に倉曎を加えるず、シェルオペレヌタヌがそれに気づき、チェックサムを再蚈算したす。 その埌、Kubernetes の魔法が機胜したす。オヌケストレヌタヌはポッドを匷制終了し、新しいポッドを䜜成し、ポッドがポッドになるのを埅ちたす。 Ready、次ぞ進みたす。 その結果、Deployment は同期され、ConfigMap の新しいバヌゞョンに切り替わりたす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

䟋 2: カスタム リ゜ヌス定矩の操䜜

ご存知のずおり、Kubernetes ではカスタム タむプのオブゞェクトを䜜成できたす。 たずえば、皮類を䜜成できたす MysqlDatabase。 この型に XNUMX ぀のメタデヌタ パラメヌタヌがあるずしたす。 name О namespace.

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

MySQL デヌタベヌスを䜜成できる、さたざたな名前空間を持぀ Kubernetes クラスタヌがありたす。 この堎合、shell-operator を䜿甚しおリ゜ヌスを远跡できたす。 MysqlDatabase、それらを MySQL サヌバヌに接続し、クラスタヌの望たしい状態ず芳察された状態を同期したす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

䟋 3: クラスタヌネットワヌクの監芖

ご存知のずおり、ping の䜿甚はネットワヌクを監芖する最も簡単な方法です。 この䟋では、shell-operator を䜿甚しおそのような監芖を実装する方法を瀺したす。

たず最初に、ノヌドをサブスクラむブする必芁がありたす。 シェル オペレヌタヌには、各ノヌドの名前ず IP アドレスが必芁です。 圌らの助けを借りお、圌はこれらのノヌドに ping を送信したす。

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

パラメヌタヌ executeHookOnEvent: [] フックがむベントに応答しお (぀たり、ノヌドの倉曎、远加、削陀に応答しお) 実行されないようにしたす。 しかし、圌は、 走りたす (そしおノヌドのリストを曎新したす) 予定 - フィヌルドの芏定に埓っお毎分 schedule.

ここで疑問が生じたす。パケット損倱などの問題に぀いお、どのように正確に知るこずができるのでしょうか? コヌドを芋おみたしょう:

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
}

ノヌドのリストを反埩凊理し、ノヌドの名前ず IP アドレスを取埗し、ping を実行しお、結果を Prometheus に送信したす。 シェルオペレヌタヌはメトリクスを Prometheus に゚クスポヌトできたす、環境倉数で指定されたパスに埓っお配眮されたファむルに保存したす。 $METRICS_PATH.

このような クラスタヌ内の単玔なネットワヌク監芖甚のオペレヌタヌを䜜成できたす。

キュヌむングメカニズム

シェル オペレヌタヌに組み蟌たれおいる別の重芁なメカニズムに぀いお説明しなければ、この蚘事は䞍完党になりたす。 クラスタヌ内のむベントに応答しお、ある皮のフックが実行されるず想像しおください。

  • 同時にクラスタヌ内で䜕かが発生した堎合はどうなりたすか? もう䞀぀ むベント
  • シェルオペレヌタヌはフックの別のむンスタンスを実行したすか?
  • たずえば、クラスタヌ内で䞀床に XNUMX ぀のむベントが発生した堎合はどうなるでしょうか?
  • シェルオペレヌタヌはそれらを䞊行しお凊理したすか?
  • メモリやCPUなどの消費リ゜ヌスはどうなるでしょうか?

幞いなこずに、shell-operator にはキュヌむング メカニズムが組み蟌たれおいたす。 すべおのむベントはキュヌに入れられ、順番に凊理されたす。

これを䟋を挙げお説明したしょう。 フックが XNUMX ぀あるずしたす。 最初のむベントは最初のフックに進みたす。 凊理が完了するず、キュヌは前に進みたす。 次の XNUMX ぀のむベントは XNUMX 番目のフックにリダむレクトされ、キュヌから削陀され、「バンドル」ずしおキュヌに入りたす。 あれは フックはむベントの配列を受け取りたす — より正確には、バむンディング コンテキストの配列です。

これらも むベントを XNUMX ぀の倧きなむベントにたずめるこずができる。 パラメヌタがこれを担圓したす group バむンディング構成内。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

任意の数のキュヌ/フックずそれらのさたざたな組み合わせを䜜成できたす。 たずえば、XNUMX ぀のキュヌが XNUMX ぀のフックで機胜するこずも、その逆も同様です。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

必芁なのは、それに応じおフィヌルドを蚭定するこずだけです queue バむンディング構成内。 キュヌ名が指定されおいない堎合、フックはデフォルトのキュヌで実行されたす (default。 このキュヌむング メカニズムにより、フックを䜿甚する際のリ゜ヌス管理の問題をすべお完党に解決できたす。

たずめ

シェル オペレヌタヌずは䜕かを説明し、それを䜿甚しお Kubernetes オペレヌタヌを迅速か぀簡単に䜜成する方法を瀺し、その䜿甚䟋をいく぀か瀺したした。

シェル オペレヌタヌの詳现情報ずその䜿甚方法に関する簡単なチュヌトリアルは、察応するドキュメントで参照できたす。 GitHub 䞊のリポゞトリ。 ご質問がございたしたら、お気軜にお問い合わせください。特別なセッションでご盞談いただけたす。 電報グルヌプ ロシア語でたたは このフォヌラム 英語

気に入っおいただけたしたら、GitHub で新しい号/PR/スタヌをい぀でも喜んで拝芋させおいただきたす。ずころで、他の号も芋぀けるこずができたす。 興味深いプロゞェクト。 その䞭でも泚目すべきは アドオンオペレヌタヌ、シェルオペレヌタヌの兄です。。 このナヌティリティは、Helm チャヌトを䜿甚しおアドオンをむンストヌルし、曎新を配信しおさたざたなチャヌトのパラメヌタヌ/倀を監芖し、チャヌトのむンストヌル プロセスを制埡し、クラスタヌ内のむベントに応じおチャヌトを倉曎するこずもできたす。

行く バッシュ シェル オペレヌタヌの玹介 (KubeCon EU'2020 のレビュヌずビデオ レポヌト)

ビデオずスラむド

パフォヌマンスのビデオ (箄 23 分):


報告曞のプレれンテヌション:

PS

私たちのブログもお読みください:

出所 habr.com

コメントを远加したす