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

Kubernetesのコントローラーに入門してみる

 Kubernetesのコントローラーに入門してみる

社内で開催した、Kubernetesのコントローラーに関しての勉強会資料です。
Kubernetesのコンポーネントに関するおさらいや、コントローラーの仕組みに関して解説した後、実際にReplicaSetコントローラーの実装を追っていきます。

Avatar for Kosuke Taniguchi

Kosuke Taniguchi

October 25, 2025

Other Decks in Programming

Transcript

  1. Agenda • 今日のゴール • Kubernetesに関しておさらい • Podがデプロイされるまで • コントローラーとは? •

    ReplicaSetコントローラーの実装を覗いてみる • カスタムコントローラーを作る時は ...?
  2. Podがデプロイされるまで https://kubernetes.io/ja/docs/concepts/overview/components/ ①kubectl apply -f deployment.yaml ②オブジェクトを永続化 ③リソースの更新を検知 & Podを生成

    ④PodをNodeへ割り当て ⑤kubeletがPodを起動 ⑥kubeletがPodの状態等 をapiserver 経由で etcdに 永続化 ↓今日はここを深掘り!
  3. コントローラーとは? Desired State (yaml) Actual State (実際のリソース) コントローラー kubectl apply

    … ①Desired Stateを取得 ②Actual Stateを取得 ③Desired StateとActual Stateに 差分があれば Actual Stateを更新
  4. コントローラーとは? Desired State (yaml) Actual State (実際のリソース) コントローラー kubectl apply

    … ①Desired Stateを取得 ②Actual Stateを取得 ③Desired Stateに変更があれば Actual Stateを更新 Reconciliation Loop(=①~③の繰り返し)
  5. ???

  6. コントローラーとは? • Informer:リソースの変更を監視。変更があれば in-memoryキャッシュへ保存 ◦ Reflector:apiserverをwatch ◦ Indexer:in-memoryキャッシュ。実体はスレッドセーフな map。Reflectorがwatchした結果を保持 •

    EventHandler:Informerが検知したイベントを処理する。基本的に workqueueへenqueueする • WorkQueue:EventHandlerにより登録されたイベントを溜める Queue • Lister:Indexerのラッパー。これにより簡単に Indexerからリソースの状態を取得できる コントローラーのコンポーネント: apiserverへの過負荷を避けるため
  7. コントローラーとは? • Informer:リソースの変更を監視。変更があれば in-memoryキャッシュへ保存 ◦ Reflector:apiserverをwatch ◦ Indexer:in-memoryキャッシュ。実体はスレッドセーフな map。Reflectorがwatchした結果を保持 •

    EventHandler:Informerが検知したイベントを処理する。基本的に workqueueへenqueueする • WorkQueue:EventHandlerにより登録されたイベントを溜める Queue • Lister:Indexerのラッパー。これにより簡単に Indexerからリソースの状態を取得できる コントローラーのコンポーネント: ↑大体ここら辺のコンポーネントを抑えればなんとなくコントローラーのソースコードは読める ...! apiserverへの過負荷を避けるため
  8. ①イベントハンドラーによるイベントの enqueue これを回避するための Controller Expectation Controller Expectationによる重複実行の回避 • →コントローラーはキャッシュを参照するため、重複で削除が実行される可能性がある(下記参考) ◦

    Podを5→3にしたい ◦ キャッシュを見るとPodが5つあるので2つ削除 ◦ 再び見ると、5つあるので2つ削除(キャッシュが更新されていない) ◦ →合計4つのPodが削除されてしまう
  9. ①イベントハンドラーによるイベントの enqueue Controller Expectationによる重複実行の回避 • Podを5→3にする • ExpectationにPodを2つ削除することを記録 • Podを2つ削除するリクエストを

    apiserverへ送る • 再びキャッシュを見るとまだ Podは2つあるが、Expectationのカウンタが2なので何もしない • Podを1つ削除するとExpectationのカウンタを1減らす(これを削除した分繰り返す)
  10. ②実際のreconcile処理 やっていることは • イベントハンドラーにより enqueueされたオブジェクトをworkqueueから取得しReconcile処理を呼び 出す • Reconcile処理では下記をしている ◦ 対象のReplicaSetを取得

    ◦ 対象のReplicaSetの管理対象のPodを取得する ◦ desiredとactualを比較しPodの数の調整 ◦ Podの数、Ready数、Terminating数を計算し、ReplicaSetのStatusを更新
  11. ②実際のreconcile処理 やっていることは • イベントハンドラーにより enqueueされたオブジェクトをworkqueueから取得しReconcile処理を呼び 出す • Reconcile処理では下記をしている ◦ 対象のReplicaSetを取得

    ◦ 対象のReplicaSetの管理対象のPodを取得する ◦ desiredとactualを比較しPodの数の調整 ◦ Podの数、Ready数、Terminating数を計算し、ReplicaSetのStatusを更新
  12. ②実際のreconcile処理 やっていることは • イベントハンドラーにより enqueueされたオブジェクトをworkqueueから取得しReconcile処理を呼び 出す • Reconcile処理では下記をしている ◦ 対象のReplicaSetを取得

    ◦ 対象のReplicaSetの管理対象のPodを取得する ◦ desiredとactualを比較しPodの数の調整 ◦ Podの数、Ready数、Terminating数を計算し、ReplicaSetのStatusを更新
  13. カスタムコントローラー作る時も ... • Informer, Reflector, DeltaFIFO, workqueueなどを意識しないといけない ...? • イベントハンドラーも自分で作らないといけない

    ...? • カスタムリソースの構造体も自前で定義 ...? • というか、そもそもどこから書いていけば良いんだろう ...
  14. • controller-runtime ◦ https://github.com/kubernetes-sigs/controller-runtime ◦ client-goをラップした高レベルなライブラリ ◦ 開発者はキャッシュや workqueueなどの意識せず reconciliation

    loopのロジックに のみ集中できる • kubebuilder ◦ https://github.com/kubernetes-sigs/kubebuilder ◦ controller-runtimeを利用したスキャフォールドツール ◦ main起動のソースコード、プロジェクト全体を自動生成したり、 CRDの構造体を生成 してくれる(フレームワークに近い) ◦ また、make deployなどにより簡単にコントローラーを起動できる 便利なツールたち