今回はNode削除時の挙動について、ご紹介します。
Nodeのスケーリング状態
k8sではPodの配置に対して、2つの状態があります。
- SchedulingEnabled:新規のPodがNodeに作成可能な状態
- SchedulingDisabled:新規のPodはNodeに作成不可な状態
※Scheduling:Podをどのノードに配置することを意味する
イメージとしては、以下のようになります。
状態の切り替えはkubectlコマンドで設定可能です。
# cordon:SchedulingDisabledにする
kubectl cordon <Node名>
# uncordon:SchedulingEnabledにする
kubectl cordon <Node名>
# 全Node状態を確認
kubectl get nodes
注意が必要なのは、Nodeのスケーリング状態は新規Podのスケーリングにのみ影響するので、既に存在しているPodには影響しません。
Node内Podの排出処理
Cordonは新規Podに対して制御できますが、既にスケジューリング済みのPodはどうすれば追い出せますでしょうか。
ここで使うのはk8sのdrain(排出)処理です。
このdrain処理の本質は、「kubectl cordon」 + 「kubectl delete pods」 と考えてれば、イメージし易いと思います。
※PodがReplicaSetやDeploymentに管理されている場合、削除されても自動的SchedulingEnabledのNodeで作成されます。
実行コマンド:
# drain処理
kubectl drain <Node名>
drain不可状態
drainを実施する時、以下のケースの場合エラーが表示されます
- Nodeに親リソースのないPodが存在している場合
- 解決策:
--force
オプション付けて、強制削除 - 注意点:親リソースがないので、drainすると、Podはさっぱり消えてしまう
- 解決策:
- Podがlocal storageを使っている場合
- 解決策:
--delete-local-data
オプション付けて削除 - 注意点:データが消えてしまう
- 解決策:
- DaemonSet管理されているPodがある場合
- 解決策:
--ignore-daemonset
オプション付けて削除
- 解決策:
PodDisruptionBudget(PDB)
manifestのリソース指定:
kind: PodDisruptionBudget
PodDisruptionBudgetは、公式ドキュメントでは以下のように説明されています。
An Application Owner can create a PodDisruptionBudget object (PDB) for each application. A PDB limits the number of pods of a replicated application that are down simultaneously from voluntary disruptions.
要するに、spec.selectorにマッチしているPodの稼働個数を保証するためのリソースです。
例えば、labelがappのPod群が偶にすべて同じNodeにスケジューリングされるとしたら、そのNodeをdrainすると、このラベルのすべてのPodが一時的に全滅します。
そうすると、アプリにダウンタイムが発生する可能性があります。
PodDisruptionBudget(PDB)を事前に定義すると、こう言ったリスクを回避することができます。
PodDisruptionBudget(PDB)は以下の設定が可能です。
spec.minAvailable
:条件にあったPodの最小同時起動数spec.maxUnavailable
:条件にあったPodの最大同時停止数
manifest例
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: myapp
spec:
minAvailable: 30% # Podの最小同時起動数、%指定可能
maxUnavailable: 1 # Podの最大同時停止数、個数指定可能
selector: # 条件
matchLabels:
app: sample-app
最後に
今回はNode停止するための準備設定について、ご紹介しました。
Nodeを削除する前に、事前に上記の設定内容を考えて行っていきましょう。
ここまで読んでいただいて、お疲れ様でした。
コメント