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

そのコンテナ、もっと「賢く」置けますよ? #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

y_taka_23

July 23, 2019
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

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

    View Slide

  2. #CNDT2019 #RoomG

    View Slide

  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

    View Slide

  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 が勝手に決まる

    View Slide

  5. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    スケジューリング
    クラスタ上の Pod 配置をコントロールすること

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. #CNDT2019 #RoomG
    ユーザが kubectl コマンドで Deployment を作成
    Node 上で Pod が起動
    この間、何が起こっているのか?
    ?

    View Slide

  10. #CNDT2019 #RoomG
    Scheduler
    Controller Manager API Server
    Kubelet
    Kubelet
    Kubelet
    User

    View Slide

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

    View Slide

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

    View Slide

  13. #CNDT2019 #RoomG
    User

    View Slide

  14. #CNDT2019 #RoomG
    Queue
    Scheduling Cycle Binding Threads

    View Slide

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

    View Slide

  16. #CNDT2019 #RoomG
    : node-02
    : node-01
    : node-03
    Scheduling Cycle
    Pod の行き先 Node を “ひとつずつ” 確定
    スケジューラの心臓部分

    View Slide

  17. #CNDT2019 #RoomG
    Binding Threads
    Pod ごとに goroutine を生成して
    行き先となる Node を API Server に登録

    View Slide

  18. #CNDT2019 #RoomG
    Queue
    Scheduling Cycle Binding Threads

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  23. #CNDT2019 #RoomG
    スケジューラの基本動作
    ● Pod と Node の紐付けのみを担当
    ○ 自分自身が Pod を作成するわけではない
    ● Pod ひとつずつに対し以下を繰り返す
    ○ キューから配置 Node が未定の Pod を取り出す
    ○ Pod の条件から Node の候補を絞る
    ○ 残った中からさらに最適な Node を選択する

    View Slide

  24. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    なるほどわからん。
    もうちょっと具体的に言って?
    ?

    View Slide

  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

    View Slide

  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 に配置してくれ

    View Slide

  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

    View Slide

  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 を除外する

    View Slide

  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 の中から
    ベストを選ぶ
    より余裕がある

    View Slide

  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

    View Slide

  31. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    でも一口に Pod って言っても
    実は「二種類」あるよね?
    ?

    View Slide

  32. #CNDT2019 #RoomG
    ● 主に Deployment で管理
    ● 長時間、稼働し続ける
    ● できるだけ散らしたい
    Server 系の Pod
    S
    S S
    S

    View Slide

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

    View Slide

  34. #CNDT2019 #RoomG
    スケジューラの設定
    ● スケジューラ起動時に --config フラグを指定
    ○ 冗長化などの設定も含まれる
    ○ さらに ConfigMap 化しておいた Policy を参照
    ● Policy は用意された項目を組み合わせる
    ○ Node を Filtering する条件
    ○ Scoring の順位付け関数と重み付け

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  40. #CNDT2019 #RoomG
    {
    "kind": "Policy",
    "apiVersion": "v1",
    "predicates": [
    {"name": "PodFitsHostPorts"},
    {"name": "PodFitsHostResources"},
    ...
    ],
    "priorities": [
    {"name": "MostRequestedPriority", "weight": 1},
    {"name": "ServiceSpreadingPriority", "weight": 1},
    ...
    ]
    }
    確保済みリソースが多い Node を優先
    = 詰め込む配置戦略
    policy.cfg

    View Slide

  41. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    ひとつの Kubernetes クラスタには
    Server 系 or Batch 系のみ?
    ?
    マネージド Kubernetes なんですけど
    起動時のフラグとは一体。。。
    ?

    View Slide

  42. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Kubernetes のクラスタ内には
    複数のスケジューラが存在できるぞ!
    !

    View Slide

  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
    スケジューラに名前を付けておく

    View Slide

  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
    どのスケジューラの管理下にするかを指定

    View Slide

  45. #CNDT2019 #RoomG

    View Slide

  46. #CNDT2019 #RoomG

    View Slide

  47. #CNDT2019 #RoomG
    Section 2 のポイント
    ● スケジューラは Pod を Node へ紐付ける
    ○ Filtering で Node の候補を絞り、Scoring で順位付け
    ● Policy によるスケジューリングの調整
    ○ あらかじめ定義されている項目の中から指定
    ● クラスタ内に複数のスケジューラが共存可能
    ○ Kubernetes の「舵輪型」アーキテクチャの恩恵

    View Slide

  48. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    フィードバックとリソース効率
    More Adaptive Scheduling Scheme

    View Slide

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

    View Slide

  50. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    今すぐ立てたい Pod がある。
    Node 上の Pod が邪魔なんだけど?
    ?

    View Slide

  51. #CNDT2019 #RoomG
    ● 主に Deployment で管理
    ● 長時間、稼働し続ける
    ● できるだけ散らしたい
    ● 今すぐ起動したい
    Server 系の Pod
    ● 主に Job で管理
    ● 短期間で終了する
    ● できるだけ詰め込みたい
    ● 余裕がある時に起動
    Batch 系の Pod

    View Slide

  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

    View Slide

  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

    View Slide

  54. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Priority と Preemption を駆使して
    邪魔な Pod を立ち退かせよう!
    !

    View Slide

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

    View Slide

  56. #CNDT2019 #RoomG
    Dequeue Filtering
    Node が未定の
    Pod を一つ選択
    Pod の条件に合う
    Node が見つからない
    Preemption
    自分より低優先度の
    Pod を追い出す

    View Slide

  57. #CNDT2019 #RoomG
    Priority と Preemption
    ● Priority の指定
    ○ Scheduler のキューは優先度付きキューになる
    ● Preemption
    ○ Filtering で Node の候補が見つからなかった際に発動
    ○ 低優先度の Pod を強制的に追い出す
    ○ できるだけ影響が小さくなる Node を選ぶ

    View Slide

  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"

    View Slide

  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"
    優先度:高
    優先度:低

    View Slide

  60. #CNDT2019 #RoomG
    Preemption のアルゴリズム
    ● まず低優先度の Pod をすべて消したと仮定
    ○ 余裕ができなければその時点で可能性なし
    ○ 可能性がある Node が見つかったら次に進む
    ● そのあとで消した Pod をひとつずつ戻す
    ○ 追い出さざるをえない Pod に対してペナルティを計算
    ○ 最終的に傷がもっとも浅く済む Node をターゲットに

    View Slide

  61. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    なるほどわからん。
    もうちょっと具体的に言って?
    ?

    View Slide

  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

    View Slide

  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 を
    全て追い出してみる
    追い出しても無理 可能性あり 可能性あり

    View Slide

  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

    View Slide

  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

    View Slide

  66. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Job がいきなり追い出されて
    途中までの計算が無駄になった!
    ?

    View Slide

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

    View Slide

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

    View Slide

  69. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Resource Request の値って
    結局のところ恣意的な決め事じゃん?
    ?

    View Slide

  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 で死なないように多めにしとこう

    View Slide

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

    View Slide

  72. #CNDT2019 #RoomG
    Mem : 6 / 8 GiB
    CPU : 0.2 / 2 core
    (Mem : 2 GiB)
    (CPU : 0.2 core)
    無駄

    View Slide

  73. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Vertical Pod Autoscaler (VPA) で
    実際の使用量を自動で反映できるぞ!
    !

    View Slide

  74. #CNDT2019 #RoomG
    Vertical Pod Autoscaler (VPA)
    ● Resource Requests は実使用量と無関係
    ○ 少なすぎると危険、大きすぎるとお金の無駄
    ○ あらかじめ検証するにしても負荷テストが必要
    ○ 最終的には経験則で設定
    ● VPA により実測値に基づいた設定が可能に
    ○ 現状、Pod を削除してから再作成する

    View Slide

  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

    View Slide

  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

    View Slide

  77. #CNDT2019 #RoomG
    VPA の構成要素
    ● Recommender
    ○ 時系列データからリソース使用量の上限と下限を算出
    ● Updater
    ○ 設定が上限と下限に収まっていない Pod を退去
    ● Admission Controller
    ○ 新しい Pod の作成に割り込んで Request 値を上書き

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  83. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Node が死んだり復旧したりしたら
    Pod の配置も勝手に追従してほしい
    ?

    View Slide

  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

    View Slide

  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

    View Slide

  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
    復活しても空のまま

    View Slide

  87. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Descheduler を実行してみよう。
    Pod の偏りを修正してくれるはず
    !

    View Slide

  88. #CNDT2019 #RoomG
    Descheduler
    ● 運用に伴って崩れた Pod の配置を回復
    ● 特定の条件下で Pod を退去させる
    ○ RemoveDuplicates : Replica が同じ Node に固まっている
    ○ LowNodeUtilization : リソース使用率が一定以下
    ○ RemovePodsViolatingPodAntiAffinity : 他 Pod との相性に違反
    ○ RemovePodsViolatingNodeAffinity : Node との相性に違反

    View Slide

  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

    View Slide

  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
    下限値(単位は %)

    View Slide

  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
    上限値(単位は %)

    View Slide

  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

    View Slide

  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 使いすぎ

    View Slide

  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

    View Slide

  95. #CNDT2019 #RoomG
    Section 3 のポイント
    ● シンプルな原理だけでは最適な配置は難しい
    ○ Pod を一度配置した後の事情を加味することができない
    ● 状況に応じて補完する機能やツールを使用
    ○ Preemption : 重要な Pod を優先して起動したい
    ○ Vertical Pod Autoscaler : 実測値に基づいて Requests を決めたい
    ○ Descheduler : Pod の偏りに対応したい

    View Slide

  96. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    広がるスケジューラの世界
    Build Your Own Strategy

    View Slide

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

    View Slide

  98. #CNDT2019 #RoomG
    Scheduler Extender
    ● JSON Webhook による処理の追加
    ● 拡張ポイントは 4 箇所
    ○ Filter : Node の候補をさらに絞る
    ○ Prioritized : Node の Scoring 関数を追加
    ○ Preempt : 退去させられる Pod の候補を絞る
    ○ Bind : Pod の Node の紐付けの方法を定義

    View Slide

  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

    View Slide

  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

    View Slide

  101. #CNDT2019 #RoomG
    Filter Extender
    Node の候補を
    さらに絞る

    View Slide

  102. #CNDT2019 #RoomG
    拡張点 1 : Filter
    ● ノードの絞り込み条件を追加できる
    ○ 入力:通常の Filter を通過した Node のリスト
    ○ 出力:さらに絞り込んだ Node のリスト
    ● その Pod を配置したくない Node を選べる
    ○ NodeAntiAffinity より自由なロジックが記述できる
    ○ 時間経過で変化する条件も使用できる

    View Slide

  103. #CNDT2019 #RoomG
    Prioritize Extender
    Node の順位付け
    関数を追加する

    View Slide

  104. #CNDT2019 #RoomG
    拡張点 2 : Prioritize
    ● ノードのスコアリング関数を追加できる
    ○ 入力:Filter の結果残った Node のリスト
    ○ 出力:各 Node のスコア
    ● スコアが大きい Node ほど選択されやすい
    ○ 各スコアリング関数が 0 から 10 で採点
    ○ Weight をかけて合計したものが Node の最終スコアに

    View Slide

  105. #CNDT2019 #RoomG
    Preempt Extender
    Preemption の犠牲となる
    Pod を選択する

    View Slide

  106. #CNDT2019 #RoomG
    拡張点 3 : Preempt
    ● Preemption の犠牲になる Pod を選択できる
    ○ 入力:犠牲にされそうな Pod のリスト
    ○ 出力:犠牲にしてもよい Pod のリスト
    ● 犠牲はあくまでも候補から選択するのみ
    ○ しかも Pod Disruption Budget 違反を算出する必要がある
    ○ 入力そのまま、もしくは完全に空リストを返すのが現実的

    View Slide

  107. #CNDT2019 #RoomG
    Bind Extender : Pod の Node の紐付けを移譲 

    View Slide

  108. #CNDT2019 #RoomG
    拡張点 4 : Bind
    ● Pod を Node に紐付ける 操作を移譲する
    ○ 入力:Scheduling Cycle で決定された Node 名
    ○ 出力:なし
    ● Node 上で時間のかかる前処理ができる
    ○ Binding は Pod ごとに個別の goroutine になっている
    ○ Extender が Binding オブジェクトを作成する

    View Slide

  109. #CNDT2019 #RoomG
    Extender を利用したツール例
    ● kube-throttler (by PFN)
    ○ 割り当て分を超えた Pod をリジェクトせず待機
    ● TopoLVM (by Cybozu)
    ○ Node ごとの Persistent Volume のキャパシティを反映
    ● Stork (by Portworx)
    ○ ネットワークストレージの状況を反映

    View Slide

  110. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    処理を挟むだけじゃなく
    アルゴリズム自体を最適化したい!
    ?

    View Slide

  111. #CNDT2019 #RoomG
    開発中の特殊スケジューラ
    ● kube-batch
    ○ All or Nothing の配置 (Co-Scheduling) に対応
    ○ 実証済み機能は kubeflow (TensorFlow on K8s) で使用
    ● Poseidon
    ○ Firmament Scheduler の Kubernetes 向け実装
    ○ Pod の配置をグラフ上の最小費用流問題に帰着

    View Slide

  112. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    よっしゃ、うちの会社でも
    効率的な独自スケジューラ作るぜ!
    ?

    View Slide

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

    View Slide

  114. #CNDT2019 #RoomG
    スケジューラ完全自作は危険
    ● そもそもテストできるのか?
    ○ リアルなワークロードでの負荷テストしないと意味がない
    ○ 公式ベンチマークは Kubernetes 本体以外に使用しにくい
    ○ シミュレータはスケジューラ全体をテストできない
    ● Extender までに止めておいたほうが無難
    ○ Webhook は入出力がはっきりしておりテストしやすい

    View Slide

  115. #CNDT2019 #RoomG
    Section 4 のポイント
    ● スケジューリングのカスタマイズの必要性
    ○ 用意された項目を選ぶだけで可能なことは限られる
    ● Scheduler Extender でロジックを追加できる
    ○ 外部の Webhook サーバとして稼働させる
    ○ 4 箇所の拡張点に対応
    ● その他、特殊なスケジューラも開発されている

    View Slide

  116. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    本日のまとめ
    Recap of the Session

    View Slide

  117. #CNDT2019 #RoomG
    まとめ
    ● スケジューラの責務
    ○ Filtering + Scoring で Pod にあった Node を選択
    ● リソース効率を上げるための追加施策
    ○ 通常フローではクラスタの状態を反映させるのが難しい
    ● より複雑なユースケースに対応するユーザ拡張
    ○ Scheduler Extender や特殊スケジューラの開発

    View Slide

  118. #CNDT2019 #RoomG
    #CNDT2019 #RoomG
    Have a Nice Scheduling!
    Presented by チェシャ猫 (@y_taka_23)

    View Slide