技術系TIPS
PR

KubernetesのPDBでminAvailableに1を設定するとdrainに失敗する

saratogax
記事内に商品プロモーションを含む場合があります

普段、PodDisruptionBudget(PDB)には以下の設定を入れているのですが、

maxUnavailable: 1

テスト環境など pod を冗長化させていない場合に、drain(ドレイン)など pod の削除と作成が同時に発生する場面で通信断が発生します。

rollout restart deployment」のような動きをしてくれるといいのですが、このあたりとは仕組みが異なるようです。

今回は minAvailable を設定した時の挙動と問題について紹介していきます。

やりたかったこと

pod が 1 台しか起動していない状態で drain が実行された時、移行先の node(ノード)で新しい pod が起動した後、移行元の pod が削除されてほしい。

minAvailable に 1 を設定すれば、最低でも 1 台の pod が起動していないといけないハズなので、drain 時の挙動も変わるのではないかという想定でした。

PodDisruptionBudget(PDB)の設定

PDB の設定では、以下の 2 つを同時に定義することができません。

・maxUnavailable
・minAvailable

よって、元々設定していた maxUnavailable の設定を削除し、新たに minAvailable の設定を追加します。

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

この時、以下の両方のコマンドの挙動はこれまでと変わらず、特に問題なく操作できました。

kubectl rollout restart deployment hoge

kubectl delete pod hoge-xxxxxxxxxx-xxxxx

ただ、minAvailable を設定したにも関わらず「delete pod」の動きに変化がない・・・。

これまでと変わらず pod の作成と削除が同時に発生するので、このケースでは minAvailable の設定は考慮されないのか。

これだと通信断が発生するので、drain(ドレイン)の動きにも期待が持てません。

drain(ドレイン)時に発生したエラー

では、この hoge のアプリが存在する node(ノード)を cordon して、別の node に移してみましょう。

drain 時に cordon されますが、明示的に cordon しておきます。

kubectl cordon [node]

それでは drain を実行。

kubectl drain –delete-emptydir-data –ignore-daemonsets [node]

順調に pod の入れ替えが発生していくのですが、PDB の設定を変更したアプリのみ以下のエラーが発生します。

evicting pod hoge-xxxxxxxxxx-xxxxx
error when evicting pods/”hoge-xxxxxxxxxx-xxxxx” (will retry after 5s): Cannot evict pod as it would violate the pod’s disruption budget.

どうやら pod を削除できないというエラーのようです。

原因と対策

同様の問題を探ってみたところ、以下の記事に行き当たりました。

minAvailable の設定前と設定後の「poddisruptionbudgets.policy」の結果を確認してみると確かに異なります。

maxUnavailable: 1

「Allowed disruptions」が 1 になっています。

Name:             hoge
Namespace:        xxxxxx
Max unavailable:  1
Selector:         app=hoge
Status:
    Allowed disruptions:  1
    Current:              1
    Desired:              0
    Total:                1
Events:                   <none>

minAvailable: 1

「Allowed disruptions」が 0 になっています。

Name:           hoge
Namespace:      xxxxxx
Min available:  1
Selector:       app=hoge
Status:
    Allowed disruptions:  0
    Current:              1
    Desired:              1
    Total:                1
Events:                   <none>

まとめ

deployment では replicas が 1 なので、この場合だと難しそうですね。

kubectl get deployment hoge -o yaml

ちなみに、スケールの設定は HorizontalPodAutoscaler(HPA)で設定しており、minReplicas が 1、maxReplicas が 3 です。

やはり 1 台だけで稼働させているテスト的な環境では、drain 時の一時的な通信断は避けられないかなぁ。

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました