ゼロバンク・デザインファクトリー株式会社(ZDF)のSRE張です、kubernetesのスペシャリストとして日々GKEの世話をしています、直近GKEのコスト最適化活動をしていて、出会った問題や経験を共有したいと思い、この記事を書くとこになりました。
背景
コスト最適化の一環として検証環境のGKEのスケジューリングプロファイルをOputimize Utilizationモード(積極的にスケールイン)に設定しました。
設定した直後は予想通りNode台数は凡そ10%減りました、設定一つでこれ程の効果を得たのはうれしいです。
数日間Nodeの使用状況を見て一つ問題に気付きました、数台のNodeはリソース(CPUとメモリー)使用率が低いにもかかわらず、スケールインが発動できませんでした。
調査
GCPサポートに問い合わせしつつ、oss kubernetes git上のcluster-autoscalerドキュメントを見てました。
親切にスケールインしないときのトラブルシューティングが書いてあります。
使用率が低いにもかかわらず、スケールインが発生しない主な理由は以下になります
- ノードグループはすでに最小サイズになってます。
- ノードにはスケールインが無効なannotationが付けられています。
- ノードが不要になった時間は10分未満。
- 過去10分間にスケールアウトがありました。
- 過去3分間にこのグループのスケールインが失敗しました。
- 特定のノードを削除しようとして失敗場合、クラスターオートスケーラーはさらに5 分間待機してから再度削除することを検討します。
- --scale-down-delay-after-deleteまたは--scan-intervalに大きなカスタム値を使用しているとCluster Autoscalerアクションが遅れます。
- --scale-down-enabled が false に設定されています。
- コントローラーがいない、podタイプPodがNode上で稼働されてます。
- kube-system のpodがNode上で稼働し、かつPDB未設定。
結果的にkube-systemのpodがNodeのスケールインを阻害していることが分かりました。
対応
kube-system配下のpodはNodeからevictされるとき、可用性に影響するもの(kube-dnsなど)もあり、そのためデフォルトではスケールインしない振る舞いになっています、PDB(PodDisruptionBudget)を設定することで回避できます。
今回の対象は検証環境なので、PBDを設定し、コストを下げるほうの作業を進めました。
PDBは以下のコマンドで作成する
# kube-system配下deploymentとラベル確認
$ kubectl -n kube-system get deploy --show-labels
# helpでコマンド形式を確認(必須ではない)
$ kubectl create pdb -h
# deploymentの名前とラベルからpdbを作成
$ kubectl -n kube-system create poddisruptionbudget <name> --selector=k8s-app=<app name> --max-unavailable=1
# 自信がないときdry runでyamlファイルを出力し、確認してからデプロイ
$ kubectl -n kube-system create poddisruptionbudget <name> --selector=k8s-app=<app name> --max-unavailable=1 --dry-run=client -o yaml > pdb.yaml
$ vim pdb.yaml
$ kubectl apply -f pdb.yaml
# 作成されたpdbを確認
$ kubectl -n kube-system describe pdb <name>
# 漏れはないかの確認
$ kubectl -n kube-system get deploy
$ kubectl -n kube-system get pdb
# nodeスケールインの確認(GCPコンソール上も確認できる)
$ kubectl get nodes
$ kubectl top nodes
まとめ
GKEはマネジードサービスとは言え、kube-system配下のpod PDB設定次第でスケールインが想定より上手くいかないこともあります、今回はPDBを設定し、スケールインがなるべくNodeを節約するOputimize Utilizationモードで動かすことができました。
参考資料
- https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja#limitations
- https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#i-have-a-couple-of-nodes-with-low-utilization-but-they-are-not-scaled-down-why
- https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-to-set-pdbs-to-enable-ca-to-move-kube-system-pods
- https://kubernetes.io/docs/concepts/workloads/pods/disruptions/