Slide 1

Slide 1 text

Cloud Controller Manager Deep Dive Cloud Native Days 2020(2020/09/09) @bells17

Slide 2

Slide 2 text

▶ Daiki Hayakawa / @bells17 ▶ Software Engineer ▶ 主に Kubernetes 関連コンポーネントの開発など ▶ Kubernetes #sig-docs-ja-reviews ▶ CNBF実⾏委員 ▶ @bells17_

Slide 3

Slide 3 text

今⽇話すこと ▶ Cloud Controller Managerの概要 ▶ Cloud Controller Managerの導⼊背景 ▶ Cloud Controller Managerの実装と動作するコントローラーについて ▶ Cloud Providerの概要と実装⽅法について

Slide 4

Slide 4 text

注意点 ▶ 内容としてはCloud Controller ManagerのDeep Diveセッションを想定 してます + なのでKubernetesそのものの説明は、ある程度知っている前提で
 話すと思います ▶ コードべースはv1.17です(release-1.17タグ) + ちょっと古いけど最新版もそんなにロジック変わらないはず(たぶん)

Slide 5

Slide 5 text

アジェンダ 1. Cloud Controller Managerとは? 2. Kubernetes アーキテクチャのおさらい 3. Cloud Controller ManagerのDesign Proposal 4. Cloud Controller Managerの実装の概要 5. Kubernetes Componentの実装 6. Cloud Controller Managerが起動するコントローラー群 7. Cloud Provider 8. まとめ

Slide 6

Slide 6 text

Cloud Controller Managerとは?

Slide 7

Slide 7 text

Cloud Controller Manager ▶ Kube Controller ManagerなどKubernetesのコアコンポーネントから
 クラウドプラットフォームに関するロジックを分離させたコンポーネント + クラウドプラットフォーム: AWSとかOpenStackみたいなk8sを動作
 させてるIaaS環境というイメージが近い ▶ 追加されたk8sノードの初期化処理や、Serviceのtype: LoadBalancerに対 応したL4ロードバランサーの構築をしたりといった、k8sが利⽤している
 クラウド環境との連携を⾏うことができる ▶ 対応するクラウド環境と連携させるためのCloud Provider実装を組み込ん でビルドする必要がある + 公式やクラウドプラットフォームがサポートしているCloud Provider実 装があれば⾃前での実装は不要

Slide 8

Slide 8 text

Kubernetesアーキテクチャのおさらい

Slide 9

Slide 9 text

https://github.com/kubernetes/website/blob/fb6364da0afd19e8a9515aaae2de9bc74a0a6abd/static/images/docs/components-of-kubernetes.png

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Cloud Controller Managerの
 Design Proposal

Slide 12

Slide 12 text

https://github.com/kubernetes/enhancements/blob/435a1c5c1468f363ecb6437d4a160551ee7a9d3c/keps/0001-kubernetes-enhancement-proposal-process.md

Slide 13

Slide 13 text

Design Proposalの要約(動機) ▶ 当時各Cloud Providerの実装のアップデートがKubernetesのライフサイ クルに依存しているという問題があった + Kubernetesのリリースサイクルは3ヶ⽉に1度 ▶ そのためCloud Provider実装をKubernetesのコアから外部に移⾏したい + Cloud Provider⾃⾝がリリースサイクルを管理できるようになる

Slide 14

Slide 14 text

Design Proposalの要約(変更内容) ▶ 当時はKubernetesの複数のコンポーネントがCloud Providerの実装に
 依存していた ▶ 依存コンポーネントは + kube-controller-manager + kubelet + kube-apiserver ▶ これらのリファクタリングを⾏いつつ、Cloud Provider実装に依存する 箇所をCloud Controller Managerに処理を切り出す

Slide 15

Slide 15 text

結果的に変化したこと ▶ 外部化することで、Kubernetes公式のサポート外環境でもクラウドと の連携が可能になった + Kubernetesが提供するインターフェイスに沿った実装を組み込め ば、任意のクラウド環境向けのCloud Controller Managerが実装可能 になったため ▶ 各種コンポーネントのバイナリに含まれていたCloud Provider向けの 実装が削減されたため、その分バイナリサイズが⼩さくなった

Slide 16

Slide 16 text

https://kubernetes.slack.com/archives/C718BPBQ8/p1566870958006200 実際に約70MBほどサイズが減ったらしい

Slide 17

Slide 17 text

Cloud Controller Managerの実装の概要

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

アーキテクチャ ▶ 4種類のコントローラー起動 + Node + Node Lifecycle + Service + Route ▶ 各コントローラーはそれぞれでイベントハンドリングを⾏い、必要に 応じて組み込んだCloud Providerのメソッドを呼び出す ▶ クラウドプラットフォームとの直接のやり取りはすべてCloud Provider を経由して⾏う ▶ Cloud Providerはインターフェイスが定義されていて、独⾃実装する場 合はインターフェイスを満たしたものを実装する

Slide 20

Slide 20 text

Kubernetes Componentの実装

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

基本パターン ▶ Managerプロセス全体の中で1つ、または複数のコントローラーが実⾏ される ▶ コントローラーは1つにつき、1種類のKubernetesリソースのみに対す る調整ループ(Reconciliation Loop)が実⾏される + 調整ループ: リソースのあるべき状態(Desired State)と実際の状態 (Actual State)を⽐較~あるべき状態になるように調整処理を⾏うもの + なので、2種類のリソースに対しては、最低2コントローラー以上が
 あるのが基本

Slide 23

Slide 23 text

調整ループ ▶ 主に以下の2種類の⽅法で実⾏される + Event Handlers: 監視対象のKubernetes Resourceの更新といった、 なんらかのイベントを元に実⾏される + 無限ループによる定期実⾏: 設定値に基づいて数秒毎などの間隔で定 期実⾏が⾏われる

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

▶ Kubernetesのコードリーディングをする上で知っておくと良さそうなこと こういったKubernetes Componentの実装周りについてはコード リーディングについての記事の中で書いたので良ければ⾒てください

Slide 28

Slide 28 text

Cloud Controller Managerが起動する コントローラー群

Slide 29

Slide 29 text

ServiceController(1) ▶ Serviceのtype: LoadBalancerの設定に基づきクラウド環境のL4ロード バランサーの構築・設定を⾏うコントローラー ▶ 以下の2種類のメソッドによりL4ロードバランサーのDesired Stateを実 現する + worker: Kubernetes Component実装の基本パターンのEvent Handlersパターンによるイベント駆動 + Serviceリソースのイベントをハンドリングして調整ループを実⾏ + LBの作成/更新/削除処理を⾏う + nodeSyncLoop: 100秒毎に実⾏され、各Service type: LoadBalancer に対応する、クラウド側のロードバランサーに紐付けるノード⼀覧の
 更新処理を⾏う

Slide 30

Slide 30 text

ServiceController(2) ▶ LBに紐付けが⾏われるノードは以下の条件にマッチするもの + Ready状態のノードであること + unschedulableではないノードであること + kubectl cordon コマンドを使うとunschedulableとなり、Podがスケ ジュールされなくなる + "LegacyNodeRoleBehavior" feature gateがONの場合 + 以下のラベルが無いノードであること + "node-role.kubernetes.io/master" + "ServiceNodeExclusion" feature gateがONの場合 + 以下のラベルが無いノードであること + “node.kubernetes.io/exclude-from-external-load-balancers" + "alpha.service-controller.kubernetes.io/exclude-balancer"

Slide 31

Slide 31 text

ServiceController(3) ▶ 個⼈的に気になっている点 + LBの作成/削除を⾏うのは基本的にworker側の調整ループで⾏う想定と なっている + nodeSyncLoopではCloud ProviderのLB設定をアップデートするメソッ ド(UpdateLoadBalancer)を呼び出すのみ + そのため、クラウド側で該当のLBの削除などを⾏っても、該当LBに紐づ くServiceリソースの変更イベントが無い限りはLBが⾃動で再構築され るといったことは⾏われない + Cloud Provider側のUpdateLoadBalancerでLBの有無を確認し、無けれ ば再⽣成する処理を⾏えば対応可能ではあるが、そういった実装になっ ているCloud Providerは把握している範囲では存在しない

Slide 32

Slide 32 text

NodeController(1) ▶ k8sの各ノードの初期化処理を⾏うコントローラー ▶ NodeリソースのCreate/Updateイベントをハンドリングして調整ループ を実⾏ ▶ `node.cloudprovider.kubernetes.io/uninitialized`というtaintが
 付与されているノードを初期化処理が⾏われていないノードとみなして 実⾏対象にする ▶ `node.cloudprovider.kubernetes.io/uninitialized` taintはkubeletを `--cloud-provider=external`フラグ付きで起動すると付与される

Slide 33

Slide 33 text

NodeController(2) ▶ 以下の処理を⾏う + NodeオブジェクトにIPアドレス情報を設定 + NodeオブジェクトのラベルにNodeが動いているマシン情報
 (e.g. インスタンスタイプ)やゾーン、リージョン情報の設定 ▶ 上記が完了すると`node.cloudprovider.kubernetes.io/uninitialized` taintの除去を⾏う

Slide 34

Slide 34 text

NodeLifeCycleController ▶ k8sの各ノードの状態チェックを⾏うコントローラー ▶ 設定値のNodeMonitorPeriod秒毎に調整ループを⾏う ▶ 処理としては全ノードに対して以下のようなことを⾏う + ノードのステータスが”Ready”かチェックを⾏う + “Ready”ではない場合、ノードがシャットダウンしているかチェック を⾏い、シャットダウン状態であれば `node.cloudprovider.kubernetes.io/shutdown` taintを付与する + シャットダウン状態のノードのステータスが”Ready”に復帰すれば taintを除去する + “Ready”でもないし、シャットダウン状態でもないのであれば、イン スタンスが存在するのかのチェックを⾏い、存在しなければノードの 削除を⾏う

Slide 35

Slide 35 text

RouteController ▶ k8sの各ノードのPodCIDRの経路情報の設定を⾏うコントローラー ▶ 設定値のRouteReconciliationPeriod秒毎に調整ループを⾏う ▶ 前提としてClusterCIDRが未設定のクラスターのとき動作するように なってるっぽい ▶ 処理としては以下のようなことを⾏っているっぽい + VPCなどの経路設定情報を取得 + 各ノードのPodCIDRの経路設定が⾏われているか確認を⾏い、まだ
 ⾏われていなければ経路情報の設定を⾏う + すでに使われていない古い経路情報が残っていれば、それらの削除を ⾏う + もし経路設定に失敗しているノードがあれば、該当ノードのネット ワークコンディションを失敗状態にする

Slide 36

Slide 36 text

▶ KubernetesのCloud Controller Managerについて ▶ KubernetesのServiceControllerの実装 Cloud Controller Managerのコントローラーに関する記事は 以下の記事でも書いたので興味があればチェックしてみてください

Slide 37

Slide 37 text

Cloud Provider

Slide 38

Slide 38 text

Cloud Provider ▶ Cloud Controller Managerに組み込んで実⾏される ▶ Goで定義されたインターフェイスのメソッドを実装して組み込むこと で、独⾃のCloud Provider実装をCloud Controller Managerから利⽤す ることができる ▶ Goのインターフェイスであるcloudprovider.Intrefaceは https:// github.com/kubernetes/cloud-provider/blob/release-1.17/cloud.go に ある

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

独⾃のCloud Providerを実装する ▶ 独⾃のCloud Providerを実装する場合に⾏うのは以下のようにする + cloudprovider.Intrefaceを満たすCloud Providerを実装 + “k8s.io/kubernetes/cmd/cloud-controller-manager/ app”.NewCloudControllerManagerCommand().Execute()を実⾏する コマンドを作成する + 上記コマンドでメイン処理実⾏前に予め以下を⾏うようにする + ⾃作したCloud Providerの登録処理 + 実⾏するCloud Providerの指定 ▶ PodとしてCloud Controller Managerを実⾏する際には適切なRBACや tolerationsなどの設定を⾏う必要あり

Slide 41

Slide 41 text

注意点 ▶ Cloud Controller ManagerはCSIなどのように、どの機能を実装すると こう動作する、といった仕様が明確ではない ▶ そのため、Cloud Controller Managerの実装を直接読む、他のCloud Provider実装を参考に実装するといった対応が必要になってくる

Slide 42

Slide 42 text

Digitaloceanのコマンド例(コメントを削ったものです)

Slide 43

Slide 43 text

Cloud Providerの登録処理はinit()を使って⾃動で⾏うことが多い

Slide 44

Slide 44 text

メソッドの実装はこんな感じに⾃分たちに必要なものだけ⾏う

Slide 45

Slide 45 text

まとめ

Slide 46

Slide 46 text

まとめ ▶ Cloud Controller Managerの動作とその実装について紹介しました ▶ Kubernetesの裏側で動作するコンポーネントがどんなふうに動作しているのかの理解を深 めるきっかけになればと思います ▶ 実際にCloud Providerを組み込んだCloud Controller Managerを⾃作してみると Kubernetesに対する理解が深まって⾯⽩いかなと思います

Slide 47

Slide 47 text

参考資料 ▶ Kubernetes Components https://kubernetes.io/docs/concepts/overview/components/ ▶ Cloud Controller Manager https://kubernetes.io/docs/concepts/architecture/cloud-controller/ ▶ Developing Cloud Controller Manager https://kubernetes.io/docs/tasks/administer-cluster/developing-cloud-controller-manager/ ▶ Controllers https://kubernetes.io/docs/concepts/architecture/controller/ ▶ Nodes https://kubernetes.io/docs/concepts/architecture/nodes/ ▶ client-go under the hood https://github.com/kubernetes/sample-controller/blob/master/docs/controller-client-go.md ▶ Kubernetes Source Code: https://github.com/kubernetes/kubernetes/blob/release-1.17 ▶ Cloudprovider.Interface https://github.com/kubernetes/cloud-provider/blob/release-1.17/cloud.go ▶ Refactor Cloud Provider out of Kubernetes Core https://github.com/kubernetes/community/blob/1922998843eb61d13eb41d6303e36e5e206a1cee/ contributors/design-proposals/cloud-provider/cloud-provider-refactoring.md ▶ Kubernetes Enhancement Proposal Process https://github.com/kubernetes/enhancements/blob/435a1c5c1468f363ecb6437d4a160551ee7a9d3c/keps/ 0001-kubernetes-enhancement-proposal-process.md ▶ KEP Template https://github.com/kubernetes/enhancements/tree/435a1c5c1468f363ecb6437d4a160551ee7a9d3c/keps/NNNN-kep-template ▶ digitalocean-cloud-controller-manager: https://github.com/digitalocean/digitalocean-cloud-controller-manager ▶ Kubernetesのコードリーディングをする上で知っておくと良さそうなこと https://bit.ly/2BY8FzM ▶ KubernetesのCloud Controller Managerについて https://bit.ly/2DW1oBP ▶ KubernetesのServiceControllerの実装 http://bit.ly/2SCjm0C

Slide 48

Slide 48 text

Thanks / Question? ▶ Daiki Hayakawa, @bells17 ▶ Slide: https://speakerdeck.com/bells17 ▶ Blog: https://medium.com/@bells17 ▶ @bells17_