この記事の目的
WorkerNode上で起動するPod(レプリカ)数の偏りを自動的に解消するためにDescheduler for Kubernetesを導入したお話をざっくりと書いて残しておきます。
前提
Descheduler for Kubernetesのバージョンは0.26.1です。
次のGitHubリポジトリに記載されている手順に従ってデプロイします。
https://github.com/kubernetes-sigs/descheduler
5分間隔でJob Podを作成して処理が終わったら捨てたかったので私はCronJobを選びました。
kustomize build 'github.com/kubernetes-sigs/descheduler/kubernetes/cronjob?ref=v0.26.1' | kubectl apply -f -
Deschedulerをどのような場面で効かせたかったか
- とあるWorkerNodeが障害によってダウンし、新しいWorkerNodeをクラスタに追加したとき
- シンプルに新しいWorkerNodeをクラスタに追加したとき
です。
DaemonSetであれば新しいWorkerNodeで自動的に起動されてくるのですが、DeploymentやReplicasetで管理しているPodはkubectl rollout restart
やkubectl delete pod
で再作成してあげないと新しいWorkerNodeにスケジューリングされません。
だからといって手動でコマンドを打ちに行くのも大変なので、スケジューリング解除のためにDeschedulerを導入しました。
WorkerNode上のPod数を平均化するために
Deschedulerのconfigmapを次のように変更しました。
---
apiVersion: v1
kind: ConfigMap
metadata:
name: descheduler-policy-configmap
namespace: kube-system
data:
policy.yaml: |
apiVersion: "descheduler/v1alpha2"
kind: "DeschedulerPolicy"
profiles:
- name: ProfileName
pluginConfig:
- name: "RemoveDuplicates"
- name: "DefaultEvictor"
args:
evictSystemCriticalPods: true
evictLocalStoragePods: true
plugins:
balance:
enabled:
- "RemoveDuplicates"
Configmapで設定したDeschedulerPolicyの解説
基本戦略はRemoveDuplicates
とし、kube-system Namespaceで動くPodやPersistentVolumeをマウントしているPodもDeschedulerによってスケジュール解除させます。
RemoveDupulicates
は、各WokerNodeがほぼ同じ数のレプリカを起動させます。
evictSystemCriticalPods: true
kube-systemのNamespaceで動作するPodもスケジュール解除させる。
evictLocalStoragePods: true
PersistentVolumeをマウントするPodもスケジュール解除させる。
他の使い方として
とあるPod同士を同じWorkerNode上で起動させたい時に使うPodAffinityや、Podが起動するNodeを固定したい時に使うNodeAffinityのルール違反を検知・スケジュール解除を行うこともできます。
WorkerNodeの使用リソース量をトリガーにPodのスケジュールを解除できたり、TopologySpreadConstraintで定義したルールに違反したPodのスケジュール解除を行うこともできます。
気を付けたいポイント
Deschedulerがスケジュールを一度に解除できるPod数に対して制限を掛けてあげる必要が出てきます。
せっかく起動してサービス提供が行われているPod全てが別Nodeへ移動することになったらサービスとしてダウンタイムが生じることになるからです。
PodDisruptionBudgetを併用したり、コネクションドレインの時間が作られるようGracefulな感じの設定を検討する必要が出てくると思います。
そのあたりは要件や用途に応じてどこまで突き詰めるか一度整理しておくと無難です。
おわり
おわります。