K8s) kube-controller-manager

kube-controller-manager

API SeverInformerKCMControllerController ContextInformer FactoryindexercontrollerwatchqpushsharedProcessorhandlerqeventkeysync()listerSummery거의 모든 리소스 종류(Kind)마다 존재능동적인 상태 관리(Reconciliation)가필요한 리소스에만 존재

コントローラーを生成(初期化)し、実行する

CreateControllerContextBuildControllersInformerFactory.Start()RunControllers순서informer 생성 및 등록 (to factory)informer factory 생성핸들러 등록 (informer 구독)informer 실행- watch AP 서버Controller 실행- 리소스 상태 sync

コア初期化 (run 関数)

  • CreateControllerContext
    • 全てのコントローラーが共有する SharedInformerFactoryClient を生成
  • BuildControllers
    • informer を生成し、登録
    • コントローラーが informer に ハンドラー を登録(購読)
  • InformerFactory.Start
    • InformerFactory を開始し、キャッシュ の同期を開始
  • RunControllers
    • 各コントローラーのループを実行

Controller

deployment.DeploymentControllerworkqueue.TypedRateLimitingInterface[string]queueappslisters.DeploymentListerdListerclientclientset.InterfaceInformerIndexer (cache)deploymentListerlisters.ResourceIndexer(Accessor)AddEventHandler(Subscribe)enqueueInformerhandlerdeployment.DeploymentControllerqueueenqueuedListerRun()indexergetprocessNextWorkItem()syncDeployment()e.g.addDeploymentController 동작

目標状態と現在の状態を一致させる無限ループ

能動的な状態管理(Reconciliation)が必要なリソースにのみ存在する

役割

  • 多数のコントローラー(リソースごとに存在する)を調整
  • 共有依存関係を管理(Informers, Clients)
  • 高可用性(Leader Election)を処理
Leader Election

マスターノード 3台にそれぞれ1つずつ、合計3つの kube-controller-manager プロセス(インスタンス)を起動

  • このうち1つだけがリーダーに選出(選出基準:先着順)され、全てのコントローラーを生成・実行する
  • リーダーは2秒ごとに Lease というドキュメント(定期的な生存報告用)を更新する
  • 残りは待機状態(Standby)となり、リーダー障害時に政権交代が行われる
    • 全てのデータの元(Truth)は etcd にのみ保存されているため、引き継ぎは不要

動作

queuekey のみを追加し、Worker がキューから取り出してビジネスロジック(sync)を実行する

  • informer に EventHandler を登録
    • EventHandler では queue に key を追加するロジックを実行する
  • レート制限付きキューを使用
    • workqueue.TypedRateLimitingInterface[string]
    • リトライ回数が増えるほど、より遅くリトライする
  • key の形式
    • "Namespace/Name"
  • データは常に処理直前に取得
    • データは informer のローカルキャッシュを lister を通じて取得する

Informer

SharedInformerFactoryInformerAPI ServerListerWatcherWatchIndexersharedProcessorCachingControllerNotifyControllerupdate(Reflector)리소스 종류마다 하나씩 존재map[reflect.Type]cache.SharedIndexInformerdeploymentInformerLister()Informer()InformerIndexer (cache)InformerInformerInformer...InformerGET ?watch=trueAPI Server(Streaming)Transfer-Encoding: chunkedwatch.Eventqueueindexereventtypeobject infoprocessLoop()handlerHandleDeltas()PopprocessDeltas()ControllerupdatecallInformerRun()SharedProcessorProcessorListenerdistributeaddChnextChrunringbufferlisteners 목록 관리버퍼링(Queueing) & 핸들러 함수 실행Informerrequest(Watch)responseInformerFactory.Start()Informer 동작watch()API Serverconnectionresponse body+ DeltaTyped.reader.Read(d.buf[base:])framer.NewFrameReader(resp.Body)JSON 문법상 중괄호 { 와 } 의 짝이 맞을 때까지스트림을 읽어서 하나의 완벽한 JSON 객체가완성되는 시점을 데이터의 끝으로 인식streaming.NewDecoder

「DB を直接参照せず、変更点のみを購読してローカルメモリ(キャッシュ)にコピーを持っておこう。」

ほぼ全ての種類のリソース(Kind)ごとに存在する

役割

  • API(Kubernetes API Server)の Watch
    • 一度の接続リクエストでコネクションを確立し、レスポンスボディを継続的に受け取る
  • キャッシュの構築
    • ローカルキャッシュ
      • cache.cacheStorage: treadSafeMap
        • lock (sync.RWMutex): 同時実行制御
        • items (map[string]any): 実際のデータ格納場所
        • index (storeIndex): 検索を高速化するための補助インデックス
  • イベントを購読したコントローラーに通知
sharedInformerFactory

コントローラーが共有する informer を map で管理し、
同一リソースに対して1つの informer(watch, cache)を持つようにする

Reference


Post
Category
Series