そのコンテナ、もっと「賢く」置けますよ? #CNDT2019 / CloudNative Days Tokyo 2019

そのコンテナ、もっと「賢く」置けますよ? #CNDT2019 / CloudNative Days Tokyo 2019

CloudNative Days Tokyo 2019 で使用したスライドです。

Kubernetes は既にコンテナオーケストレータのデファクトを獲得し、多種多様なアプリケーションがデプロイされるプラットフォームとなりました。この流れの中で、従来の機能ではカバーできない複雑なコンテナ配置ロジックや、リソース集積率の最適化に対する需要も高まっています。本講演では、カスタマイズの手法から次世代の特殊スケジューラまで、Kubernetes におけるコンテナ配置のすべてをお話しします。

イベント概要:https://cloudnativedays.jp/cndt2019/
ブログ記事:https://ccvanishing.hateblo.jp/entry/2019/07/30/112634
録画:https://www.youtube.com/watch?v=EsZLJT5uQ5E

332f89cc697355902a817506b6995f2b?s=128

y_taka_23

July 23, 2019
Tweet

Transcript

  1. #CNDT2019 #RoomG #CNDT2019 #RoomG そのコンテナ、 もっと「賢く」置けますよ? チェシャ猫 (@y_taka_23) CloudNative Days

    Tokyo 2019 (2019/07/23)
  2. #CNDT2019 #RoomG

  3. #CNDT2019 #RoomG $ kubectl apply -f my-deployment.yaml deployment.apps/myapp created $

    kubectl get pods -o wide NAME READY STATUS RESTARTS AGE NODE myapp-6dd86d77d-vweg2 1/1 Running 0 52s node-03 myapp-6dd86d77d-wt34h 1/1 Running 0 52s node-01 myapp-6dd86d77d-r4pag 1/1 Running 0 52s node-02
  4. #CNDT2019 #RoomG $ kubectl apply -f my-deployment.yaml deployment.apps/myapp created $

    kubectl get pods -o wide NAME READY STATUS RESTARTS AGE NODE myapp-6dd86d77d-vweg2 1/1 Running 0 52s node-03 myapp-6dd86d77d-wt34h 1/1 Running 0 52s node-01 myapp-6dd86d77d-r4pag 1/1 Running 0 52s node-02 配置される Node が勝手に決まる
  5. #CNDT2019 #RoomG #CNDT2019 #RoomG スケジューリング クラスタ上の Pod 配置をコントロールすること

  6. #CNDT2019 #RoomG 本日のアジェンダ • スケジューラのアーキテクチャ • フィードバックとリソース効率 • 広がるスケジューラの世界

  7. #CNDT2019 #RoomG #CNDT2019 #RoomG スケジューラのアーキテクチャ How the Scheduler Effectively Works?

  8. #CNDT2019 #RoomG ユーザが kubectl コマンドで Deployment を作成 Node 上で Pod

    が起動
  9. #CNDT2019 #RoomG ユーザが kubectl コマンドで Deployment を作成 Node 上で Pod

    が起動 この間、何が起こっているのか? ?
  10. #CNDT2019 #RoomG Scheduler Controller Manager API Server Kubelet Kubelet Kubelet

    User
  11. #CNDT2019 #RoomG ユーザが kubectl コマンドで Deployment を作成 Contoller Manager が

    Deplyment から ReplicaSet を作成 Controller Manager が ReplicaSet から Pod を作成 Scheduler が Pod を配置する Node を選択 Node 上の Kubelet が自分に割り当てられた Pod を起動
  12. #CNDT2019 #RoomG ユーザが kubectl コマンドで Deployment を作成 Contoller Manager が

    Deplyment から ReplicaSet を作成 Controller Manager が ReplicaSet から Pod を作成 Scheduler が Pod を配置する Node を選択 Node 上の Kubelet が自分に割り当てられた Pod を起動
  13. #CNDT2019 #RoomG User

  14. #CNDT2019 #RoomG Queue Scheduling Cycle Binding Threads

  15. #CNDT2019 #RoomG Queue API Server から行き先未定の Pod を取り出してキューに格納

  16. #CNDT2019 #RoomG : node-02 : node-01 : node-03 Scheduling Cycle

    Pod の行き先 Node を “ひとつずつ” 確定 スケジューラの心臓部分
  17. #CNDT2019 #RoomG Binding Threads Pod ごとに goroutine を生成して 行き先となる Node

    を API Server に登録
  18. #CNDT2019 #RoomG Queue Scheduling Cycle Binding Threads

  19. #CNDT2019 #RoomG Dequeue Filtering Scoring Node が未定の Pod を一つ選択 Pod

    の条件に合わない Node を除外する 残った Node から ベストを選ぶ Scheduling Cycle
  20. #CNDT2019 #RoomG Dequeue Filtering Scoring Node が未定の Pod を一つ選択 Pod

    の条件に合わない Node を除外する 残った Node から ベストを選ぶ Scheduling Cycle
  21. #CNDT2019 #RoomG Dequeue Filtering Scoring Node が未定の Pod を一つ選択 Pod

    の条件に合わない Node を除外する 残った Node から ベストを選ぶ Scheduling Cycle
  22. #CNDT2019 #RoomG Dequeue Filtering Scoring Node が未定の Pod を一つ選択 Pod

    の条件に合わない Node を除外する 残った Node から ベストを選ぶ Scheduling Cycle
  23. #CNDT2019 #RoomG スケジューラの基本動作 • Pod と Node の紐付けのみを担当 ◦ 自分自身が

    Pod を作成するわけではない • Pod ひとつずつに対し以下を繰り返す ◦ キューから配置 Node が未定の Pod を取り出す ◦ Pod の条件から Node の候補を絞る ◦ 残った中からさらに最適な Node を選択する
  24. #CNDT2019 #RoomG #CNDT2019 #RoomG なるほどわからん。 もうちょっと具体的に言って? ?

  25. #CNDT2019 #RoomG apiVersion: v1 kind: Pod metadata: name: my-app spec:

    containers: - name: my-app image: username/my-app:latest resources: requests: memory: 2Gi cpu: 200m Mem : 2 GiB CPU : 0.2 core
  26. #CNDT2019 #RoomG apiVersion: v1 kind: Pod metadata: name: my-app spec:

    containers: - name: my-app image: username/my-app:latest resources: requests: memory: 2Gi cpu: 200m Mem : 2 GiB CPU : 0.2 core メモリ 2 GiB と CPU 200 mcore 確保できる Node に配置してくれ
  27. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Mem : 4 MiB CPU : 0.2 core Mem : 3 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 / 8 GiB CPU : 0.4 / 2 core Mem : 2 GiB CPU : 0.2 core
  28. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Mem : 4 MiB CPU : 0.2 core Mem : 3 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 / 8 GiB CPU : 0.4 / 2 core Mem : 2 GiB CPU : 0.2 core Mem 不足で除外 Pod の条件に合わない Node を除外する
  29. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Mem : 4 MiB CPU : 0.2 core Mem : 3 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 / 8 GiB CPU : 0.4 / 2 core Mem : 2 GiB CPU : 0.2 core 残った Node の中から ベストを選ぶ より余裕がある
  30. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Mem : 4 MiB CPU : 0.2 core Mem : 3 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.6 / 2 core Mem : 2 GiB CPU : 0.2 core
  31. #CNDT2019 #RoomG #CNDT2019 #RoomG でも一口に Pod って言っても 実は「二種類」あるよね? ?

  32. #CNDT2019 #RoomG • 主に Deployment で管理 • 長時間、稼働し続ける • できるだけ散らしたい

    Server 系の Pod S S S S
  33. #CNDT2019 #RoomG • 主に Job で管理 • 短期間で終了する • できるだけ詰め込みたい

    Batch 系の Pod B B B B
  34. #CNDT2019 #RoomG スケジューラの設定 • スケジューラ起動時に --config フラグを指定 ◦ 冗長化などの設定も含まれる ◦

    さらに ConfigMap 化しておいた Policy を参照 • Policy は用意された項目を組み合わせる ◦ Node を Filtering する条件 ◦ Scoring の順位付け関数と重み付け
  35. #CNDT2019 #RoomG Dequeue Filtering Scoring Node が未定の Pod を一つ選択 Pod

    の条件に合わない Node を除外する 残った Node から ベストを選ぶ Scheduling Cycle
  36. #CNDT2019 #RoomG apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration leaderElection: leaderElect: false algorithmSource:

    policy: configMap: namespace: kube-system name: my-scheduler-policy
  37. #CNDT2019 #RoomG apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration leaderElection: leaderElect: false algorithmSource:

    policy: configMap: namespace: kube-system name: my-scheduler-policy Policy を記述した ConfigMap
  38. #CNDT2019 #RoomG { "kind": "Policy", "apiVersion": "v1", "predicates": [ {"name":

    "PodFitsHostPorts"}, {"name": "PodFitsHostResources"}, ... ], "priorities": [ {"name": "LeastRequestedPriority", "weight": 1}, {"name": "ServiceSpreadingPriority", "weight": 1}, ... ] } policy.cfg
  39. #CNDT2019 #RoomG { "kind": "Policy", "apiVersion": "v1", "predicates": [ {"name":

    "PodFitsHostPorts"}, {"name": "PodFitsHostResources"}, ... ], "priorities": [ {"name": "LeastRequestedPriority", "weight": 1}, {"name": "ServiceSpreadingPriority", "weight": 1}, ... ] } 確保済みリソースが少ない Node を優先 = 散らす配置戦略 policy.cfg
  40. #CNDT2019 #RoomG { "kind": "Policy", "apiVersion": "v1", "predicates": [ {"name":

    "PodFitsHostPorts"}, {"name": "PodFitsHostResources"}, ... ], "priorities": [ {"name": "MostRequestedPriority", "weight": 1}, {"name": "ServiceSpreadingPriority", "weight": 1}, ... ] } 確保済みリソースが多い Node を優先 = 詰め込む配置戦略 policy.cfg
  41. #CNDT2019 #RoomG #CNDT2019 #RoomG ひとつの Kubernetes クラスタには Server 系 or

    Batch 系のみ? ? マネージド Kubernetes なんですけど 起動時のフラグとは一体。。。 ?
  42. #CNDT2019 #RoomG #CNDT2019 #RoomG Kubernetes のクラスタ内には 複数のスケジューラが存在できるぞ! !

  43. #CNDT2019 #RoomG apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration schedulerName: my-scheduler leaderElection: leaderElect:

    false algorithmSource: policy: configMap: namespace: kube-system name: my-scheduler-policy スケジューラに名前を付けておく
  44. #CNDT2019 #RoomG apiVersion: v1 kind: Pod metadata: name: my-app spec:

    schedulerName: my-scheduler containers: - name: my-app image: username/my-app:latest resources: requests: memory: 500Mi cpu: 200m どのスケジューラの管理下にするかを指定
  45. #CNDT2019 #RoomG

  46. #CNDT2019 #RoomG

  47. #CNDT2019 #RoomG Section 2 のポイント • スケジューラは Pod を Node

    へ紐付ける ◦ Filtering で Node の候補を絞り、Scoring で順位付け • Policy によるスケジューリングの調整 ◦ あらかじめ定義されている項目の中から指定 • クラスタ内に複数のスケジューラが共存可能 ◦ Kubernetes の「舵輪型」アーキテクチャの恩恵
  48. #CNDT2019 #RoomG #CNDT2019 #RoomG フィードバックとリソース効率 More Adaptive Scheduling Scheme

  49. #CNDT2019 #RoomG Queue Scheduling Cycle Binding Threads 一方通行

  50. #CNDT2019 #RoomG #CNDT2019 #RoomG 今すぐ立てたい Pod がある。 Node 上の Pod

    が邪魔なんだけど? ?
  51. #CNDT2019 #RoomG • 主に Deployment で管理 • 長時間、稼働し続ける • できるだけ散らしたい

    • 今すぐ起動したい Server 系の Pod • 主に Job で管理 • 短期間で終了する • できるだけ詰め込みたい • 余裕がある時に起動 Batch 系の Pod
  52. #CNDT2019 #RoomG S Mem : 3 GiB CPU : 0.2

    core S Mem : 4 GiB CPU : 0.2 core B Mem : 1 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core S Mem : 4 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core B Mem : 2 GiB CPU : 0.2 core B Mem : 1 GiiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core S Mem : 6 GiB CPU : 0.2 core B Mem : 1 GiiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core S B Mem : 2 GiB CPU : 0.2 core
  53. #CNDT2019 #RoomG S Mem : 3 GiB CPU : 0.2

    core S Mem : 4 GiB CPU : 0.2 core B Mem : 1 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core S Mem : 4 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core B Mem : 2 GiB CPU : 0.2 core B Mem : 1 GiiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core S Mem : 6 GiB CPU : 0.2 core B Mem : 1 GiiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core S B Mem : 2 GiB CPU : 0.2 core
  54. #CNDT2019 #RoomG #CNDT2019 #RoomG Priority と Preemption を駆使して 邪魔な Pod

    を立ち退かせよう! !
  55. #CNDT2019 #RoomG Dequeue Filtering Node が未定の Pod を一つ選択 Pod の条件に合う

    Node が見つからない
  56. #CNDT2019 #RoomG Dequeue Filtering Node が未定の Pod を一つ選択 Pod の条件に合う

    Node が見つからない Preemption 自分より低優先度の Pod を追い出す
  57. #CNDT2019 #RoomG Priority と Preemption • Priority の指定 ◦ Scheduler

    のキューは優先度付きキューになる • Preemption ◦ Filtering で Node の候補が見つからなかった際に発動 ◦ 低優先度の Pod を強制的に追い出す ◦ できるだけ影響が小さくなる Node を選ぶ
  58. #CNDT2019 #RoomG apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: server value:

    10000 description: "The higher priority" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: batch value: 100 description: "The lower priority"
  59. #CNDT2019 #RoomG apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: server value:

    10000 description: "The higher priority" --- apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: batch value: 100 description: "The lower priority" 優先度:高 優先度:低
  60. #CNDT2019 #RoomG Preemption のアルゴリズム • まず低優先度の Pod をすべて消したと仮定 ◦ 余裕ができなければその時点で可能性なし

    ◦ 可能性がある Node が見つかったら次に進む • そのあとで消した Pod をひとつずつ戻す ◦ 追い出さざるをえない Pod に対してペナルティを計算 ◦ 最終的に傷がもっとも浅く済む Node をターゲットに
  61. #CNDT2019 #RoomG #CNDT2019 #RoomG なるほどわからん。 もうちょっと具体的に言って? ?

  62. #CNDT2019 #RoomG 高 Mem : 3 GiB CPU : 0.2

    core 高 Mem : 4 GiB CPU : 0.2 core 低 Mem : 1 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core 高 Mem : 4 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core 低 Mem : 2 GiB CPU : 0.2 core 低 Mem : 1 GiiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core 高 Mem : 6 GiB CPU : 0.2 core 低 Mem : 1 GiiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core 高 低 Mem : 2 GiB CPU : 0.2 core
  63. #CNDT2019 #RoomG 高 Mem : 3 GiB CPU : 0.2

    core 高 Mem : 4 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core 高 Mem : 4 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.2 / 2 core Mem : 6 / 8 GiB CPU : 0.2 / 2 core 高 Mem : 6 GiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core 高 まず低優先度 Pod を 全て追い出してみる 追い出しても無理 可能性あり 可能性あり
  64. #CNDT2019 #RoomG 高 Mem : 3 GiB CPU : 0.2

    core 高 Mem : 4 GiB CPU : 0.2 core Mem : 7 / 8 GiB CPU : 0.4 / 2 core 高 Mem : 4 GiB CPU : 0.2 core Mem : 6 / 8 GiB CPU : 0.4 / 2 core Mem : 6 / 8 GiB CPU : 0.2 / 2 core 高 Mem : 6 GiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core 高 低 Mem : 2 GiB CPU : 0.2 core 追い出した Pod を 戻せるところは戻す ひとつも戻せない 犠牲は 2 Pod ひとつは戻せる 犠牲は 1 Pod
  65. #CNDT2019 #RoomG 高 Mem : 3 GiB CPU : 0.2

    core 高 Mem : 4 GiB CPU : 0.2 core 低 Mem : 1 GiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core 高 Mem : 4 GiB CPU : 0.2 core 追い出される Mem : 6 / 8 GiB CPU : 0.4 / 2 core 低 Mem : 2 GiB CPU : 0.2 core 低 Mem : 1 GiiB CPU : 0.2 core Mem : 8 / 8 GiB CPU : 0.6 / 2 core 高 Mem : 6 GiB CPU : 0.2 core 低 Mem : 1 GiiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core 高
  66. #CNDT2019 #RoomG #CNDT2019 #RoomG Job がいきなり追い出されて 途中までの計算が無駄になった! ?

  67. #CNDT2019 #RoomG apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: server value:

    10000 preemptingPolicy: Never description: "The higher priority"
  68. #CNDT2019 #RoomG apiVersion: scheduling.k8s.io/v1 kind: PriorityClass matadata: name: server value:

    10000 preemptingPolicy: Never description: "The higher priority" Preemption を行わない
  69. #CNDT2019 #RoomG #CNDT2019 #RoomG Resource Request の値って 結局のところ恣意的な決め事じゃん? ?

  70. #CNDT2019 #RoomG apiVersion: v1 kind: Pod metadata: name: my-app spec:

    containers: - name: my-app image: username/my-app:latest resources: requests: memory: 6Gi cpu: 200m Mem : 6 GiB CPU : 0.2 core 本当は 2 GiB で足りるはずだけど OOM で死なないように多めにしとこう
  71. #CNDT2019 #RoomG Mem : 6 / 8 GiB CPU :

    0.2 / 2 core Mem : 6 GiB CPU : 0.2 core
  72. #CNDT2019 #RoomG Mem : 6 / 8 GiB CPU :

    0.2 / 2 core (Mem : 2 GiB) (CPU : 0.2 core) 無駄
  73. #CNDT2019 #RoomG #CNDT2019 #RoomG Vertical Pod Autoscaler (VPA) で 実際の使用量を自動で反映できるぞ!

    !
  74. #CNDT2019 #RoomG Vertical Pod Autoscaler (VPA) • Resource Requests は実使用量と無関係

    ◦ 少なすぎると危険、大きすぎるとお金の無駄 ◦ あらかじめ検証するにしても負荷テストが必要 ◦ 最終的には経験則で設定 • VPA により実測値に基づいた設定が可能に ◦ 現状、Pod を削除してから再作成する
  75. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core
  76. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Mem : 500 MiB CPU : 0.2 core Mem : 500 MiB CPU : 0.2 core Mem : 1 GiB CPU : 0.5 core VPA Mem : 1 GiB CPU : 0.5 core Mem : 1 GiB CPU : 0.5 core
  77. #CNDT2019 #RoomG VPA の構成要素 • Recommender ◦ 時系列データからリソース使用量の上限と下限を算出 • Updater

    ◦ 設定が上限と下限に収まっていない Pod を退去 • Admission Controller ◦ 新しい Pod の作成に割り込んで Request 値を上書き
  78. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Recommender Updater Mem: 500 MiB CPU : 0.2 core
  79. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Recommender Updater Mem: 500 MiB CPU : 0.2 core 200 <= Mem <= 400 0.1 <= CPU <= 1
  80. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Recommender Updater 200 <= Mem <= 400 0.1 <= CPU <= 1
  81. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Recommender Updater Mem : 500 MiB CPU : 0.2 core
  82. #CNDT2019 #RoomG Mem : 500 MiB CPU : 0.2 core

    Recommender Updater Mem: 400 MiB CPU : 0.2 core 200 <= Mem <= 400 0.1 <= CPU <= 1 Admission Webhook
  83. #CNDT2019 #RoomG #CNDT2019 #RoomG Node が死んだり復旧したりしたら Pod の配置も勝手に追従してほしい ?

  84. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 / 8 GiB CPU : 0.2 / 2 core Mem : 2 MiB CPU : 0.2 core Mem : 2 / 8 GiB CPU : 0.2 / 2 core Mem : 2 GiB CPU : 0.2 core Mem : 2 / 8 GiB CPU : 0.2 / 2 core
  85. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 / 8 GiB CPU : 0.2 / 2 core Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Node 死亡 Mem : 2 GiB CPU : 0.2 core
  86. #CNDT2019 #RoomG Mem : 2 GiB CPU : 0.2 core

    Mem : 2 / 8 GiB CPU : 0.2 / 2 core Mem : 0 / 8 GiB CPU : 0 / 2 core Mem : 2 GiB CPU : 0.2 core Mem : 4 / 8 GiB CPU : 0.4 / 2 core Mem : 2 GiB CPU : 0.2 core 復活しても空のまま
  87. #CNDT2019 #RoomG #CNDT2019 #RoomG Descheduler を実行してみよう。 Pod の偏りを修正してくれるはず !

  88. #CNDT2019 #RoomG Descheduler • 運用に伴って崩れた Pod の配置を回復 • 特定の条件下で Pod

    を退去させる ◦ RemoveDuplicates : Replica が同じ Node に固まっている ◦ LowNodeUtilization : リソース使用率が一定以下 ◦ RemovePodsViolatingPodAntiAffinity : 他 Pod との相性に違反 ◦ RemovePodsViolatingNodeAffinity : Node との相性に違反
  89. #CNDT2019 #RoomG apiVersion: descheduler/v1alpha1 kind: DeschedulerPolicy strategies: LowNodeUtilization: enabled: true

    params: nodeResourceUtilizationThresholds: thresholds: memory: 20 cpu: 20 pods: 20 targetThresholds: memory: 50 cpu: 50 pods: 50
  90. #CNDT2019 #RoomG apiVersion: descheduler/v1alpha1 kind: DeschedulerPolicy strategies: LowNodeUtilization: enabled: true

    params: nodeResourceUtilizationThresholds: thresholds: memory: 20 cpu: 20 pods: 20 targetThresholds: memory: 50 cpu: 50 pods: 50 下限値(単位は %)
  91. #CNDT2019 #RoomG apiVersion: descheduler/v1alpha1 kind: DeschedulerPolicy strategies: LowNodeUtilization: enabled: true

    params: nodeResourceUtilizationThresholds: thresholds: memory: 20 cpu: 20 pods: 20 targetThresholds: memory: 50 cpu: 50 pods: 50 上限値(単位は %)
  92. #CNDT2019 #RoomG Mem : 1 GiB CPU : 0.2 core

    Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 3 / 8 GiB CPU : 0.6 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core Mem : 3 GiB CPU : 0.1 core Mem : 6 / 8 GiB CPU : 0.5 / 2 core Mem : 0.5 GiB CPU : 0.8 core Mem : 0.5 / 8 GiB CPU : 0.8 / 2 core Mem : 20 % CPU : 20 % Pods : 20 % Thresholds Mem : 50 % CPU : 50 % Pods : 50 % Target Thresholds
  93. #CNDT2019 #RoomG Mem : 1 GiB CPU : 0.2 core

    Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 3 / 8 GiB CPU : 0.6 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core Mem : 3 GiB CPU : 0.1 core Mem : 6 / 8 GiB CPU : 0.5 / 2 core Mem : 0.5 GiB CPU : 0.8 core Mem : 0.5 / 8 GiB CPU : 0.8 / 2 core Mem : 20 % CPU : 20 % Pods : 20 % Thresholds Mem : 50 % CPU : 50 % Pods : 50 % Target Thresholds Mem 遊びすぎ Mem 使いすぎ
  94. #CNDT2019 #RoomG Mem : 1 GiB CPU : 0.2 core

    Mem : 1 GiB CPU : 0.2 core Mem : 1 GiB CPU : 0.2 core Mem : 3 / 8 GiB CPU : 0.6 / 2 core Mem : 1 GiB CPU : 0.2 core Mem : 2 GiB CPU : 0.2 core Mem : 3 / 8 GiB CPU : 0.4 / 2 core Mem : 0.5 GiB CPU : 0.8 core Mem : 3.5 / 8 GiB CPU : 0.9 / 2 core Mem : 20 % CPU : 20 % Pods : 20 % Thresholds Mem : 50 % CPU : 50 % Pods : 50 % Target Thresholds Mem : 3 GiB CPU : 0.1 core
  95. #CNDT2019 #RoomG Section 3 のポイント • シンプルな原理だけでは最適な配置は難しい ◦ Pod を一度配置した後の事情を加味することができない

    • 状況に応じて補完する機能やツールを使用 ◦ Preemption : 重要な Pod を優先して起動したい ◦ Vertical Pod Autoscaler : 実測値に基づいて Requests を決めたい ◦ Descheduler : Pod の偏りに対応したい
  96. #CNDT2019 #RoomG #CNDT2019 #RoomG 広がるスケジューラの世界 Build Your Own Strategy

  97. #CNDT2019 #RoomG #CNDT2019 #RoomG Kubernetes 外のドメイン知識に 合わせたスケジューリングがほしい! ?

  98. #CNDT2019 #RoomG Scheduler Extender • JSON Webhook による処理の追加 • 拡張ポイントは

    4 箇所 ◦ Filter : Node の候補をさらに絞る ◦ Prioritized : Node の Scoring 関数を追加 ◦ Preempt : 退去させられる Pod の候補を絞る ◦ Bind : Pod の Node の紐付けの方法を定義
  99. #CNDT2019 #RoomG { "kind": "Policy", "apiVersion": "v1", "predicates": [(snip)], "priorities":

    [(snip)], "extenders": [{ "urlPrefix": "http://my-extender:8080", "filterVerb": "filter", "prioritizeVerb": "prioritize", "preemptVerb": "preempt", "bindVerb": "bind", "enableHttps": false }] } policy.cfg
  100. #CNDT2019 #RoomG { "kind": "Policy", "apiVersion": "v1", "predicates": [(snip)], "priorities":

    [(snip)], "extenders": [{ "urlPrefix": "http://my-extender:8080", "filterVerb": "filter", "prioritizeVerb": "prioritize", "preemptVerb": "preempt", "bindVerb": "bind", "enableHttps": false }] } Webhook サーバのエンドポイント policy.cfg
  101. #CNDT2019 #RoomG Filter Extender Node の候補を さらに絞る

  102. #CNDT2019 #RoomG 拡張点 1 : Filter • ノードの絞り込み条件を追加できる ◦ 入力:通常の

    Filter を通過した Node のリスト ◦ 出力:さらに絞り込んだ Node のリスト • その Pod を配置したくない Node を選べる ◦ NodeAntiAffinity より自由なロジックが記述できる ◦ 時間経過で変化する条件も使用できる
  103. #CNDT2019 #RoomG Prioritize Extender Node の順位付け 関数を追加する

  104. #CNDT2019 #RoomG 拡張点 2 : Prioritize • ノードのスコアリング関数を追加できる ◦ 入力:Filter

    の結果残った Node のリスト ◦ 出力:各 Node のスコア • スコアが大きい Node ほど選択されやすい ◦ 各スコアリング関数が 0 から 10 で採点 ◦ Weight をかけて合計したものが Node の最終スコアに
  105. #CNDT2019 #RoomG Preempt Extender Preemption の犠牲となる Pod を選択する

  106. #CNDT2019 #RoomG 拡張点 3 : Preempt • Preemption の犠牲になる Pod

    を選択できる ◦ 入力:犠牲にされそうな Pod のリスト ◦ 出力:犠牲にしてもよい Pod のリスト • 犠牲はあくまでも候補から選択するのみ ◦ しかも Pod Disruption Budget 違反を算出する必要がある ◦ 入力そのまま、もしくは完全に空リストを返すのが現実的
  107. #CNDT2019 #RoomG Bind Extender : Pod の Node の紐付けを移譲 

  108. #CNDT2019 #RoomG 拡張点 4 : Bind • Pod を Node

    に紐付ける 操作を移譲する ◦ 入力:Scheduling Cycle で決定された Node 名 ◦ 出力:なし • Node 上で時間のかかる前処理ができる ◦ Binding は Pod ごとに個別の goroutine になっている ◦ Extender が Binding オブジェクトを作成する
  109. #CNDT2019 #RoomG Extender を利用したツール例 • kube-throttler (by PFN) ◦ 割り当て分を超えた

    Pod をリジェクトせず待機 • TopoLVM (by Cybozu) ◦ Node ごとの Persistent Volume のキャパシティを反映 • Stork (by Portworx) ◦ ネットワークストレージの状況を反映
  110. #CNDT2019 #RoomG #CNDT2019 #RoomG 処理を挟むだけじゃなく アルゴリズム自体を最適化したい! ?

  111. #CNDT2019 #RoomG 開発中の特殊スケジューラ • kube-batch ◦ All or Nothing の配置

    (Co-Scheduling) に対応 ◦ 実証済み機能は kubeflow (TensorFlow on K8s) で使用 • Poseidon ◦ Firmament Scheduler の Kubernetes 向け実装 ◦ Pod の配置をグラフ上の最小費用流問題に帰着
  112. #CNDT2019 #RoomG #CNDT2019 #RoomG よっしゃ、うちの会社でも 効率的な独自スケジューラ作るぜ! ?

  113. #CNDT2019 #RoomG #CNDT2019 #RoomG やめておけ。 !

  114. #CNDT2019 #RoomG スケジューラ完全自作は危険 • そもそもテストできるのか? ◦ リアルなワークロードでの負荷テストしないと意味がない ◦ 公式ベンチマークは Kubernetes

    本体以外に使用しにくい ◦ シミュレータはスケジューラ全体をテストできない • Extender までに止めておいたほうが無難 ◦ Webhook は入出力がはっきりしておりテストしやすい
  115. #CNDT2019 #RoomG Section 4 のポイント • スケジューリングのカスタマイズの必要性 ◦ 用意された項目を選ぶだけで可能なことは限られる •

    Scheduler Extender でロジックを追加できる ◦ 外部の Webhook サーバとして稼働させる ◦ 4 箇所の拡張点に対応 • その他、特殊なスケジューラも開発されている
  116. #CNDT2019 #RoomG #CNDT2019 #RoomG 本日のまとめ Recap of the Session

  117. #CNDT2019 #RoomG まとめ • スケジューラの責務 ◦ Filtering + Scoring で

    Pod にあった Node を選択 • リソース効率を上げるための追加施策 ◦ 通常フローではクラスタの状態を反映させるのが難しい • より複雑なユースケースに対応するユーザ拡張 ◦ Scheduler Extender や特殊スケジューラの開発
  118. #CNDT2019 #RoomG #CNDT2019 #RoomG Have a Nice Scheduling! Presented by

    チェシャ猫 (@y_taka_23)