Kubernetes Controllerを
Scale-Outさせる方法
Kubernetes Meetup Tokyo #55, 2022/12/22(Thu)
Shingo Omura, Preferred Networks, Inc.
@everpeace
2
@everpeace
▶ Preferred Networks, Inc. / エンジニア
▶ 社内向けオンプレML基盤の開発運用
▶ 社内クラスタ向けにkube-schedulerを拡張
▶ kubernetes sig-scheduling/sig-node でも
時々活動中
Shingo OMURA / @everpeace
3
@everpeace
PFNのオンプレML基盤の概要
続・PFN のオンプレML基盤の取り組み PFN のオンプレML基盤の取り組み
4
@everpeace
● おさらい: Kubernetes Controllerのアーキテクチャ
● Kubernets ControllerをScale-Outする方法
○ Namespace単位のSharding
○ Resource単位のSharding
● Kubernetes自体のScalability限界に注意
● ControllerをShardingさせて嬉しい時
● まとめ
本日の流れ
5
(おさらい)
Kubernetes Controller
のアーキテクチャ
6
@everpeace
Kubernetes Controller とは
Icons made by Gregor Cresnar, Kiranshastry, Icon Pond, Icon Monk from www.flaticon.com is licensed by CC 3.0 BY
kind: MyKind
metadata:
name: my-name
Watching
(Custom) Resources
& Cluster State
Reconciling
Cluster State
Controller
Custom Resourceを使って
Kubernetesを拡張するパターンは
オペレータパターンとも呼ばれます
7
@everpeace
Kuberntes Controllerのアーキテクチャ(Pod内)
✏kubernetes/sample-controller の client-go-controller-interaction.jpeg も参考になります
controller-runtimeによるController実装の概要
Watch()
Watch()
Watch()
reconcile queue
...
Reconciler
Reconciler
Reconciler
Reconciler
並列数は
MaxConcurrentReconciles
で指定できる(default = 1)
Informer
eventqueue
Cache
8
@everpeace
Kuberntes Controllerのアーキテクチャ(Pod間)
Leader
Follower
Follower
Reconcile
Stand by
● 複数PodをActive/(Warm)Standby
な感じでデプロイするのが普通
● Leader Electionを行って
○ Leader: Reconcile担当
○ Follower:Stand by
● なぜ?
○ Leader Pod障害時に早く復旧したい
○ 同一リソースへのReconcileを直列
に行いたい
(SingleWriterはConflict起きない)
9
@everpeace
Kubernetes Controllerは通常Scale Upしかできない
Leader
Follower
Follower
Reconcile
Stand by
Leader内はReconcilerの
並行度を上げることはできる
けど
Leader Podしか
Reconcileしない
ので
Scale-Upしかできない🤔
10
@everpeace
● Reconcilerが追いつかなくなってController内のQueueが詰まる
● Reconcile間隔が増加してReconcileされないように見える
● CacheもStaleし始めてReconcile結果もStale
○ Reconcile結果が間違ってるように見えてしまう
eventqueue
Scale-Upに限界が来るとどうなるか?
Watch()
Watch()
Watch()
reconcile queue
Reconciler
Reconciler
Reconciler
Reconciler
Informer
Cache
Fire icons created by Vectors Market - Flaticon
11
@everpeace
● Reconcile処理が長い場合
○ Reconcile処理が長いとResource数が少なくても詰まりやすい
● Resource数が非常に多い場合
○ Reconcile処理が軽くてもResource数が多いと結局詰まりやすい
Scale-Upに限界が来るのはどんな時?
Fire icons created by Vectors Market - Flaticon
eventqueue
Watch()
Watch()
Watch()
reconcile queue
Reconciler
Reconciler
Reconciler
Reconciler
Informer
Cache
Fire icons created by Vectors Market - Flaticon
12
@everpeace
ReconcileがConflictしないなら
複数Podで並行処理しても
いいはずでは?
↓
Yes🎉
そもそもLeader Podだけで処理ってのがやりすぎでは?
13
Kubernetes Controller
をScale Outさせる方法
14
@everpeace
Horizontal Sharding
Reconcile
Reconcile
Reconcile
kind: MyKind
● object-1
● object-2
● object-3
● object-4
● object-5
kind: MyKind
● object-1
● object-2
kind: MyKind
● object-3
● object-4
kind: MyKind
● object-5
なんとかして
担当Resourceを
重複しないように
Podに割り振る
15
@everpeace
Shardingパターンを考える
Sharding単位 難易 概要 Pros Cons
Namespace
単位
易 ControllerをNamespace
単位にデプロイ
● 特定のnamespaceだけを
対象とするcontrollerは
すぐ作れる
● Manifestもそのまま使え
そう
● SAの権限がNamespaceに
閉じる
● Controller Podが大量に必要
(Podも一応resource)
● Namespace増減の対応難しい
● Cross-Namespace処理NG
● Cluster ScopeなResourceは
対応不可
● Namespace間での負荷は偏る
Resource
単位
難 Consistent Hashing等を
つかって各Podが担当す
るresourceを分散させる
● 1 Deploymentでいい
● Podの増減にしたがって
shardingも追従できるの
でscale outできる
● Frameworkのサポートが
まだ無い
16
@everpeace
● 方法
○ 各namespaceのControllerをデプロイ
○ Reconcileは該当Namespaceのみ対象
(controller-runtimeだとmanager optionで
指定するだけ)
Namespace単位のSharding
Leader
Follower
Follower
ns-1
Leader
Follower
Follower
ns-2
Leader
Follower
Follower
ns-3
Argo Workflow Controller
とかは対応している
担当Namespace
のResourceだけ
をReconcile
17
@everpeace
● Pros
○ 実装が簡単
○ Manifestもほぼそのまま使える
○ SAの権限がNamespaceに閉じる
(Namespace間のIsolationが大事な時は
これが良い)
● Cons
○ Controller Podが大量に必要
○ Namespaceの増減に対応しずらい
○ Namespace間での負荷は偏る
○ Cross-Namespaceな処理NG
○ Cluster ScopeなResource不可
Namespace単位のSharding
Leader
Follower
Follower
ns-1
Leader
Follower
Follower
ns-2
Leader
Follower
Follower
ns-3
Argo Workflow Controller
とかは対応している
担当Namespace
のResourceだけ
をReconcile
18
@everpeace
Resource単位のSharding
● Towards Horizontally Scalable Kubernetes Controllers
○ Tim Ebert (@timebertt) 氏の修士論文
(バーデンヴュルテンベルク州協同州立大学)
● Github Repos
○ timebertt/thesis-controller-sharding
■ 修士論文本体
○ timebertt/kubernetes-controller-sharding
■ Shardingに対応したサンプルController実装
○ timebertt/controller-runtime@v0.12.3-sharding-1
■ Sharding対応のcontroller-runtime
Tim Ebert
@timebertt
Cloud Engineer
@stackitcloud
working on
#Kubernetes
@GardenerProject
19
@everpeace
Resource単位のSharding
出典: "Towards Horizontally Scalable Kubernetes Controllers," Tim Ebert
● ShardはLeaseで定義
○ Shard名 = Lease名 = Pod名
(StatefulSetだとShard名を安定させられる)
● Sharder (Singleton)
○ Shard群をwatchして、
○ Resource群をshardに割り振り
リソースに shard:<shard名>を付与
(by Consistent Hashing)
● Controller (≒Shard)
○ 自身のShard(Lease)を管理
○ shard:<shard名>ラベルが付いている
リソースのみをReconcile
20
@everpeace
● Shardメンバーシップと耐障害性
● オブジェクトの振り分け
● オブジェクトの割当
● 並行Reconcileの防止
Resource単位のSharding〜設計のポイント〜
21
@everpeace
Shardメンバーシップと耐障害性
Sharder Controller Sharder Controller Sharder Controller
<Leader>
Lease
(Shard)
Lease
(Shard)
Lease
(Shard)
SharderがSingleton
Shardメンバシップの認識を一箇所で集中
管理にすることで認識ズレが起きない
(ズレが起きるとObjectのShard割当が
乱れて並行更新が起きる)
ShardがLease (Podじゃない)
Shard=PodだとRollingUpdate等で短期間Pod
が不在なだけでShardが不在になってObject
の再割り当てが必要に。Leaseだと短期間の
Pod不在に対してRobustになる。
Health icons created by Freepik - Flaticon
22
@everpeace
Objectの振り分け=Consistent Hashing
Lease
(Shard)
Lease
(Shard)
Lease
(Shard)
Sharder
Lease
(Shard)
obj1
obj2
obj3
obj4
obj5
obj6
obj7
obj8
<Leader>
Lease
(Shard)
Lease
(Shard)
Lease
(Shard)
Sharder
Lease
(Shard)
obj1
obj2
obj3
obj4
obj5
obj6
obj7
obj8
<Leader>
23
@everpeace
Objectの振り分け = Consistent Hashing
Lease
(Shard)
Lease
(Shard)
Lease
(Shard)
Sharder
Lease
(Shard)
obj1
obj2
obj3
obj4
obj4
obj5
obj6
obj7
<Leader>
Lease
(Shard)
Lease
(Shard)
Lease
(Shard)
Sharder
Lease
(Shard)
obj1
obj2
obj3
obj4
obj4
obj5
obj6
obj7
<Leader>
Consistent Hashing
Shardの追加削除に対して
Shard間のオブジェクトの移動が
少なくできる
24
@everpeace
オブジェクトの割当
kind: MyKind
metadata:
name: obj1
labels:
shard: shard-a
kind: MyKind
metadata:
name: obj2
labels:
shard: shard-a
Sharder
Controller
(shard-a)
Watch&Reconcile
Label
Lease
(shard-a)
Sharder
obj1
<Leader>
obj2
SharderがLabelでShardを割当
shard labelの値はたかだか1つ➔重複割当が起きない
25
@everpeace
オブジェクトの割当
kind: MyKind
metadata:
name: obj1
labels:
shard: shard-a
kind: MyKind
metadata:
name: obj2
labels:
shard: shard-a
Sharder
Controller
(shard-a)
Watch&Reconcile
Label
Lease
(shard-a)
Sharder
obj1
<Leader>
obj2
SharderがLabelでShardを割当
shard labelの値はたかだか1つ重複割当が起きない
!!!ただしshard間の移動には注意!!!
旧shardと新shardが同時に
reconcileするのを防ぐ必要があります
(Sharderは旧shardでのreconcileが
停止されたことを知る必要がある)
26
@everpeace
並行Reconcileの防止
Shard間の移動(Scale-Out時)
Drainラベルを使う
shard-a PodのReconcile停止を確実
に確認してからshard-bへの割当る
ことで並行Reconcileが防げる
labels:
shard: shard-a
drain: true
labels: { }
labels:
shard: shard-b
Sharder
Controller
(shard-a)
Sharder
②
③
④
Health icons created by Freepik - Flaticon
Shard間の移動(Scale-In時)
labels:
shard: shard-a
labels:
shard: shard-b
Controller
(shard-a)
Sharder
②
Lease
(shard-a)
①
直接shardラベルを書き換え
shard-a Leaseがexpireする
➔Podがもう居ない➔Reconcile起きない
➔直接書き換えてOK
Lease
(shard-b)
①
27
@everpeace
controller-runtime(Forked)でのsharding対応
mgr, err := manager.New(restConfig, manager.Options{
Sharded: true, // enable sharding for this manager
ShardID: "", // ShardID (default to Pod name)
ShardMode: sharding.ModeBoth, // Run Shard and Sharder(default)
})
① ManagerはOptionを指定
controller, err := builder.ControllerManagedBy(mgr).
For(&webhostingv1alpha1.Website{}, builder.Sharded{}).
Owns(&appsv1.Deployment{}, builder.Sharded{}).
Watches(...).
Build(reconciler)
② Reconcilerは普通に書いてbuilderでSharded optionを指定
これだけで
自Shard用のCache
Sharderが起動します
これだけで自Shard用の
Controller起動します
(Shard移動処理は自動)
28
@everpeace
controller-runtime(Forked)でのsharding対応
Watch()
For()
Own()
reconcile queue
...
Sharded
Reconciler
Sharded
Reconciler
Sharded
Reconciler
Informer
eventqueue
Cache
Reconciler
Reconciler
Reconciler
shard:<shard_id>な
labelSelectorが付く
Predicateに
shard:<shard_id>
が付与される
担当ShardのRequestだけを
User Reconcilerに渡してくれる
(drain処理もやってくれます)
※ この他にもSharder with LeaderElectionの起動、Shard Lease用のLeaderElection、metrics recorder等
が追加されます
29
@everpeace
controller-runtime(Forked)でのsharding対応
出典: "Towards Horizontally Scalable Kubernetes Controllers," Tim Ebert
Observabilityも
バッチリ対応🎉
30
Scale-Outする
Kubernetes Controllerが
出来た🎉
HorizontalPodAutoScalerと
組み合わせるとかもできそう💡
31
Control Planeってそんなに
Scale-Outできたっけ?🤔
32
@everpeace
Kubernetes自体のScalability限界に注意
● Considerations for large clusters | Kubernetes に上限値の明記あり
○ No more than 110 pods per node
○ No more than 5000 nodes
○ No more than 150000 total pods
○ No more than 300000 total containers
● etcd 自体がすべての書き込みは直列処理する
➔ つまり更新はScale-Outしない
(--etcd-servers-overridesでgroup/resource単位でetcd更新負荷をOffload/分離可)
➔ せっかくController Scale-Outしても意味ない!?😇
eventだけ別etcd
とか見かけますよね
33
@everpeace
ControllerをShardingして嬉しいときって?
● Control Plane(etcd)は余裕があるけど
ControllerをScale-Upしても詰まる場合
● 例えば
○ 外部のAPI/DB等に依存していて1回のReconcileに時間がかかる場合
➔ リソースが多いとすぐにControllerだけが詰まる場合
○ Reconcile対象リソースの更新頻度が高い時
➔ リソース数が多くてScale-Upの限界が来た時
(最近のサーバは多コアで高速なのでこちらはかなりレアかも)
34
@everpeace
タレコミ情報
https://twitter.com/timebertt/status/1593500057856352257
KubeConEU 2023へのSubmissionに
ControllerのSharding
が含まれているそうです!!
35
@everpeace
● Kubernetes Controllerの基本的なアーキテクチャはScale-Upのみ
● ControllerにShardingを適用したScale-Outなアーキテクチャが
提案&検証はされています
○ controller-runtimeのForkでのみサポートされている
○ client-goでのサポートはない
● ただしKubernetes自体のScale Limitには注意が必要
● Reconcile自体に時間がかかるようなControllerの場合は効果ありそう
まとめ
まだまだ検証
の域を出ないけど
今後が楽しみ!!
36
@everpeace
We're Hiring!!
機械学習プラットフォームエンジニア (Infrastructure)
● こんな環境にワクワクする方を募集しています!
○ 日進月歩で進化している機械学習にフォーカスした計算技術を低レイヤーから高レイヤー
までトータルに吸収できる
○ 大規模機械学習クラスタの開発・運用が経験できる
○ Kubernetesを始めとするOSSコミュニティでも活躍できるチャンスがある
○ HPCとCloud Nativeの境界領域という今後ますます重要になる分野の経験ができる
○ 多様な要求・ユーザーリテラシをサポートするプラットフォーム設計・実装を経験できる

Kubernetes ControllerをScale-Outさせる方法 / Kubernetes Meetup Tokyo #55