5.6. ノードの再起動について
プラットフォームで実行されているアプリケーションを停止せずにノードを再起動するには、まず Pod の退避を実行することが重要です。ルーティング階層によって可用性が高くなっている Pod については、何も実行する必要はありません。ストレージ (通常はデータベース) を必要とするその他の Pod については、1 つの Pod が一時的にオフラインになってもそれらの Pod が作動状態を維持できることを確認する必要があります。ステートフルな Pod の回復性はアプリケーションごとに異なりますが、いずれの場合でも、ノードの非アフィニティー (node anti-affinity) を使用して Pod が使用可能なノードにわたって適切に分散するようにスケジューラーを設定することが重要になります。
別の課題として、ルーターやレジストリーのような重要なインフラストラクチャーを実行しているノードを処理する方法を検討する必要があります。同じノードの退避プロセスが適用されますが、一部のエッジケースについて理解しておくことが重要です。
5.6.1. 重要なインフラストラクチャーを実行するノードの再起動について
ルーター Pod、レジストリー Pod、モニターリング Pod などの重要な OpenShift Container Platform インフラストラクチャーコンポーネントをホストするノードを再起動する場合、これらのコンポーネントを実行するために少なくとも 3 つのノードが利用可能であることを確認します。
以下のシナリオは、2 つのノードのみが利用可能な場合に、どのように OpenShift Container Platform で実行されているアプリケーションでサービスの中断が生じ得るかを示しています。
- ノード A がスケジュール対象外としてマークされており、すべての Pod の退避が行われている。
- このノードで実行されているレジストリー Pod がノード B に再デプロイされる。 ノード B が両方のレジストリー Pod を実行しています。
- ノード B はスケジュール対象外としてマークされ、退避が行われる。
- ノード B の 2 つの Pod エンドポイントを公開するサービスは、それらがノード A に再デプロイされるまでの短い期間にすべてのエンドポイントを失う。
インフラストラクチャーコンポーネントの 3 つのノードを使用する場合、このプロセスではサービスの中断が生じません。しかし、Pod のスケジューリングにより、退避してローテーションに戻される最後のノードにはレジストリー Pod がありません。他のノードのいずれかには 2 つのレジストリー Pod があります。3 番目のレジストリー Pod を最後のノードでスケジュールするには、Pod の非アフィニティーを使用してスケジューラーが同じノード上で 2 つのレジストリー Pod を見つけるのを防ぎます。
関連情報
- Pod の非アフィニティーについての詳細は、 アフィニティールールと非アフィニティールールの使用による他の Pod との相対での Pod の配置 について参照してください。
5.6.2. Pod の非アフィニティーを使用するノードの再起動
Pod の非アフィニティーは、ノードの非アフィニティーとは若干異なります。ノードの非アフィニティーの場合、Pod のデプロイ先となる適切な場所が他にない場合には違反が生じる可能性があります。Pod の非アフィニティーの場合は required (必須) または preferred (優先) のいずれかに設定できます。
これが有効になっていると、2 つのインフラストラクチャーノードのみが利用可能で、1 つのノードが再起動される場合に、コンテナーイメージレジストリー Pod は他のノードで実行できなくなります。oc get pods
は、適切なノードが利用可能になるまで Pod を Unready (準備が未完了) として報告します。ノードが利用可能になり、すべての Pod が Ready (準備ができている) 状態に戻ると、次のノードを再起動することができます。
手順
Pod の非アフィニティーを使用してノードを再起動するには、以下の手順を実行します。
ノードの仕様を編集して Pod の非アフィニティーを設定します。
apiVersion: v1 kind: Pod metadata: name: with-pod-antiaffinity spec: affinity: podAntiAffinity: 1 preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 100 3 podAffinityTerm: labelSelector: matchExpressions: - key: registry 4 operator: In 5 values: - default topologyKey: kubernetes.io/hostname
この例では、コンテナーイメージレジストリー Pod に
registry=default
のラベルがあることを想定しています。Pod の非アフィニティーでは任意の Kubernetes の一致式を使用できます。-
スケジューリングポリシーファイルで、
MatchInterPodAffinity
スケジューラー述語を有効にします。 - ノードの正常な再起動を実行します。
5.6.3. ルーターを実行しているノードを再起動する方法について
ほとんどの場合、OpenShift Container Platform ルーターを実行している Pod はホストポートを公開します。
PodFitsPorts
スケジューラー述語は、同じポートを使用するルーター Pod が同じノード上で実行できないようにし、Pod の非アフィニティーが確保されるようにします。ルーターが高可用性を確保するために IP フェイルオーバーに依存する場合は、他に必要な設定等はありません。
高可用性のための AWS Elastic Load Balancing のような外部サービスに依存するルーター Pod の場合は、ルーターの再起動に対応するサービスが必要になります。
ルーター Pod でホストのポートが設定されていないということも稀にあります。この場合は、インフラストラクチャーノードについての推奨される再起動プロセスに従う必要があります。
5.6.4. ノードを正常に再起動する
ノードを再起動する前に、ノードでのデータ損失を回避するために、etcd データをバックアップすることをお勧めします。
手順
ノードの正常な再起動を実行するには:
ノードにスケジュール対象外 (unschedulable) のマークを付けます。
$ oc adm cordon <node1>
ノードをドレインして、実行中のすべての Pod を削除します。
$ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data
カスタムの Pod の Disruption Budget (停止状態の予算、PDB) 関連付けられた Pod を退避できないというエラーが発生することがあります。
エラーの例
error when evicting pods/"rails-postgresql-example-1-72v2w" -n "rails" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
この場合、drain コマンドを再度実行し、
disable-eviction
フラグを追加し、PDB チェックを省略します。$ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force --disable-eviction
デバッグモードでノードにアクセスします。
$ oc debug node/<node1>
ルートディレクトリーをホストに切り替えます。
$ chroot /host
ノードを再起動します。
$ systemctl reboot
すぐに、ノードは
NotReady
状態になります。再起動が完了したら、以下のコマンドを実行して、ノードをスケジューリング可能な状態にします。
$ oc adm uncordon <node1>
ノードの準備ができていることを確認します。
$ oc get node <node1>
出力例
NAME STATUS ROLES AGE VERSION <node1> Ready worker 6d22h v1.18.3+b0068a8
関連情報
etcd データのバックアップの詳細については、Backing up etcd data を参照してください。