タイトル通り
細かいしきい値とか実装までは追っていないので軽め
PODの垂直のほうには触れません
なお、検証したのは2021年8月なので、以前以後による変更があるやもしれません
コードブロックに貼ってあるやつは要点以外は削っていることが多いです
何を見たかったんですか
ノードのスケールイン/アウトの様子
PODのスケールイン/アウトの様子
PDBの守護神っぷり
参考(公式)
https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-cpu-resource/
https://kubernetes.io/ja/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
https://cloud.google.com/kubernetes-engine/docs/how-to/horizontal-pod-autoscaling?hl=ja#kubectl-apply
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja
https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#does-ca-work-with-poddisruptionbudget-in-scale-down
ほぼ日本語なのがすばらしい
クラスタ構成(要点のみ)
自動スケーリングを有効にして最低1/最高3に設定
インスタンスタイプはn2-std2(2vcpu)
他はデフォルト(アクセス権限関係は必要ならちゃんと設定しよう)
e2系(small以上)だと
Capacity:
cpu: 2
Allocatable:
cpu: 940m ← !?
という、CPU2って書いてあるのに割り当てが2000mじゃないという現象に襲われて検証めんどうくさくなるのでn2系が無難
deployments
アプリケーションに固有の部分は適当に読み替えてください
apiVersion: apps/v1
kind: Deployment
metadata:
name: yourAPP
labels:
app: yourAPP
spec:
replicas: 1
selector:
matchLabels:
app: yourAPP
template:
metadata:
labels:
app: yourAPP
spec:
containers:
- name: yourAPP
image: [[your image url]]
ports:
- containerPort: xxxxx
resources:
requests:
cpu: 500m
要するにレプリカ1のcpuリクエストは実値で500mです
CAはリクエストに呼応するため、リクエストを設定しないとウンともスンともしてくれません
また、リクエストはリソースの確保ではなく、勝手な宣言です
いくら使うと宣言しても実際の使用率には影響しません
HPA
アプリケーションに固有の部分はry
v2からはCPU以外の指標も扱えるそうですが、とりあえずCPUで事足りるだろうということで
HPAは指定したDeployments(POD)以外のリソースには見向きもしないので結構考えやすいですね
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: yourHPA
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: yourAPP
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: AverageValue
averageValue: 500m
UtilizationではなくAverageValueを使います
ノードのCPUコア数が分かってるならこっちのほうが考えやすい気がする
なお、Utilizationを使う場合でDeployments側にrequestsの設定をしていない場合、
failed to compute desired number of replicas based on listed metrics for Deployment/yourAPP: invalid metrics (1 invalid out of 1), first error is: failed to get cpu utilization: missing request for cpu
こんなのが出てTARGETSが一生unknownのままだったので気を付けましょう
ちなみにrequestsが無くてもAverageValueを使えばHPAは機能はしますがノードの増減が行われません(上述)
PODの数だけスケールしたいってのはあんまりない要件な気はするので、基本は設定して運用するかと思います
PDB
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: yourAPP
spec:
minAvailable: 5
selector:
matchLabels:
app: yourAPP
最低有効であるべきpod数を5に設定
検証
開幕
# node
NAME STATUS ROLES
node1 Ready <none>
# pod
NAME READY STATUS RESTARTS
pod1 1/1 Running 0
# top pod
NAME CPU(cores) MEMORY(bytes)
pod1 0m 1Mi
# HPA
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
hpa Deployment/yourAPP 0/500m 1 5 1
pod1に負荷をかける
pod1に接続してyes > /dev/null
を実行、しばらく後
# node
NAME STATUS ROLES
node1 Ready <none>
# pod
NAME READY STATUS RESTARTS
pod1 1/1 Running 0
pod2 1/1 Running 0
# top pod
NAME CPU(cores) MEMORY(bytes)
pod1 1000m 2Mi
pod2 0m 1Mi
# HPA
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
hpa Deployment/yourAPP 500m/500m 1 5 2
予想通りpodが1個増えてる。
pod1/2に負荷をかける
続いてpod2にも負荷をかける
# node
NAME STATUS ROLES
node1 Ready <none>
node2 Ready <none>
# pod
NAME READY STATUS RESTARTS
pod1 1/1 Running 0
pod2 1/1 Running 0
pod3 1/1 Running 0
pod4 1/1 Running 0
# top pod
NAME CPU(cores) MEMORY(bytes)
pod1 1000m 2Mi
pod2 1000m 1Mi
pod3 0m 1Mi
pod4 0m 1Mi
# HPA
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
hpa Deployment/yourAPP 500m/500m 1 5 4
pod3以降がnode1にdeploy出来なくなったため(リソース不足)ノードも増えてる。
pod1/2/3に負荷をかける
node1 Ready <none>
node2 Ready <none>
node3 Ready <none>
# pod
NAME READY STATUS RESTARTS
pod1 1/1 Running 0
pod2 1/1 Running 0
pod3 1/1 Running 0
pod4 1/1 Running 0
pod5 1/1 Running 0
# top pod
NAME CPU(cores) MEMORY(bytes)
pod1 1000m 2Mi
pod2 1000m 1Mi
pod3 1000m 1Mi
pod4 0m 1Mi
pod5 0m 1Mi
# HPA
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
hpa Deployment/yourAPP 723m/500m 1 5 5
# node desc(cpuのみ)
Resource Requests Limits
-------- -------- ------
cpu 1639m (84%) 201m (10%)
Resource Requests Limits
-------- -------- ------
cpu 1463m (75%) 0 (0%)
Resource Requests Limits
-------- -------- ------
cpu 703m (36%) 0 (0%)
# PDB(一部)
spec:
minAvailable: 5
selector:
matchLabels:
app: yourAPP
status:
currentHealthy: 5
desiredHealthy: 5
disruptionsAllowed: 0
expectedPods: 5
observedGeneration: 3
負荷解除
解除してしばらく後
# node
NAME STATUS ROLES
node1 Ready <none>
node2 Ready <none>
# pod
NAME READY STATUS RESTARTS
pod1 1/1 Running 0
# top pod
NAME CPU(cores) MEMORY(bytes)
pod1 0m 1Mi
# HPA
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
hpa Deployment/yourAPP 0/500m 1 5 1
結論と余談
CA/HPA
設定内容さえ分かっていればかなり素直に動いてくれそう
ただ、上記の最終状態からdeploymentを消してもnode2はスケールインされなかったため、1-2台目にはシステム関連のpodがdeployされるのかもしれない。一応、2台目と3台目の初期podで3台目にはkube-dns
がなかったためそれなのか?
なお、素の状態(こっちで定義したアプリケーションを一切deployしていない状態)だとCPUリクエストが
1台目: 639m
2台目: 463m
3台目: 203m
となっており、vcpuの数を変えても変化はなかったため、1vcpuで2台以下だと割とカツカツだった
PDB
あくまでこいつはノードの計画停止とかでdrainが走る時に面倒を見てくれる機構であり、HPAとは関与しない様子
なのでPDBでminを5にしていてもHPAで1に設定していればごりごりスケールインされる
drain使った検証は他に記事たくさんあったから割愛