Slide 1

Slide 1 text

kube-controller-manager⼊⾨ SRETT # 2 7 ( 2 0 2 3 / 0 9 / 1 2 ) @bells 1 7

Slide 2

Slide 2 text

▶ @bells 1 7 ▶ Software Engineer@ 3 -shake inc. ▶ kubernetes & kubernetes-csi member ▶ Kubernetes Internal Organizer ▶ #kubenews ▶ X(Twitter): @bells 1 7 _ ▶ GitHub: @bells 1 7

Slide 3

Slide 3 text

Kubernetesのコンポーネントについて

Slide 4

Slide 4 text

https://github.com/kubernetes/website/blob/fb 6 3 6 4 da 0 afd 1 9 e 8 a 9 5 1 5 aaae 2 de 9 bc 7 4 a 0 a 6 abd/static/images/docs/components-of-kubernetes.png

Slide 5

Slide 5 text

https://github.com/kubernetes/website/blob/fb 6 3 6 4 da 0 afd 1 9 e 8 a 9 5 1 5 aaae 2 de 9 bc 7 4 a 0 a 6 abd/static/images/docs/components-of-kubernetes.png

Slide 6

Slide 6 text

kube-controller-managerの前に

Slide 7

Slide 7 text

Kubernetesの基本機能 ▶ サービスディスカバリとロードバランシング ▶ ストレージオーケストレーション ▶ ⾃動化されたロールアウトとロールバック ▶ ⾃動ビンパッキング ▶ ⾃⼰修復 ▶ 秘密情報と設定の管理 ▶ バッチ実⾏ ▶ ⽔平スケーリング ▶ IPv 4 /IPv 6 デュアルスタック ポッド ▶ 拡張性を考慮した設計 https://kubernetes.io/docs/concepts/overview/ より

Slide 8

Slide 8 text

Kubernetesの基本機能 ▶ サービスディスカバリとロードバランシング ▶ ストレージオーケストレーション ▶ ⾃動化されたロールアウトとロールバック ▶ ⾃動ビンパッキング ▶ ⾃⼰修復 ▶ 秘密情報と設定の管理 ▶ バッチ実⾏ ▶ ⽔平スケーリング ▶ IPv 4 /IPv 6 デュアルスタック ポッド ▶ 拡張性を考慮した設計 https://kubernetes.io/docs/concepts/overview/ より これらの実現を主にController 
 による調整ループで実現している

Slide 9

Slide 9 text

Controllerとは?

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

https://github.com/kubernetes/sample-controller/blob/master/docs/images/client-go-controller-interaction.jpeg

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

https://github.com/kubernetes/website/blob/fb 6 3 6 4 da 0 afd 1 9 e 8 a 9 5 1 5 aaae 2 de 9 bc 7 4 a 0 a 6 abd/static/images/docs/components-of-kubernetes.png kube-api-server以外のConponentは Controllerを中⼼として機能を実現している

Slide 14

Slide 14 text

Controllerの実装例

Slide 15

Slide 15 text

clusterrole-aggregation-controller ▶ ClusterRoleというリソースの1機能を実現するControllerの例 ▶ ClusterRoleは対象のユーザーやServiceAccountに対してClusterレベルでのRBAC権限を 
 設定できるリソース ▶ ClusterRoleにはAggregationRule.ClusterRoleSelectorsの設定で、他のClusterRoleの RBAC権限設定を⾃動的に取り込むことのできる機能がある ▶ AggregationRule.ClusterRoleSelectorsには取り込みたいRBAC権限を設定したClusterRole のラベルを設定する

Slide 16

Slide 16 text

設定例は https://kubernetes.io/docs/reference/access-authn-authz/rbac/ より AggregationRule.ClusterRoleSelectorsの設定例

Slide 17

Slide 17 text

Controllerの起動処理 ▶ Controllerを起動する必要があるかのチェック後 ▶ go clusterroleaggregation.NewClusterRoleAggregation().Run() 
 でゴルーチンを使⽤してControllerの⽣成 ~ 実⾏を⾮同期で⾏っている

Slide 18

Slide 18 text

Controller⽣成: イベントハンドラーを設定してる

Slide 19

Slide 19 text

enqueue: 
 毎回AggregationRuleを設定してる全てのClusterRoleをc.queueに追加してる

Slide 20

Slide 20 text

RunによるControllerの起動処理: 
 キャッシュの同期を待機後c.runWorkerを毎秒実⾏する設定を⾏っている

Slide 21

Slide 21 text

runWorker ~ processNextWorkItem: 
 queueが空になるまでデータを取り出してc.syncHandlerを実⾏している

Slide 22

Slide 22 text

syncHandler(syncClusterRole) # 1 : 
 keyを元にClusterRoleのデータをキャッシュ(Indexer)から取得

Slide 23

Slide 23 text

syncHandler(syncClusterRole) # 2 : 
 AggregationRule.ClusterRoleSelectorsにマッチするClusterRoleのRuleを取得

Slide 24

Slide 24 text

syncHandler(syncClusterRole) # 3 : 
 ⽣成したruleに差分があるかチェックして、あれば保存

Slide 25

Slide 25 text

https://github.com/kubernetes/sample-controller/blob/master/docs/images/client-go-controller-interaction.jpeg このControllerを通して図にある全てを⼀通り体験できた

Slide 26

Slide 26 text

kube-controller-manager と cloud-controller-manager は何が違うの?

Slide 27

Slide 27 text

https://github.com/kubernetes/website/blob/fb 6 3 6 4 da 0 afd 1 9 e 8 a 9 5 1 5 aaae 2 de 9 bc 7 4 a 0 a 6 abd/static/images/docs/components-of-kubernetes.png

Slide 28

Slide 28 text

Cloud Controller Managerは Cloud(実⾏基盤)との連携が必要なControllerをまとめて実⾏~管理する

Slide 29

Slide 29 text

Cloud Provider ▶ Cloud Controller Managerʹ૊ΈࠐΜͰ࣮ߦ͞ΕΔ ▶ GoͰఆٛ͞ΕͨΠϯλʔϑΣΠεͷϝιουΛ࣮૷ͯ͠૊ΈࠐΉ͜ͱ ͰɺಠࣗͷCloud Provider࣮૷ΛCloud Controller Manager͔Βར༻͢Δ ͜ͱ͕Ͱ͖Δ ▶ GoͷΠϯλʔϑΣΠεͰ͋Δcloudprovider.Intreface͸ https:// github.com/kubernetes/kubernetes/blob/v1.28.2/staging/src/k8s.io/cloud- provider/cloud.go#L42-L69 ʹ͋Δ

Slide 30

Slide 30 text

Cloud Provider Interface

Slide 31

Slide 31 text

kube-controller-manager

Slide 32

Slide 32 text

kube-controller-manager ▶ (ओʹ)cloud-controller-manager͕࣮ߦ͢ΔҎ֎ͷ֤छControllerΛ
 ·ͱΊ࣮ͯߦ~؅ཧ͢Δ΍ͭ ▶ ࣮ࡍʹ͸ͦͷଞͷComponentͰ΋͍ͭ͘΋ControllerΛ࣋ͬͯ͸͍Δ ▶ ઃఆʹΑͬͯىಈ͢ΔController਺͸લޙ͢Δ͕ɺ
 େମ30-40छྨͷControllerΛ࣮ߦ ▶ ؀ڥʹΑͬͯ͸cloud-controller-managerͷControllerΛ࣮ߦΛߦ͏

Slide 33

Slide 33 text

kube-controller-manager Overview

Slide 34

Slide 34 text

ということで起動するControllerをざっくり紹介していく

Slide 35

Slide 35 text

の前に注意点 ▶ ぶっちゃけ全部のControllerをちゃんと精査して読んでません + 全部のControllerに関わるリソースの全フィールドと仕様を把握するには 
 時間がなさすぎた… ▶ また、関連するComponentなども合わせて把握しないと機能に関する実装の全体像がわ からないことも多いのですが、今回はあくまでkube-controller-managerの実装のみの話し となります ▶ Cloud Controller Managerで起動されるっぽいやつも除外してます ▶ なのであくまでざっくり解説です ▶ ※ Kubernetes v 1 . 2 8 . 2 の実装をベースにしてます

Slide 36

Slide 36 text

Podؔ࿈Controller ▶ replicaset-controller ▶ replicationcontroller-controller ▶ deployment-controller ▶ daemonset-controller ▶ statefulset-controller ▶ job-controller ▶ cronjob-controller ▶ horizontal-pod-autoscaler-controller ▶ disruption-controller ▶ pod-garbage-collector-controller ▶ ttl-after- fi nished-controller

Slide 37

Slide 37 text

Pod関連Controller Overview

Slide 38

Slide 38 text

ϘϦϡʔϜؔ࿈Controller ▶ persistentvolume-binder-controller ▶ persistentvolume-attach-detach-controller ▶ persistentvolume-expander-controller ▶ persistentvolumeclaim-protection-controller ▶ persistentvolume-protection-controller ▶ ephemeral-volume-controller

Slide 39

Slide 39 text

ボリューム関連Controller Overview

Slide 40

Slide 40 text

ূ໌ॻؔ࿈Controller ▶ certi fi catesigningrequest-signing-controller ▶ certi fi catesigningrequest-approving-controller ▶ certi fi catesigningrequest-cleaner-controller ▶ root-ca-certi fi cate-publisher-controller

Slide 41

Slide 41 text

証明書関連Controller Overview

Slide 42

Slide 42 text

Endponts & EndpointSliceؔ࿈Controller ▶ endpoints-controller ▶ endpointslice-controller ▶ endpointslice-mirroring-controller

Slide 43

Slide 43 text

Endponts & EndpointSlice関連Controller Overview

Slide 44

Slide 44 text

Namespace/ΞΧ΢ϯτؔ࿈Controller ▶ namespace-controller ▶ resourcequota-controller ▶ serviceaccount-token-controller ▶ serviceaccount-controller ▶ clusterrole-aggregation-controller

Slide 45

Slide 45 text

Namespace/アカウント関連Controller Overview

Slide 46

Slide 46 text

Nodeؔ࿈+ͦͷଞController ▶ node-lifecycle-controller ▶ ttl-controller ▶ garbage-collector-controller ▶ storageversion-garbage-collector-controller ▶ resourceclaim-controller ▶ validatingadmissionpolicy-status-controller

Slide 47

Slide 47 text

Node関連+その他Controller Overview

Slide 48

Slide 48 text

まとめ

Slide 49

Slide 49 text

まとめ ▶ ザックリとkube-controller-managerのアーキテクチャと実⾏しているControllerの概要を 紹介しました ▶ kube-controller-managerはController数が多いし、kube-controller-manager外とも連携 して動作するので、これ何か特定の機能を全て理解するのは難しかったりしますが、今回 ざっくりと⼀通りのController実装を眺めてみたことで内部実装の解像度がより鮮明になっ たように思います ▶ また、ResourceClaimなどの新機能についてもざっと触れる機会があったのでおもしろ かったです

Slide 50

Slide 50 text

もう少し詳しいメモはzennのスクラップでまとめています https://zenn.dev/bells 1 7 /scraps/ 5 9 2 a 0 2 b 3 bc 1 ff 3

Slide 51

Slide 51 text

参考資料 ▶ https://github.com/kubernetes/kubernetes/tree/v 1 . 2 8 . 2

Slide 52

Slide 52 text

画像引⽤元 ▶ https://github.com/kubernetes/community/tree/master/icons ▶ https://github.com/kubernetes/kubernetes/tree/master/logo ▶ https://github.com/cncf/artwork/tree/master/projects/kubernetes ▶ https://github.com/kubernetes/kubeadm/tree/main/logos

Slide 53

Slide 53 text

Thanks / Question? ▶ @bells 1 7 ▶ Slide: https://speakerdeck.com/bells 1 7 ▶ @bells 1 7 _

Slide 54

Slide 54 text

追加コンテンツ: Controllerのざっくり解説

Slide 55

Slide 55 text

Podؔ࿈Controller $POUSPMMF໊ આ໌ replicaset-controller ReplicaSetの状態に応じたPodの作成/削除を⾏う。 replicationcontroller-controller ReplicationControllerの状態に応じたPodの作成/削除を⾏う。 deployment-controller Deploymentに応じたReplicaSetの作成と更新を⾏う。 
 DeploymentのRollingUpdateなどの処理もこのControllerで 
 ロジック制御されている。 daemonset-controller DaemonSetに応じて対象となる各Nodeに配置するPodを作成、管理する。 その際ControllerRevisionというリソースを使⽤して状態の管理を⾏いつつPodの作成などを⾏う。 statefulset-controller StatefulSetリソースの設定に基づくPodやPVCを作成~管理する。 job-controller Jobリソースに基づいてPodを作成して、実⾏管理を⾏う。 cronjob-controller CronJobリソース設定に基づくJobリソースの作成とcron式から次回の実⾏時間を計算してenqueする controller。 なのでcron式に対応した定期処理の実⾏はworkqueueのenqueueによって実現されていたことになる。 horizontal-pod-autoscaler-controller HPAの設定に基づいて /scale サブリソースを提供しているリソースのスケールを⾏う。 disruption-controller PodDisruptionBudget(PDB)に紐づくPodの内「ReplicationController」「Deployment」 「ReplicaSet」「StatefulSet」「その他 /scale サブリソースを持つリソース」 のいずれかによって管理されているPodの件数とPDBの設定を⽐較して、 
 起動する必要のあるPod情報などを計算してPDBのステータスに保存するcontroller。 pod-garbage-collector-controller ⼀定間隔で実⾏されて、すでに終了してるけど何らかの理由で削除されずに残っているPodを削除する ttl-after- fi nished-controller Jobが実⾏が完了してからSpec.TTLSecondsAfterFinished分の時間を過ぎたJobを削除するcontroller

Slide 56

Slide 56 text

ϘϦϡʔϜؔ࿈Controller $POUSPMMF໊ આ໌ persistentvolume-binder-controller 主にPVCとPVの紐づけ処理を⾏う。 場合によってはPVのプロビジョニングも⾏う。 persistentvolume-attach-detach- controller PVCやPV、Podなどの状態を元にPodのスケジュール対象NodeにPVのアタッチ/デタッチを⾏う。 アタッチ/デタッチの具体的な処理⽅法はVolume Pluginの実装に依存しており、例えばCSI Driverであ ればVolumeAttachmentの作成/削除を⾏い、実際のアタッチ/デタッチはCSI Driver側で⾏うなどする。 persistentvolume-expander- controller PVCのボリュームサイズ拡張に応じてVolume Pluginを⽤いて実ボリュームのリサイズを⾏い、その結果 をPVのサイズに反映する。 なおCSI DriverについてはVolume Pluginが対応していなかったので、CSI Driverとsidecar側で勝⼿にや るんだと思われる。 persistentvolumeclaim-protection- controller PVCに "kubernetes.io/pvc-protection" fi nalizerをつけて削除保護を⾏い、PVC削除時にPVCに紐付けら れたPVを使⽤しているPodがあるかどうかを持って fi nalizerのON/OFFを⾏いPVCの削除タイミングをコ ントロールする。 persistentvolume-protection- controller persistentvolumeclaim-protection-controllerのPV版 PVが"Bound"ステータスか否かに応じて"kubernetes.io/pv-protection"Annotationのつけ外しを⾏い PVの削除保護を⾏う。 ephemeral-volume-controller Podにephemeral volumeが設定されていた場合、ephemeral volume⽤のPVCを作成する。 ephemeral volumeはPVCにPodのowner referenceが設定されるようなので、Pod owner referenceの 有無を持ってephemeralかどうかを判断してるのかも。

Slide 57

Slide 57 text

ূ໌ॻؔ࿈Controller $POUSPMMF໊ આ໌ certi fi catesigningrequest-signing- controller Certi fi cateSigningRequestリソースが作られたら、 
 Status.Certi fi cateに⽣成した証明書データを設定する。 certi fi catesigningrequest-approving- controller Certi fi cateSigningRequestをチェックして、問題なければSubjectAccessReviewsを作成して Certi fi cateSigningRequestのStatusに成功結果のコンディションを設定するcontroller。 certi fi catesigningrequest-cleaner- controller 下記のCerti fi cateSigningRequestを削除するcontroller。 • 承認済み or 拒否済み or 証明書の発⾏に失敗した or 承認も拒否もされなかったもので古くなったもの • 承認済みだけど証明書が失効したもの root-ca-certi fi cate-publisher- controller 各Namespaceに"kube-root-ca.crt"というCon fi gMapを作成して、 
 “ca.crt"というキー名にrootCAデータを設定するcontroller。

Slide 58

Slide 58 text

Endponts & EndpointSliceؔ࿈Controller $POUSPMMF໊ આ໌ endpoints-controller Serviceリソースを元にEndpointsリソースを設定する。 
 ExternalNameのServiceについてはSelectorが有る限りはEndpointsが作成されるようだった。 endpointslice-controller Serviceリソースを元にEndpointSliceリソースを設定する。 
 ExternalNameのServiceについてはSelectorが有る限りはEndpointSliceが作成されるようだった。 endpointslice-mirroring-controller Endpointsを元にEndpointSliceを⽣成する。 
 Endpoints→EndpointSliceへの移⾏期のためのControllerっぽい。

Slide 59

Slide 59 text

Namespaceؔ࿈Controller #1 $POUSPMMF໊ આ໌ namespace-controller namespace-controllerは下記のような処理を⾏う。 • 対象Namespaceの Namespace.Spec.Finalizers が空では無く、また • namespace.DeletionTimestamp が空のときに限定して処理が実⾏される • Namespaceの削除時に対象NamespaceのNamespacedなリソースのすべてを削除する(ただしDelete APIのあるものに限定) • 削除を試みた結果 fi nalizerやその他の影響で削除できないリソースがあった場合はrequeueされ、再度 削除が試みられる • 全リソース削除ができなかったリソースにPodが含まれる場合、Podのgraceful shutdownの設定に応 じてrequeueの時間が調整されるよう(estimate) • 対象Namespaceの Namespace.Spec.Finalizersからnamespace-controllerの fi nalizerを取り除く 
 上記のようにNamespaceに紐づくリソースが(ほぼ)完全に削除されるまで処理を繰り返すコントロー ラーとなっているよう

Slide 60

Slide 60 text

Namespaceؔ࿈Controller #2 $POUSPMMF໊ આ໌ resourcequota-controller 仕組みとしては複雑なんだけど、やってることとしてはResourceQuotaで設定されたQuotaの設定項⽬ と、その対象となるリソースの使⽤量をResourceQuota.Statusに保存して、現在のリソース使⽤量を保 存する、ということをやっている。 これを実現するためにおおまかに⾔うと下記のようなことをやっている。 • 現在の各種ResourceQuotaの設定を取得 • 各種ResourceQuotaの設定に基づき、QuotaMonitorというQuotaを監視するモニターを管理するマネ ージャーがMonitorと呼ばれる対象リソースを監視するcontrollerのようなものを起動(リソース別にgo routineを実⾏している感じ) • 各Monitorを通してリソースの変更が⾏われたものを取得して、対象リソース(+Namespace)に関連す るResourceQuotaをqueueに追加 • resourcequota-controller側の調整ループにより、ResourceQuotaで設定されたQuotaの設定項⽬と、 その対象となるリソースの使⽤量をResourceQuota.Statusに保存して、現在のリソース使⽤量を保存 する 
 その他ResourceQuotaを定期的に全件requeueしたりなどもしているが最終的にはこんな感じのことを やっている。 
 
 API Server側でのValidatingはQuotaAdmissionプラグインを⽤いて実現している。

Slide 61

Slide 61 text

ΞΧ΢ϯτؔ࿈Controller $POUSPMMF໊ આ໌ serviceaccount-token-controller serviceaccount-token-controllerは下記のような処理を⾏う。 • service accountに紐づくtoken(secret)の管理を⾏う • tokenに紐づくservice accountがなければtokenの削除を⾏い • service accountに紐づくtokenを必要に応じて⽣成して更新する serviceaccount-controller serviceaccount-controllerは下記のような処理を⾏う。 • 作成されたNamespaceに"default" ServiceAccountを作成する • "default" ServiceAccountが削除された場合に再作成を⾏う clusterrole-aggregation-controller 名前の通りClusterRoleにはClusterRole.AggregationRuleという他のClusterRoleのRuleを⾃⾝に取り組 む設定があるらしい。 具体的には ClusterRole.AggregationRule.ClusterRoleSelectors のラベルルールにマッチする ClusterRoleの各種Ruleを取り込むように対象ClusterRoleのRuleの更新を⾏う。

Slide 62

Slide 62 text

Nodeؔ࿈+ͦͷଞController $POUSPMMF໊ આ໌ node-lifecycle-controller • Nodeのコンディション状態などが正しくkubeletによって更新されているかを確認して、更新されて いなかったら更新する(kubeletが停⽌したりしたケースを想定してる?) • Nodeのコンディションなどが変更された場合のPodの際スケジュールのためのPodのステータス更新 や削除 といったことを⾏っている。 なので"NoExecute"なTaintが出た際にPodを再スケジュールさせるのはこのコントローラーのおかげの よう。 ttl-controller "node.alpha.kubernetes.io/ttl" AnnotationというCon fi gMapやSecretの更新を⾏うタイミングをNode に提案するための時間情報をNodeに設定するコントローラーのよう。 garbage-collector-controller ゴミとなったリソースの削除を⾏っているらしいけど詳細がよくわからない。 storageversion-garbage-collector- controller • 各StorageVersionsリソースのStatus.StorageVersionsから⾃⾝のものがあれば除外する。 • 各StorageVersionsリソースのStatus.StorageVersionsから無効なものがあれば除外する。 • Status.StorageVersionsが存在しなければ、そのStorageVersionsは削除する。 といった処理を⾏うよう。 validatingadmissionpolicy-status- controller validatingadmissionはPolicyがCommon Expression Language(CEL)でルールを記述することが可能に なった。 
 このcontrollerでは、このCELの⽂法が正しいかをチェックするcontrollerとなっている。 バリデーションエラーになったポリシーをValidatingAdmissionPolicyの Status.TypeChecking.ExpressionWarningsに設定するという処理を⾏う。

Slide 63

Slide 63 text

Nodeؔ࿈+ͦͷଞController #2 $POUSPMMF໊ આ໌ resourceclaim-controller ざっくりこんな感じのよう。 • ResourceClaimsは紐づくdriverによって管理するリソースの要求‧管理を⾏うリソース • ResourceClaims.Status.ReservedFor は複数Podを紐付けられるので、driverの設定次第でこのリソー スを複数Podでシェアすることが可能 • PodSchedulingContextsは(ResourceClaimsを使⽤する)Podが使⽤するNodeを紐付ける • PodからResourceClaimsが作られて、driverによってResourceClaimsの実体が設定されて、 schedulerでNodeが設定されたらPodSchedulingContextsが作られて、 ResourceClaims.Status.ReservedForによってPodと紐付けられて、ResourceClaimsを要求するPod が無くなったらResourceClaimsを削除する おおまかにいうと初めっからCSI Driver⽅式で実装されたvolume pluginみたいな感じのやつ。