$30 off During Our Annual Pro Sale. View Details »

Cloud Controller Manager Deep Dive

bells17
September 09, 2020

Cloud Controller Manager Deep Dive

Cloud Native Days Tokyo 2020(#CMDT2020)で発表したCloud Controller Managerに関するセッションです

https://event.cloudnativedays.jp/cndt2020/talks/32

bells17

September 09, 2020
Tweet

More Decks by bells17

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

  4. 注意点
    ▶ 内容としてはCloud Controller ManagerのDeep Diveセッションを想定
    してます
    + なのでKubernetesそのものの説明は、ある程度知っている前提で

    話すと思います
    ▶ コードべースはv1.17です(release-1.17タグ)
    + ちょっと古いけど最新版もそんなにロジック変わらないはず(たぶん)

    View Slide

  5. アジェンダ
    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. まとめ

    View Slide

  6. Cloud Controller Managerとは?

    View Slide

  7. Cloud Controller Manager
    ▶ Kube Controller ManagerなどKubernetesのコアコンポーネントから

    クラウドプラットフォームに関するロジックを分離させたコンポーネント
    + クラウドプラットフォーム: AWSとかOpenStackみたいなk8sを動作

    させてるIaaS環境というイメージが近い
    ▶ 追加されたk8sノードの初期化処理や、Serviceのtype: LoadBalancerに対
    応したL4ロードバランサーの構築をしたりといった、k8sが利⽤している

    クラウド環境との連携を⾏うことができる
    ▶ 対応するクラウド環境と連携させるためのCloud Provider実装を組み込ん
    でビルドする必要がある
    + 公式やクラウドプラットフォームがサポートしているCloud Provider実
    装があれば⾃前での実装は不要

    View Slide

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

    View Slide

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

    View Slide

  10. View Slide

  11. Cloud Controller Managerの

    Design Proposal

    View Slide

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

    View Slide

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

    View Slide

  14. Design Proposalの要約(変更内容)
    ▶ 当時はKubernetesの複数のコンポーネントがCloud Providerの実装に

    依存していた
    ▶ 依存コンポーネントは
    + kube-controller-manager
    + kubelet
    + kube-apiserver
    ▶ これらのリファクタリングを⾏いつつ、Cloud Provider実装に依存する
    箇所をCloud Controller Managerに処理を切り出す

    View Slide

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

    View Slide

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

    View Slide

  17. Cloud Controller Managerの実装の概要

    View Slide

  18. View Slide

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

    View Slide

  20. Kubernetes Componentの実装

    View Slide

  21. View Slide

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

    あるのが基本

    View Slide

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

    View Slide

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

    View Slide

  25. View Slide

  26. View Slide

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

    View Slide

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

    View Slide

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

    更新処理を⾏う

    View Slide

  30. 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"

    View Slide

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

    View Slide

  32. NodeController(1)
    ▶ k8sの各ノードの初期化処理を⾏うコントローラー
    ▶ NodeリソースのCreate/Updateイベントをハンドリングして調整ループ
    を実⾏
    ▶ `node.cloudprovider.kubernetes.io/uninitialized`というtaintが

    付与されているノードを初期化処理が⾏われていないノードとみなして
    実⾏対象にする
    ▶ `node.cloudprovider.kubernetes.io/uninitialized` taintはkubeletを
    `--cloud-provider=external`フラグ付きで起動すると付与される

    View Slide

  33. NodeController(2)
    ▶ 以下の処理を⾏う
    + NodeオブジェクトにIPアドレス情報を設定
    + NodeオブジェクトのラベルにNodeが動いているマシン情報

    (e.g. インスタンスタイプ)やゾーン、リージョン情報の設定
    ▶ 上記が完了すると`node.cloudprovider.kubernetes.io/uninitialized`
    taintの除去を⾏う

    View Slide

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

    View Slide

  35. RouteController
    ▶ k8sの各ノードのPodCIDRの経路情報の設定を⾏うコントローラー
    ▶ 設定値のRouteReconciliationPeriod秒毎に調整ループを⾏う
    ▶ 前提としてClusterCIDRが未設定のクラスターのとき動作するように
    なってるっぽい
    ▶ 処理としては以下のようなことを⾏っているっぽい
    + VPCなどの経路設定情報を取得
    + 各ノードのPodCIDRの経路設定が⾏われているか確認を⾏い、まだ

    ⾏われていなければ経路情報の設定を⾏う
    + すでに使われていない古い経路情報が残っていれば、それらの削除を
    ⾏う
    + もし経路設定に失敗しているノードがあれば、該当ノードのネット
    ワークコンディションを失敗状態にする

    View Slide

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

    View Slide

  37. Cloud Provider

    View Slide

  38. 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 に
    ある

    View Slide

  39. View Slide

  40. 独⾃の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などの設定を⾏う必要あり

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. まとめ

    View Slide

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

    View Slide

  47. 参考資料
    ▶ 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

    View Slide

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

    View Slide