Weitere ähnliche Inhalte Ähnlich wie Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster (20) Mehr von Preferred Networks (20) Kürzlich hochgeladen (10) Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster1. Shingo Omura (@everpeace), Preferred Networks, Inc.
Kubernetes Meetup Tokyo #13 2018-09-28
schedulerとdevice-pluginをカスタムし
て機械学習ジョブクラスタを
作っている話
1
2. 大村伸吾 (おおむらしんご)
• エンジニア, Preferred Networks, Inc.
• 社内向けGPUクラスタの開発運用
• Chainerのクラウドでのユーザビリティ向上
• kubeflow/chainer-operator 開発
– ChainerMNによる分散深層学習も
single yamlで動きます
– 仲間募集中!
– v0.3(今月末予定)で正式リリース!
• @everpeace (twitter)
• shingo.omura (facebook)
2
We’re Hiring!!
6. PFN における Kubernetes クラスタ
credits:
gpu by Misha Petrishchev, Cpu Chip by Vectors Market, Memory by Jugalbandi, Network Switch by Creaticca Creative Agency,
Webhooks by Paul Dietzel, label by nauraicon, schedule by Pixel Lab from the Noun Project
128 (P100)
512 (V100)
56 Gbps x 2
100 Gbps x 24608 vCore
192 vCore
24 TiB
4 TiB
64 nodes (MN-1b)
16 nodes (MN-1a) (全体では128 node)
v1.11.1
NVIDIA/k8s-device-plugin
everpeace/k8s-host-device-plugin
custom
admission
webhook
custom
node feature
discovery
custom
kube
-scheduler
6
日々絶賛拡張中
InfiniBand
7. • 息を吸うように分散機械学習
– ChainerMN ➔ GPU, InfiniBand をスケジュールしたい
• 日常的なグランドチャレンジ
– Preemptionを活用したい
• オンプレなのでキャパは有限
– Preemptionを活用したい(長時間のジョブは優先度低)
– Preemptionが起きないようにパッキング
• 未対応だが将来やりたい
– スケジューリングの改善(100人以上で使うので何らかの公平性を)
– ギャングスケジューリング(複数のpodを同時にschedule)
PFN の Kubernetes クラスタに求められるもの
7
クラスタ全体を専有して
ブレイクスルーを目指す実験
8. • 息を吸うように分散機械学習
– ChainerMN ➔ GPU, InfiniBand をスケジュールしたい
• 日常的なグランドチャレンジ
– Preemption を 活用したい
• オンプレなのでキャパは有限
– Preemptionを活用したい & カスタムPreemptionロジック
– Preemptionが起きにくいようにパッキング
• 未対応だが将来やりたい
– スケジューリングの改善(100人以上で使うので何らかの公平性を)
– ギャングスケジューリング(複数のpodを同時にschedule)
customized kube-schedulercustomized kube-scheduler
カスタムしているコンポーネント
custom device plugin
8
PriorityClass
10. Kubernetes Device Pluginとは
• 本体を変更せずに計算リソースを
kubeletにadvertiseする仕組み
– Extended Resourceと呼ばれる
– 非特権コンテナでデバイス利用可
• v1.8 で 登場
• 現 api バージョンは v1beta1
• 通常DeamonSetでデプロイ
• GPU以外にもある(公式ドキュメント)
– GPU (Nvidia, AMD, Intel),
FPGA (Intel), RDMA devices, etc.
# your container spec
resources:
limits:
my-special-device: 1
こんな風にできるようになる
# kubectl describe nodes
Allocatable:
my-special-device: 15
10
11. Kubernetes Device Plugin の制約
• 整数単位のみでの指定
– 0.5 とかは駄目
• overcommit できない
– 要 requests == limits
• コンテナ同士でシェアはできない
• unlimited リソース は 未対応
– capabilityっぽいリソース
– dirty hack あり (後述)
# your container A
resources:
requests:
nvidia.com/gpu: 1
limits:
nvidia.com/gpu: 1
# your container B
resources:
limits:
nvidia.com/gpu: 1
別々のGPU
要同値&整数
11
12. ● gRPC on unix socket で通信
● device id や deviceファイル情報 をやり取り
● kubelet は起動時に --device, -v オプションを
つけてコンテナを起動
Kubernetes Device Plugin 動作概要
12
/dev/my0 /dev/my1 /dev/my2 /dev/my3
device-plugin
Pod
/dev/my0, 1
--device, -v, --env
等のoption付きで起動
kubelet
13. Kubernetes Device Plugin の 動作概要
• design doc, api定義(v1beta1) が詳しい
kubelet device plugin
gRPC API
Action
Register
ListAndWatch
Container起動前
Register
ListAndWatch
Allocate
PreStartContainer
kubelet.sock
hoge.sock
unix socket
主に
Register処理
と
2つのAPI
を実装する
13
14. Kubernetes Device Plugin: Register
kubelet device plugin gRPC API
Action
Register Registerkubelet.sock
unix socket
# rpc Register (RegisterRequest) returns (Empty) {}
RegisterRequest {
version = “v1beta1”
endpoint = “/var/lib/kubelet/device-plugin/hoge.socket” ← pluginのsocket名
resource = “my-device-name” ← デバイス名
options = DevicePluginOptions {
pre_start_required = true ← Allocate 後に PreStartContainer を呼んでほしいか
}
}
問題があればエラー
が返る
14
15. Kubernetes Device Plugin: ListAndWatch
kubelet device plugin
gRPC API
Action
ListAndWatch ListAndWatchhoge.sock
unix socket
デバイスリストを
更新し続ける
# rpc ListAndWatch (Empty) returns (stream ListAndWatchResponse) {}
# デバイスの状態が変わったら速やかに全デバイスのリストを再送信
ListAndWatchResponse {
devices = [ Device {
ID = “GPU-fef8089b-4820-abfc-e83e-94318197576e” ← デバイスのID
health = “Healthy” ← Healthy or Unhealthy
}, ... ]
}
15
16. Kubernetes Device Plugin: Allocate
kubelet device plugin gRPC API
Action
Container起動前 Allocatehoge.sock unix socket
デバイスを要求
# rpc Allocate (AllocateRequest) returns (AllocateResponse)
AllocateRequest {
container_requests = [
ContainerAllocateRequest {
deviceIDs = [ “GPU-...”, “GPU-...” ] ← 各コンテナに割り当てたいIDのリスト
} ]
}
16
17. Kubernetes Device Plugin: Allocate
# rpc Allocate (AllocateRequest) returns (AllocateResponse)
AllocateResponse { container_responses = [
ContainerAllocateResponse {
envs = map( “env_name”: “env_value” ) ← 環境変数
mounts= [ Mount { ← ホストボリュームマウント指定(-v)
host_path = “...”
mount_path = “...”
read_only = true/false
} ]
devices = [ DeviceSpec { ← ホストデバイスマウント指定(--device)
container_path = “/dev/foo”
host_path = “/dev/bar”
permissions = r / w / m ← r = read, w = write, m = mknod 権限
} ]
annotations = map( “key”: “value” ) ← コンテナアノテーション
},
]} 17
18. Kubernetes Device Plugin: PreStartContainer
kubelet device plugin gRPC API
Action
Container起動前 PreStartContainerhoge.sock unix socket
# rpc PreStartContainer (PreStartContainerRequest) returns (PreStartContainerResponse) {}
PreStartContainerRequest {
devicesIDs = [ “GPU-...”, “GPU-...” ] ← 初期化等の前処理をするデバイスIDs
}
PreStartContainerResponse { } ← レスポンスは中身なし
pre_start_required = true
の場合のみ呼ばれる
18
19. InfiniBand 用に Unlimited な Extended Resource を擬似的に作る
Pod
PFN における 自作device plugin (everpeace/k8s-host-device-plugin)
19
everpeace/k8s-host-device-plugin
/dev/infiniband/uverbsX
kubelet
/dev/infiniband/uverbsX
/dev/infiniband/rdma_cm
/dev/infiniband/rdma_cm ● 特定のdeviceファイルの集合 に 大量 のdummy
device IDをつける
● Allocate ではどの ID をリクエストされても
同じDeviceSpecを返す
20. まだまだ発展途上なので注意が必要
• KEP や issueがたくさんあって今後大きく変わる可能性あるかも
– KEP-14: New Resource API proposal (kubernetes/community#2265)
• ResourceClass の提案 (Volume Classみたいな)
• GPUモデルをLabels/Taintsで管理するんじゃなくてもっとちゃんと
– KEP-18: Compute Device Assignment (kubernetes/community#2454)
• ComputeDevice と ComputeDeviceBind 使ってdevice の bindを表現
• kubeletが保存しているlocal checkpoint(containerとdevice IDの対応)からの脱却
– specify hw devices in container (kubernetes/kubernetes#60748)
• Container Spec に hostDevices attributeを追加
20
22. • PodをNodeに割り当てる 責務を担うControl Plane のコンポーネント
• kube-schedulerの動作は この2つを読めばほぼ完璧 です
– @tkusumi さんの “Kubernetes: スケジューラの動作”
– チェシャ猫(@y_taka_23) さんの "猫でもわかるPod Preemption"
• 特徴
– schedule policy を 柔軟 にカスタマイズ
• toleration, nodeSelector, affinity といった機能はココ
– priority による preemption
– Extender (Webhook) による拡張
kube-schedulerとは
22
24. Pod Queue (FIFO)
kube-schedulerの動作
24
Pod を 1個 Pop
対象ノードを選ぶ
ノードに紐づけ
プリエンプション
(犠牲になるPod群を停止)
kube-api
Policy 及び Extender
でカスタム可能
Extender
でカスタム可能
Extender
でカスタム可能
対象ノードがない
Bind リソース を作成
犠牲Pod群をDelete
PodをWatch
26. 26出展: Kubernetes: スケジューラの動作 - Qiita by tkusumi
kube-schedulerの動作: ノードを選ぶ
● Policyで選べる
● Extenderで独自Predicates
● Policyで選べる
● Extenderで独自ロジック挿せる
27. kube-schedulerの動作: プリエンプション
27
Node 1
Node 2
Node 3
Node 4
候補ノードを選ぶ
● クリティカルな
FitError以外の
ノード
● 低優先度Podがい
るノード
Node 2
Node 3
Node 4
犠牲Node&Podを選ぶ
1. 低優先Pod全部犠牲候補にして
(抜いてみて) fit するかチェック
2. pdb違反を高優先度から順に
fitする限り救済
3. 残りも高優先度から順にfitする
限り救済
4. 残りを犠牲Podsとする
Node 2
Node 3
Extenderによる調整
● 選ばれたノードと犠牲
Podsを受け取って調
整できる
● Victimを完全に選ぶ
ことはできない
Node 2
Nodeを1つに絞る
下記の順にNodeを絞る
1. PDB違反数最小
2. 最高優先度最小
3. 優先度和最小
4. 犠牲pod数最小
5. ランダム!
28. kube-scheduler のカスタマイズ方法
• 残念ながらほとんどdocumentはない(記事は幾つか存在する )
• コマンドラインオプションは公式ドキュメント に載っている
– --config でファイルを渡す形式(--write-config-toでdefault書出し可)
– 設定は下記を見ながらyaml, jsonを書くしか無い
• kube-scheduler 自体の設定
→ KubeSchedulerConfiguration (yaml サンプル)
• スケジューリングポリシー(predicates, priorities, extenders, etc.)
→ Policy (json サンプル)
• Extender: ドキュメント(design-doc)
– サンプル: everpeace/k8s-scheduler-extender-example
• 自分で自由にpredicate, priority, preempt, bind等のロジックを
webhookで挿せる
– 応用: everpeace/kube-throttler: Throttle CRDを使ってpodのスケジュールをthrottle
28
29. PFNでのカスタム事例
• 寄せて詰めたい (= Greedy な Bin Packing)
– podがfitする中で一番空きが少ないところに入れる
– MostRequestedPriority を使う
• Victim を 自由に選びたい
– kube-schedulerが Vicitim Pod を選び、Extenderは調整しか
できないので
– やむなくforkして実装している(諸事情で現在未デプロイ)
• 新バージョンが来たときのrebaseが辛い
• Extenderでもうちょっと柔軟にできるようにしてほしい
29
31. Kubernetes の Scheduler もまだまだ発展途上
• kube-scheduler がものすごく多くのデフォルト機能を実装していて
自作のスケジューラが同じ機能を実装するのが困難なのが実情
• kubernetes-incubator/kube-arbitrator (←やりたいことに近いかも )
– HPC系のスケジューラの機能の実現
– JobQueue, Gang Scheduling, Preemption に対応している
– まだまだ絶賛開発中な模様
• 幾つかのスケジューラ系のKEPも存在
– Add scheduling framework design proposal (kubernetes/community#2281)
• よりカスタマイズできるように schedulerをframework化
– KEP: Gang scheduling (kubernetes/community#2337)
• PodGroup というresourceを導入してGroup単位でschedule
31
33. Icons made by Vincent Le Moign from https://icon-icons.com/ licensed by CC 3.0 BY
Thank you for Listening!!
Any Questions?
33
36. MN-1a 構成
36
Total: 1024 GPUs (NVIDIA Tesla P100)
8 GPUs x 16 Servers
56 Gps(InfiniBand FDR) x 2
56 Gbps(InfiniBand FDR) x 2
credits:
gpu by Misha Petrishchev from the Noun Project
Network Switch by Creaticca Creative Agency from the Noun Project
37. MN-1b 構成
37
8 GPUs x 16 Servers
100 Gps(InfiniBand EDR) x 2
100 Gbps(InfiniBand EDR) x 2
credits:
gpu by Misha Petrishchev from the Noun Project
Network Switch by Creaticca Creative Agency from the Noun Project
MN-1a
Total: 512 GPUs (NVIDIA Tesla V100)