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

kubernetesでGPUを 管理するために スケジューラをいじってみた

uesyn
September 17, 2018

kubernetesでGPUを 管理するために スケジューラをいじってみた

uesyn

September 17, 2018
Tweet

More Decks by uesyn

Other Decks in Technology

Transcript

  1. kubernetesでGPUを
    管理するために
    スケジューラをいじってみた

    View Slide

  2. ● 名前:上村 真也(@uesyn)
    ● 所属:KDDI株式会社
    ● 主な業務内容
    ○ 新しいサーバインフラ基盤の検証 (NFV向け/コンテナ/GPU)
    ○ NFV人材育成講師
    ● 趣味
    ○ ゲーム(特にFPS)
    自己紹介
    Gopher君

    View Slide

  3. 皆さん
    kubernetes
    使ってますか?

    View Slide

  4. それでは本題

    View Slide

  5. 背景〜ある会社の研究所のお話〜
    ● 研究者がGPUを欲しがる
    ● GPUを割り当てたリソースをユーザに提供(手動)
    GPUを1つください
    研究者 研究者 兼 研究所インフラ担当者
    はい、どうぞ
    社内の
    GPU搭載サーバ群

    View Slide

  6. Problems
    丹精込めた愛情たっぷり手作り GPUリソース
    ● 管理者がボトルネックとなり払い出しに時間がかかる
    社内で利用するGPUリソースを共通化できていない
    ● 規模の経済が働かない
    パブリッククラウドの GPUリソースを利用できない
    ● 社外に出せないデータの存在
    ● 必然的に社内基盤が必要
    共通GPU演算基盤が必要!!!

    View Slide

  7. Can we solve them
    with kubernetes?
    7

    View Slide

  8. GPUをkubernetesで管理する
    検証環境を作ってみました!

    View Slide

  9. kubernetes
    Master
    GPU Servers CPU Servers
    Ingress Controller(ユーザごとに分離)
    ストレージ
    Kubernetesのワーカーノード
    GPUを使わない処理用
    実際に作った環境の構成

    View Slide

  10. 基板上に作ったサンプルアプリ
    アプリについて
    ● 動画上の物体検出
    ● アップロードされた動画を
    リアルタイム処理
    ・解析するワーカーをいつでも増減可能
      ・GPUでもCPUでも解析可能

    View Slide

  11. やったこと
    1) GPUを使うコンテナのスケジューリング
    2) 1クラスタでマルチテナント環境な基盤
    ● GPU搭載ノードは共有
    ● GPU非搭載ノードは専有
    3) コンテナ基盤のセキュリティの検証
    ● スケジューラに関しては
    ドキュメントがない部分も。。。
    ● セキュリティは社内利用なので甘々に
    今日はここのお話

    View Slide

  12. kubernetesのGPUリソースの管理
    ● kubeletでは最小限のデバイスディスカバリのみサポート
    ○ CPUやメモリやディスク
    ○ GPUは標準で管理されない
    ● ベンダー固有のデバイスはExtended ResourceとDevice Pluginとで管理

    View Slide

  13. Extended ResourceとDevice Plugin
    Extended Resource
    ● Built-inされているリソース以外の数を表現
    ○ ResourceNameと数(integer)
    ○ 0.5個GPUが欲しいといった要求不可能
    ● コンテナ間の共有・オーバーコミット不可能
    Device Plugin
    ● ベンダー固有デバイスを kubeletへ通知
    ● デバイスをAllocateする情報をkubeletへ渡す
    ● kubernetesのコアコードをいじらず実装可能
    ● NVIDIAのGPUを扱うにはNVIDIA/k8s-device-plugin
    ○ https://github.com/NVIDIA/k8s-device-plugin

    View Slide

  14. Device Pluginについて
    ● Registry
    ○ Device Pluginをkubeletへ登録
    ○ 利用するExtended ResourceNameを通知
    ● ListAndWatch
    ○ 利用可能なデバイスをkubeletへ通知
    ● Allocate
    ○ コンテナ作成前にCRI-Specへ下記の値を挿入
    ■ 環境変数
    ■ マウント
    ■ デバイス
    ■ アノテーション
    出典:https://github.com/kubernetes/community/blob/master/contributors/
    design-proposals/resource-management/device-plugin.md

    View Slide

  15. NVIDIAのGPU用Device Pluginのコードを読んでみると・・・
    15
    NVIDIA/k8s-device-plugin
    ● NVIDIAのGPUをkubernetesで扱うためのDevice Plugin
    ● Allocateで実装されているのは 環境変数をコンテナ作成時に挿入するのみ
    https://github.com/NVIDIA/k8s-device-plugin/blob/v1.10/server.go

    View Slide

  16. Device PluginだけじゃGPUは使えない!
    NVIDIA container runtime
    ● コンテナでNVIDIAのGPUを利用できるようにしたものの総称
    ○ libnvidia-containerやツール等
    ● 特定の環境変数(NVIDIA_VISIBLE_DEVICES)が入っていればGPUを割り当て
    ● OCIで定義されるprestart hookでnvidia-container-runtime-hookを呼び出す
    ○ コイツがGPUをコンテナに割り当てる
    出典:https://devblogs.nvidia.com/wp-content/uploads/2018/05/pasted-image-0-27.png

    View Slide

  17. GPUを持ったコンテナの起動
    ● CPUやmemoryのようにrequests, limitsを指定して利用
    ● GPUの場合limitsのみで動作
    ○ limitsのみを指定した場合requestsも同じ値になる
    ○ requestsを書く場合limitsも同じ値を指定する必要

    View Slide

  18. GPUコンテナのスケジューリングの課題
    実際に発生した状況
    ● GPUを2つ搭載するノードが2台ある
    ● 以下の順番でPodを起動
    1. GPUを1つ使うPod① → ○
    2. GPUを1つ使うPod② → ○
    3. GPUを2つ使うPod③ → X
    ● でも2つのGPU空きリソースが存在
    ノード1 ノード2
    Pod①
    Pod③
    Pod②

    View Slide

  19. GPUコンテナのスケジューリングの課題
    理想としては・・・
    ● リソース効率を考えると GPUは使用率が高くなるように 埋まってくれると嬉しい
    ノード1 ノード2
    Pod③
    Pod②
    Pod①

    View Slide

  20. スケジューリングを実施するコンポーネント
    kube-apiserver
    kube-scheduler kube-controller-manager
    kubelet
    kube-proxy
    これがスケジューリングする
    マスター側 ノード側

    View Slide

  21. スケジューラの設定を変えれば
    いけるんじゃないか?

    View Slide

  22. kubernetesのスケジューリング
    ● kube-schedulerがPodをスケジューリング
    ○ Predicates
    ■ Podを配置可能なノードを通すフィルタ
    ○ Priorities
    ■ Podが配置できるノードの中で最適なノードを決定
    ノード A
    ノード B
    ノード C
    ノード A
    ノード B
    Predicates
    (フィルタ)
    ノード C
    Priorities
    (ランキング付け)
    ノード A
    ノード B
    この設定を変更すれば…?

    View Slide

  23. Prioritiesのざっくりとした仕組み
    PriorityC
    のスコア
    PriorityA
    のスコア
    PriorityB
    のスコア
    重み
    重み 合計がノードのスコア
    Priorities
    ● いくつかのPriorityを付ける処理の組み合わせで構成
    ○ 例:
    ■ LeastRequestedPriority: PodのリソースのRequest合計が少ないノード優先
    ■ BalancedResourcePriority: CPUとメモリの使用率のバランスをとるように
    重み

    View Slide

  24. 使えそうなPriorityを探してみた(1/2)
    ● pkg/scheduler/algorithm/prioritiesの中で使えそうなPriorityはないか?
    ○ ImageLocalityPriority
    ○ InterPodAffinityPriority
    ○ NodeAffinityPriority
    ○ NodeLabelPriority
    ○ NodePreferAvoidPodsPriority
    ○ ResourceLimitsPriority
    ○ SelectorSpreadPriority
    ○ TaintTolerationPriority
    ○ LeastRequestedPriority
    ○ BalancedResourcePriority
    ○ MostRequestedPriority
    ● 漏れがあったらごめんなさい
    使えそう?

    View Slide

  25. ● CPUとメモリの使用率が高いノードを優先的にコンテナを起動する設定は存在
    ● GPU(Extended Resource)は対象外
    https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/algorithm/priorities/most_requested.go
    使えそうなPriorityを探してみた(2/2)

    View Slide

  26. なら、スケジューラを拡張
    するしかない!

    View Slide

  27. kubernetesのschedulerの拡張方法
    1. kube-schedulerに手を加えて、既存のものと置き換える
    ● 基盤をVerUPするたびに手を加える必要があり
    2. Multiple-scheduler
    ● 実はkubernetesでは複数のスケジューラを起動可能
    ■ 実際に使うスケジューラはどれか一つ
    ■ 既存のものと拡張したものを配置すれば
    ● PodのSpecにスケジューラを指定
    ● ユーザ側の操作が不可欠なため、好ましい方法ではない
    3. Scheduler extender
    ● kube-schedulerが呼び出す外部APIとして実装される
    今回はこれを採用

    View Slide

  28. Scheduler extenderの作り方
    Scheduler extenderを利用したスケジューリング
    kube-scheduler
    Predicates
    kube-scheduler
    Priorities
    ノード A
    ノード B
    ノード scheduler-extender
    Predicates
    scheduler-extender
    Priorities
    ● 標準のkube-schedulerで管理されていないリソースのスケジューリングのために必要だと書いてあった
    出典:https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md

    View Slide

  29. Scheduler Extenderをこんな感じで作ろう
    ノード1 ノード2
    ● GPUの専有枚数の多いほどがスコアが高くなるように
    ○ Priorityのみ実装
    ● スコア =  ( リクエストGPU数 + ノード上の専有されている GPU数) / ノードが持ってるGPU数 * 10
    ○ Maxが10になるように正規化
    ■ Priorityのルール
    Pod①
    GPUを1つください
    スコア = (1+1) / 2 * 10 = 10 スコア = (1+0) / 2 * 10= 5

    View Slide

  30. Scheduler extenderの実装
    ● ↓こんなリクエストがくるので
    https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/types.go

    View Slide

  31. Scheduler extenderの実装
    ● ↑こんなリプライを返してあげる
    https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/types.go
    https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/types.go

    View Slide

  32. 実装していい感じに動きました!

    View Slide

  33. Scheduler Extenderが動作していない時の挙動
    https://github.com/kubernetes/kubernetes/blob/release-1.11/pkg/scheduler/api/v1/types.go
    ● v1.10
    ○ Ignorableがtrueの挙動
    ● v1.11
    ○ Configで設定可

    View Slide

  34. Scheduler Extenderが動作していない時の挙動
    https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/v1/types.go

    View Slide

  35. GPU何枚使ってるかどうやって調べるの?
    ~ノード単位で見る場合①~
    ● とりあえずkubectl describe node (Client v1.10)
    何枚使ってるかわからん!

    View Slide

  36. GPU何枚使ってるかどうやって調べるの?
    ~ノード単位で見る場合②~
    ● とりあえずkubectl describe node (Client v1.11)
    ○ 1.11からExtended ResourceのAllocated resoucesも見れるように!

    View Slide

  37. GPU何枚使ってるかどうやって調べるの?
    ~クラスタ全体で見る場合~
    ● kube-state-metricを使う
    ○ v1.4.0からExtended Resourceもmetricsとして収集可能に!
    https://github.com/kubernetes/kube-state-metrics/pull/451

    View Slide

  38. おわり

    View Slide