replicaCount: 1 と Drain とダウンタイム
Kubernetes で Node を Drain するとき、replicaCount: 1 な ReplicaSet (Service) はある程度のダウンダイムを許容せざるを得ない。
関連 issue は以下。
問題
- ReplicaSet X があり、その replicaCount は 1 にしている
- また、同じ Selector で Service X を作成している
- Node A に ReplicaSet X の Pod X1 が 1つある
状況で Node A を Drain すると、
- Pod X1 が Terminate される
- ReplicaSet X に設定した replicaCount に従って、新しい Pod X2 が別の Node に立つ
といった挙動となり、Pod X1 が Terminate されてから Pod X2 が Ready になるまでは Service X に属する Ready な Pod がない状態になる。その結果、ダウンタイムが生じる。
Terminate されてから Pod が Scheduling されるまではほとんど同時なので、ダウンタイムは Container のセットアップが終わるまでの時間と大体同じになる。
PDB は無力
このような問題の対策として Pod Disruption Budget (PDB) で minAvailable を設定することが考えられるが、残念ながら replicaCount: 1 の場合は仕様上うまく動かない。
PDB は Drain の抑制を行うものの、レプリカ数を良い感じに調整してくれるものではない。なので、上の条件からさらに PDB で minAvailable を 1 に設定した状態で Node A を Drain すると、
- Pod X1 は PDB があるので Terminate されない
- ReplicaSet X から見ると Pod X1 が Healthy な状態で存在しているので、新たな Pod を別 Node にスケジューリングを行うこともしない
ということで単に Pod X1 が消えずに Node A が一生 Drain されないことになる。
どうするか?
Issue にある通り replicaCount が1つである限りどうしようもないので、replicaCount を増やすことになる。
replicaCount を増やす
replicaCount を増やすと 1 つの Node が死んでも別の Pod が生きており、ダウンタイムは生じない。PDB があると複数ノードが同時に Drain されることも抑制されるのでなお良い。
Drain 前に rollup して Drain 後に rolldown する
要するに replicaCount を一時的に増やす。
…このように replicaCount を増やすのが正攻法だと思うが、今回は個人のどうでもいいクラスタなので、コンテナが立つまでの十数秒のダウンタイムは許容することにした。