💭

Kubernetes における PDB の動作確認 ( minAvailable 編 )

2023/11/09に公開

はじめに

今回は Kubernetes における Pod Disruption Budget ( 以下、 PDB ) についての検証記事です。
https://kubernetes.io/docs/tasks/run-application/configure-pdb/

n 番煎じではありますが、意外と忘れがちなのと細かい動作を確認したかったので備忘録です。

今回は PDB の中でも特に minAvailable の設定時の挙動についての確認です。

目的

Controller などで普段は冗長化するまでもなく 1 Pod で稼働しているが、ノードの移動時などにも常に最低 1 Pod 以上稼働していて欲しいワークロードに対する PDB の最適解を求める。

結論

replicas: 1 のワークロードに対して PDB の minAvailable を用いた最低 1 Pod 以上での稼働制御はできないので PDB を無効化する or replicas を 2 以上で運用しましょう。

環境

Kubernetes

GKE 1.24.10-gke.2300
ノードプールにはオートスケールの設定を適用済み

ワークロード

本当に最低限の Nginx を利用します。

apiVersion: v1
kind: Namespace
metadata:
  name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

確認手順

上記の Nginx が配置されているノードに対して kubectl cordon ***kubectl drain *** --ignore-daemonsets を実行します。
この際に、 Nginx の Pod がどのように起動 / 終了されるのかを確認します。

確認内容

PDB を設定しない場合

Nginx が配置されているノードを drain した直後に稼働中の Pod が terminate され、新しい別のノード上で create されました。
PDB が設定されていないので想定通り、 terminate → create になるためワークロードの瞬断が起きる可能性があります。

nginx-7cdf44cc7b-clkrx   1/1     Running             0          48s     172.20.1.5   gke-tetsuya28-tetsuya28-03af8d09-rrn7   <none>           <none>
nginx-7cdf44cc7b-clkrx   1/1     Terminating         0          3m31s   172.20.1.5   gke-tetsuya28-tetsuya28-03af8d09-rrn7   <none>           <none>
nginx-7cdf44cc7b-t25zr   0/1     Pending             0          0s      <none>       <none>                                  <none>           <none>
nginx-7cdf44cc7b-t25zr   0/1     Pending             0          0s      <none>       gke-tetsuya28-tetsuya28-1c3e9e37-btdg   <none>           <none>
nginx-7cdf44cc7b-t25zr   0/1     ContainerCreating   0          0s      <none>       gke-tetsuya28-tetsuya28-1c3e9e37-btdg   <none>           <none>
nginx-7cdf44cc7b-t25zr   0/1     Terminating         0          0s      <none>       gke-tetsuya28-tetsuya28-1c3e9e37-btdg   <none>           <none>

minAvailable: 1 の PDB を設定した場合

上記のワークロードに以下の PDB を設定します。これにより、 Nginx は最低でも 1 つ以上の Pod が稼働していることを保証します。

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx
  namespace: nginx
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: nginx

先ほどと同様にノードに対して cordon → drain を行うと以下のメッセージとともに Nginx Pod の terminate が実行されない状態となります。

evicting pod nginx/nginx-7cdf44cc7b-drzkj
error when evicting pods/"nginx-7cdf44cc7b-drzkj" -n "nginx" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.

これは Nginx Deployment に replicas: 1 と指定しているため 2 Pod 目が作成できない & PDB により 1 つ目の Pod も削除できないためデッドロックのような状態となっています。

試しに以下のように replicas: 2 とすると想定通り、先に 2 つ目の Pod が create され、その後 1 つ目の Pod が terminate されます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: nginx
spec:
  selector:
    matchLabels:
      app: nginx
-  replicas: 1
+  replicas: 2

しかし、これでは当初の「平常時は replicas: 1 で運用する」という要件を満たせなくなります。

結果、ここまで検証しましたが、 PDB を設定したい場合 replicas: 2 以上で運用する or 一時的なダウンタイムを許容して PDB を設定しないの二択になるかと思います。

参考リンク

https://nonylene.hatenablog.jp/entry/2021/05/23/175910

Discussion