退避(eviction)とは、リソース不足のノードで1つ以上のPodを積極的に終了させるプロセスです。
とあるように、ノードに配置するリソース(Pod)の最適化処理です。対象となったPodは一度削除された上で別のノードに再配置されます。
Kubernetes Autoscalerを自動スケーリングのツールとして使用している場合は、Autoscalerによってもevictionによるリソースの最適化が処理が実行されることになります。 Autoscalerはリソースの需要が高い場合はノードを増やし、低い場合はノードを減らすような挙動をします。
GKE(Standardクラスタ)ではノードの自動スケジューリング(Kubernetes Autoscaler)を設定することができます。autoscalingを有効にすることで、ワークロードの需要に応じてノードプールにノードを追加してくれます。
以下は例
gcloud container clusters create example-cluster \
--num-nodes=2 \
--location=us-central1-a \
--node-locations=us-central1-a,us-central1-b,us-central1-f \
--enable-autoscaling --min-nodes=1 --max-nodes=4
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja
Autopilotクラスタの場合は、デフォルトでAutoscalingが有効になっているようです。ワークロードの要件に合わせて自動的にスケーリングされるため、ノードのプロビジョニングやノードプールの管理を行う必要がありません。
※ ノードの自動スケジューリング機能(Kubernetes Autoscaler)を有効にする場合は、Podで実行される処理が再実行されても問題ないような作りになっている必要があることに注意です。
運用中のクラスタで前述したノードのAutoscalerが有効になっているとします。 CronJobで実行するような実行時間が長いJobは実行中にevictionの対象になってしまう可能性が高いです。 あるCronJobで実行されたPodがevictionの対象になった場合は、AudoscalerからSIGTERMされます。その後、対象のPodは別のノードで再実行されることになります。
どのような挙動かは以下が以下の資料わかりやすいので、参照してください。
GKEのガイドにあるように中断を最小限にする必要のある処理については、evictionの対象にされると困るため(処理自体は再実行されても問題ない作りになっているべきですが、どうしても許容できない場合もあります)、AutoscalerはevictionからPodを保護する機能を用意しています。
Podにアノテーション(cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
)を設定することでevictionから保護することが可能です。
以下はtemplateにアノテーションを設定する例です。
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
metadata:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
spec:
containers:
- name: hello
image: busybox
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
ただし、リソースの最適化観点では不要なリソースを持つノードが長時間残る可能性があるため、多用は中止する必要があります。 基本的には、再実行されても問題ないようなアプリーケーション設計を行い、一部どうしても再実行の許されない処理に対して、evictionからの保護を設定するのが推奨されます。