ノードを安全にドレインする

このページでは、ノードを安全にドレインする方法を示します。 オプションで、定義されたPodDisruptionBudgetを考慮することも可能です。

始める前に

このタスクを実行するには、以下のいずれかの前提条件を満たしている必要があります:

  1. ノードのドレイン中にアプリケーションの高可用性を必要としない
  2. PodDisruptionBudgetの概念に関する記事を読み、必要とするアプリケーションに対してPodDisruptionBudgetを設定していること

(オプション)Disruption Budgetを設定する

メンテナンス中もワークロードの可用性を維持するために、PodDisruptionBudgetを設定できます。

ドレイン対象のノード上で動作している、または今後動作する可能性のあるアプリケーションにとって可用性が重要である場合は、まずPodDisruptionBudgetを設定してから、このガイドに従ってください。

ノードのドレイン中に不具合のあるアプリケーションの削除を許容するため、PodDisruptionBudgetにはAlwaysAllowUnhealthyPodEvictionPolicyを設定することが推奨されます。 デフォルトの挙動では、アプリケーションのPodが健全になるまで、ドレインは実行されません。

kubectl drainを使ってノードをサービスから除外する

ノードに対してメンテナンス(例: カーネルのアップグレードやハードウェアのメンテナンスなど)を行う前に、kubectl drainを使用して、そのノード上のすべてのPodを安全に退避させることができます。 安全に退避すると、Podのコンテナが正常に終了し、指定したPodDisruptionBudgetも尊重されます。

kubectl drainが正常に終了した場合、それは(前段で述べた除外対象を除く)すべてのPodが安全に削除されたことを示します(望ましい正常終了期間および定義されたPodDisruptionBudgetは尊重されます)。 その時点で、ノードを停止しても安全です。 物理マシンの場合は電源を落とすことができ、クラウドプラットフォーム上であれば仮想マシンを削除しても差し支えありません。

まず、ドレインしたいノードの名前を特定します。 クラスター内のすべてのノードは、次のコマンドで一覧表示できます:

kubectl get nodes

次に、ノードをドレインするようにKubernetesに指示します:

kubectl drain --ignore-daemonsets <node name>

DaemonSetによって管理されているPodが存在する場合は、ノードを正常にドレインするために、kubectl--ignore-daemonsetsを指定する必要があります。 kubectl drainサブコマンド単体では、実際にはDaemonSetのPodをノードからドレインしません: DaemonSetコントローラー(コントロールプレーンの一部)は、欠落したPodをただちに同等の新しいPodで置き換えます。 また、DaemonSetコントローラーはスケジューリング不可のtaintを無視するPodも作成するため、ドレイン中のノード上に新しいPodが起動されることがあります。

エラーなくコマンドが完了したら、そのノードの電源を切ることができます(あるいは同等に、クラウドプラットフォーム上であれば、そのノードに対応する仮想マシンを削除することもできます)。 メンテナンス作業中にそのノードをクラスターに残しておいた場合は、作業完了後にKubernetesがそのノードへのPodのスケジューリングを再び可能にするために、次のコマンドを実行してください。

kubectl uncordon <node name>

複数ノードの並列ドレイン

kubectl drainコマンドは、一度に1つのノードに対してのみ発行すべきです。 ただし、異なるノードに対して、複数のkubectl drainコマンドを異なるターミナルまたはバックグラウンドで並行で実行することは可能です。 複数のドレインコマンドが同時に実行されていても、指定したPodDisruptionBudgetは引き続き順守されます。

たとえば、3つのレプリカを持つStatefulSetがあり、そのセットに対してminAvailable: 2を指定したPodDisruptionBudgetを設定している場合、kubectl drainは、3つのレプリカのPodがすべて健全である場合にのみ、そのStatefulSetのPodを退避させます。 このとき、複数のドレインコマンドを並行して発行した場合でも、KubernetesはPodDisruptionBudgetを順守し、任意の時点で使用不能なPodが1つ(replicas - minAvailableで計算)にとどまるように制御します。 健全なレプリカの数が指定したバジェットを下回る原因となるようなドレイン操作はブロックされます。

Eviction API

kubectl drainを使用したくないとき(外部コマンドの呼び出しを避けたい場合や、Podの退避プロセスをより細かく制御したい場合など)は、Eviction APIを用いてプログラムから退避を実行することもできます。

詳細は、APIを基点とした退避を参照してください。

次の項目