Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

#CNDT2019 #RoomG

Slide 3

Slide 3 text

#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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

#CNDT2019 #RoomG User

Slide 14

Slide 14 text

#CNDT2019 #RoomG Queue Scheduling Cycle Binding Threads

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

#CNDT2019 #RoomG Queue Scheduling Cycle Binding Threads

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

#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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

#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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

#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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

#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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

#CNDT2019 #RoomG

Slide 46

Slide 46 text

#CNDT2019 #RoomG

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

#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

Slide 53

Slide 53 text

#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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

#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"

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

#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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

#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

Slide 65

Slide 65 text

#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 高

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

#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

Slide 76

Slide 76 text

#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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

#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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

#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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

#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

Slide 85

Slide 85 text

#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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

#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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

#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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

#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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

#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

Slide 100

Slide 100 text

#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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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