Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実例から学ぶ Kubernetes Custom Controller の状態管理

Takuya TAKAHASHI
November 22, 2022
1.2k

実例から学ぶ Kubernetes Custom Controller の状態管理

CNDT2022 で発表した内容です

Takuya TAKAHASHI

November 22, 2022
Tweet

Transcript

  1. 2 アジェンダ - 自己紹介 - Kubernetes Custom Controller の難しさ -

    状態管理の種類と実例紹介 - まとめ 2
  2. 5 宣伝: GMOペパボでは CNDT 2022 で 5セッション登壇しています! 自己紹介 - 11/21

    (すべて終了) - Dynamic VM Scheduling in OpenStack by Kazuhiko Yamashita - k8s Operatorで運用負担減&ハイブリッドクラウドのコスト最適化をした話 by Chiaki Sugawara - 実例から学ぶ Kubernetes Custom Controller のステータス管理 by Takuya Takahashi - 11/22 Track F - [13:20-] ペパボのSREが生産性の向上を目指しCloud Nativeなチーム作り実践し た話 by Ryuichi Watanabe - [13:40-] しきい値監視からの卒業! Prometheus による機械学習を用いた異常検 知アラートの実装 by Takuya Takahashi 5
  3. 9 カスタムリソースとは? カスタムリソース使ってますか? - Kubernetes の自作リソースを作成できる機能 - その機能で作られたサードパーティーなリソースのこと - `kubectl

    list|get|delete` などで操作できるようになる - 身近なクラスタで `kubectl get crd` を実行してみるとどうなりますか? 9
  4. 27 Deployment の挙動から見る実装の難しさ カスタムリソースをきちんと実装できますか? - ローリングアップデート難しすぎる - Pod の更新有無の管理 -

    更新中の成否の管理 - イレギュラー時の処理の決定 - etc… 27 これらをまとめて、 リソースの状態管理 と呼ぶことにします
  5. 31 Deployment はどうやっているのか 状態管理の種類と実例紹介 - Deployment は ReplicaSet を子リソースとして持つ -

    Deployment が直接 Pod を操作しているわけではない 31 Deploy Deployment RS 同一設定の Pod を複数起動する Pod の個数を制御する
  6. 35 Deployment はどうやっているのか 状態管理の種類と実例紹介 - ローリングアップデートは ReplicaSet (rs) をうまく使って実現している -

    アップデート前(old) と後(new) の設定の rs を持っている 35 Deployment old replica: 3 new new replica: 0
  7. 37 Deployment はどうやっているのか 状態管理の種類と実例紹介 - new rs の replicas を

    1にする - rs が更新中の状態に遷移するので更新完了 (Ready) まで待つ 37 Deployment old replica: 3 new new replica: 1 Not Ready
  8. 38 Deployment はどうやっているのか 状態管理の種類と実例紹介 - old rs の replicas を

    2にする - old rs のステータスが Ready になるまで待機する 38 Deployment old replica: 2 new new replica: 1
  9. 44 Deployment はどうやっているのか 状態管理の種類と実例紹介 - 削除された Pod が所属する rs が復旧を行う

    - old, new 両方が Ready になるまで RollingUpdate を中断する 44 Deployment old replica: 1 new new replica: 2 Ready Not Ready
  10. 48 単一責務パターンのメリット 状態管理の種類と実例紹介 - 自作カスタムリソースに応用しやすい - ワークロードは Deployment を作成すれば状態管理に悩まない -

    複雑な状態管理は得意な他リソースを選定してやらせてしまえる - ロードバランシングが必要なら svc を作る 48
  11. 56 cert-manager 状態管理の種類と実例紹介 - Certificate は CertificateRequest を作成する - CertificateRequest

    が完了するまで待機し、完了したら Secret を作る 56 Certificate CertificateRequest Issuer ClusterIssuer
  12. 59 Status.Conditions パターン 状態管理の種類と実例紹介 - 「カレー作り」を Condition で表現してみる 59 Type:

    にんじんが切られている Status: True Type: いもが切られている Status: True Type: 肉に火が通っている Status: True Type: 鍋に水が入っている Status: False 59 Type: 具材が煮込まれている Status: False Type: カレーが完成している Status: False ex: カレーを作るコントローラ カレー作りの工程を 表現する状態
  13. 60 Status.Conditions パターン 状態管理の種類と実例紹介 - 各状態を表す Condition を見て次の行動を決定する 60 Type:

    にんじんが切られている Status: True Type: いもが切られている Status: True Type: 肉に火が通っている Status: True Type: 鍋に水が入っている Status: False 60 Type: 具材が煮込まれている Status: False Type: カレーが完成している Status: False Next Action: 鍋に具材と水を入れて火にかける
  14. 61 Status.Conditions パターン 状態管理の種類と実例紹介 - 状態が変更されたら 61 Type: にんじんが切られている Status:

    True Type: いもが切られている Status: True Type: 肉に火が通っている Status: True Type: 鍋に水が入っている Status: True 61 Type: 具材が煮込まれている Status: False Type: カレーが完成している Status: False Next Action: 鍋に具材と水を入れて火にかける 水を入れた Next Action: 鍋に具材と水を入れて火にかける
  15. 62 Status.Conditions パターン 状態管理の種類と実例紹介 - 次の行動も状態を見て再度決定される 62 Type: にんじんが切られている Status:

    True Type: いもが切られている Status: True Type: 肉に火が通っている Status: True Type: 鍋に水が入っている Status: True 62 Type: 具材が煮込まれている Status: False Type: カレーが完成している Status: False Next Action: 鍋に具材と水を入れて火にかける 水を入れた
  16. 63 Status.Conditions パターン 状態管理の種類と実例紹介 - Certificate リソースはふたつの Condition Type を持つ

    - Ready … 処理が完了しているかどうか - Issuing … 処理中かどうか 63 CertificateConditionReady CertificateConditionType = "Ready" CertificateConditionIssuing CertificateConditionType = "Issuing" https://github.dev/cert-manager/cert-manager/blob/e7ed5c491be93b3c93ea236d02a455aa2d6cd00a/pkg/apis/certmanager/v1/types_certificate.go#L498-L516
  17. 64 cert-manager 状態管理の種類と実例紹介 - Issuing が True = 処理中である場合、新しい CertificateReuest

    を作る 64 if !apiutil.CertificateHasCondition(crt, cmapi.CertificateCondition{ Type: cmapi.CertificateConditionIssuing, Status: cmmeta.ConditionTrue, }) { return nil } // 省略 return c.createNewCertificateRequest(ctx, crt, pk, nextRevision, nextPrivateKeySecret.Name) https://github.dev/cert-manager/cert-manager/blob/e7ed5c491be93b3c93ea236d02a455aa2d6cd00a/pkg/controller/certificates/requestmanager/requestmanager_controller.go#L152-L229
  18. 66 cert-manager 状態管理の種類と実例紹介 - 証明書の再作成をする必要が出たら、Issuing = True にする - 状態収束に必要な処理がすべて動作する

    66 log.V(logf.InfoLevel).Info("Certificate must be re-issued", "reason", reason, "message", message) crt = crt.DeepCopy() apiutil.SetCertificateCondition(crt, crt.Generation, cmapi.CertificateConditionIssuing, cmmeta.ConditionTrue, reason, message) if err := c.updateOrApplyStatus(ctx, crt); err != nil { return err } c.recorder.Event(crt, corev1.EventTypeNormal, "Issuing", message) return nil } https://github.dev/cert-manager/cert-manager/blob/e7ed5c491be93b3c93ea236d02a455aa2d6cd00a/pkg/controller/certificates/trigger/trigger_controller.go#L200-L201
  19. 67 cert-manager 状態管理の種類と実例紹介 - Certificate は CertificateRequest (CR)を作成する - CR.Status.Conditions

    が Ready = True になっていたら Secret を作る 67 Certificate CertificateRequest Issuer ClusterIssuer
  20. 70 cert-manager 状態管理の種類と実例紹介 - 各 CRD の責務はこんな感じ - 子リソースの完了は子リソースの Conditions

    を確認する 70 Certificate CertificateRequest Order Challenge Issuer ClusterIssuer CR を作成する CR の完了を監視する Secret を作る renew を管理する Order を作成する Order の完了を監視する Challenge を作成する Challenge の完了を 監視する Challenge が失敗したら再 作成する ACME Challenge を 実行する
  21. 71 cert-manager まとめ 状態管理の種類と実例紹介 71 - Certificate を頂点とする階層構造を持つ - 状態管理は

    Conditions パターンを用いる - 親は子リソースの状態を Status.Conditions から取得する - コントローラは Condition の値を見て後続の処理を決定する
  22. 73 rook 状態管理の種類と実例紹介 73 - Cloud Native なストレージクラスタオペレータ - k8s

    内で Ceph クラスタを管理する rook/ceph がメイン - 国内ではサイボウズさんが積極的に開発している
  23. 75 rook 状態管理の種類と実例紹介 75 - CephCluster も Condition を持つがほぼ参照されない! CephCluster

    Type: Progressing Status: True Type: Ready Status: False Progressing, Ready くらい
  24. 76 rook 状態管理の種類と実例紹介 76 - Message でどこまで処理が進んだかユーザーに通知する役割を持つ - Progressing Condition

    の Message を都度更新している CephCluster Type: Progressing Status: True Message: "Detecting Ceph version" Type: Ready Status: False
  25. 79 rook 状態管理の種類と実例紹介 79 - Operator の Reconcile 関数内ですべての手順を実行する -

    各手順が高度に冪等性が担保されており、何度実行されてもいい 1. initializeCluster() a. configureMonitoring() // クラスタの監視を起動する b. detectAndValidateCephVersion() // Ceph Cluster のバージョンを確認する c. reconcileCephDaemons() // Ceph のすべてのプロセスを理想状態にする i. mons.Start() // mon を開始する ii. mgrs.Start() // mgr を開始する iii. osds.Start() // osd を開始する
  26. 80 なぜ rook では状態を管理しない?(推測) 状態管理の種類と実例紹介 80 - CephCluster は1つの k8s

    クラスタに1組を想定している - 1リソースに使える処理時間が長い - CephCluster はデータの耐久性を何よりも重視している - 処理速度よりも安全な処理を選択したのでは? - ゆっくりと状態を確認しながら処理するほうがいい
  27. 81 なぜ rook では状態を管理しない? 状態管理の種類と実例紹介 81 - 状態管理しないためテストがかっこいい r :=

    &ReconcileConfig{ client: cl, context: c, config: controller.OperatorConfig{ OperatorNamespace: namespace, Image: "rook", ServiceAccount: "foo", }, } res, err := r.Reconcile(ctx, req) assert. NoError(t, err) assert. False(t, res.Requeue) }) https://github.dev/rook/rook/blob/3744a9d79576eab748aefb53f5465cd4cad0ab24/pkg/operator/ceph/controller_test.go#L73-L87
  28. 88 oci-image-operator 状態管理の種類と実例紹介 88 - 拙作プロダクト - git の更新をもとにイメージビルドをするワークフローを実行する -

    動作例: - branch1 への Push を検知する - branch1 の HEAD Revision をタグに持つイメージの存在チェック - 存在しなかったらイメージを作成、プッシュする
  29. 89 oci-image-operator 状態管理の種類と実例紹介 89 - Detected, Checked, Uploaded の3つの Condition

    Type がある - 検査対象のブランチやタグごとに Condition を持つ Image Type: Detected Target: branch1 Status: False Type: Checked Target: rev1 Status: False Type: Uploaded Target: rev1 Status: False ブランチの変更を 検知したか? 対象のイメージが レジストリに存在するか? 対象のイメージの プッシュに成功したか? git
  30. 92 oci-image-operator 状態管理の種類と実例紹介 92 - 変更を検知したら Detected=True, Checked=False を設定する Image

    Deployment git Type: Detected Target: branch1 Status: True Type: Checked Target: rev1 Status: False
  31. 94 oci-image-operator 状態管理の種類と実例紹介 94 - 結果を見て Uploaded の Condition をセットする

    Image Deployment git Type: Detected Target: branch1 Status: True Job registry Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: False
  32. 95 oci-image-operator 状態管理の種類と実例紹介 95 - Uploaded=False だったらビルドのための Job を動かす Image

    Deployment git Type: Detected Target: branch1 Status: True Job registry Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: False Job
  33. 96 oci-image-operator 状態管理の種類と実例紹介 96 - Check の Job がイメージの存在を確認したら Uploaded=True

    にする Image Deployment git Type: Detected Target: branch1 Status: True Job registry Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: True Job
  34. 97 oci-image-operator 状態管理の種類と実例紹介 97 - git のブランチの変更を検知すると Deployment が Condition

    を作成する - 以下繰り返し Image Deployment git Type: Detected Target: branch1 Status: True registry Type: Checked Target: rev2 Status: False Type: Uploaded Target: rev2 Status: False Type: Checked Target: rev2 Status: True Type: Uploaded Target: rev2 Status: True
  35. 99 oci-image-operator の状態管理は成功したのか? 状態管理の種類と実例紹介 99 - 改善の余地がある Image Deployment git

    Type: Detected Target: branch1 Status: True Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: True
  36. 100 oci-image-operator の改善ポイント 状態管理の種類と実例紹介 100 - Detected の状態は必要ない Image Deployment

    git Type: Detected Target: branch1 Status: True Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: True True から 変更なし
  37. 101 oci-image-operator の改善ポイント 状態管理の種類と実例紹介 101 - Checked, Uploaded の役割が重複している -

    存在しない状態があり無駄 Image Deployment git Type: Detected Target: branch1 Status: True Type: Checked Target: rev1 Status: True Type: Uploaded Target: rev1 Status: True Checked = False Uploaded = True …?
  38. 103 oci-image-operator の改善ポイント 状態管理の種類と実例紹介 103 - 変更を検知したら Checked=False の Condition

    を作成する Image Deployment git Type: Checked Target: rev1 Status: True Type: Checked Target: rev2 Status: False
  39. 104 oci-image-operator の改善ポイント 状態管理の種類と実例紹介 104 - イメージのワークフローは子リソースに切り出したほうがいい Image Ensure Ensure

    Git リポジトリを監視する 変更があったら Ensure を作 成する Check を作る Check の結果を見て Build を作 る Check Build