5.8. ノードの再起動について

プラットフォームで実行されているアプリケーションを停止せずにノードを再起動するには、まず Pod の退避を実行することが重要です。ルーティング階層によって可用性が高くなっている Pod については、何も実行する必要はありません。ストレージ (通常はデータベース) を必要とするその他の Pod については、1 つの Pod が一時的にオフラインになってもそれらの Pod が作動状態を維持できることを確認する必要があります。ステートフルな Pod の回復性はアプリケーションごとに異なりますが、いずれの場合でも、ノードの非アフィニティー (node anti-affinity) を使用して Pod が使用可能なノードにわたって適切に分散するようにスケジューラーを設定することが重要になります。

別の課題として、ルーターやレジストリーのような重要なインフラストラクチャーを実行しているノードを処理する方法を検討する必要があります。同じノードの退避プロセスが適用されますが、一部のエッジケースについて理解しておくことが重要です。

5.8.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 を見つけるのを防ぎます。

関連情報

5.8.2. Pod の非アフィニティーを使用するノードの再起動

Pod の非アフィニティーは、ノードの非アフィニティーとは若干異なります。ノードの非アフィニティーの場合、Pod のデプロイ先となる適切な場所が他にない場合には違反が生じる可能性があります。Pod の非アフィニティーの場合は required (必須) または preferred (優先) のいずれかに設定できます。

これが有効になっていると、2 つのインフラストラクチャーノードのみが利用可能で、1 つのノードが再起動される場合に、コンテナーイメージレジストリー Pod は他のノードで実行できなくなります。oc get pods は、適切なノードが利用可能になるまで Pod を Unready (準備が未完了) として報告します。ノードが利用可能になり、すべての Pod が Ready (準備ができている) 状態に戻ると、次のノードを再起動することができます。

手順

Pod の非アフィニティーを使用してノードを再起動するには、以下の手順を実行します。

  1. ノードの仕様を編集して 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
    1
    Pod の非アフィニティーを設定するためのスタンザです。
    2
    preferred (優先) ルールを定義します。
    3
    preferred (優先) ルールの重みを指定します。最も高い重みを持つノードが優先されます。
    4
    非アフィニティールールが適用される時を決定する Pod ラベルの説明です。ラベルのキーおよび値を指定します。
    5
    演算子は、既存 Pod のラベルと新規 Pod の仕様の matchExpression パラメーターの値のセットの間の関係を表します。これには InNotInExists、または DoesNotExist のいずれかを使用できます。

    この例では、コンテナーイメージレジストリー Pod に registry=default のラベルがあることを想定しています。Pod の非アフィニティーでは任意の Kubernetes の一致式を使用できます。

  2. スケジューリングポリシーファイルで、MatchInterPodAffinity スケジューラー述語を有効にします。
  3. ノードの正常な再起動を実行します。

5.8.3. ルーターを実行しているノードを再起動する方法について

ほとんどの場合、OpenShift Container Platform ルーターを実行している Pod はホストポートを公開します。

PodFitsPorts スケジューラー述語は、同じポートを使用するルーター Pod が同じノード上で実行できないようにし、Pod の非アフィニティーが確保されるようにします。ルーターが高可用性を確保するために IP フェイルオーバーに依存する場合は、他に必要な設定等はありません。

高可用性のための AWS Elastic Load Balancing のような外部サービスに依存するルーター Pod の場合は、ルーターの再起動に対応するサービスが必要になります。

ルーター Pod でホストのポートが設定されていないということも稀にあります。この場合は、インフラストラクチャーノードについての推奨される再起動プロセスに従う必要があります。

5.8.4. ノードを正常に再起動する

ノードを再起動する前に、ノードでのデータ損失を回避するために、etcd データをバックアップすることをお勧めします。

注記

クラスターを管理するために kubeconfig ファイルに証明書を持たせるのではなく、ユーザーが oc login コマンドを実行する必要があるシングルノードの OpenShift クラスターでは、ノードの遮断およびドレイン後に oc adm コマンドが使用できない場合があります。これは、遮断により openshift-oauth-apiserver Pod が実行されないためです。以下の手順で示したように、SSH を使用してノードにアクセスできます。

シングルノードの OpenShift クラスターでは、遮断およびドレイン時に Pod の再スケジューリングはできません。しかし、そうすることで、Pod、特にワークロード Pod が適切に停止し、関連するリソースを解放する時間を得ることができます。

手順

ノードの正常な再起動を実行するには:

  1. ノードにスケジュール対象外 (unschedulable) のマークを付けます。

    $ oc adm cordon <node1>
  2. ノードをドレインして、実行中のすべての Pod を削除します。

    $ oc adm drain <node1> --ignore-daemonsets --delete-emptydir-data --force

    カスタムの 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
  3. デバッグモードでノードにアクセスします。

    $ oc debug node/<node1>
  4. ルートディレクトリーを /host に変更します。

    $ chroot /host
  5. ノードを再起動します。

    $ systemctl reboot

    すぐに、ノードは NotReady 状態になります。

    注記

    一部のシングルノード OpenShift クラスターでは、openshift-oauth-apiserver Pod が実行されていないため、ノードの遮断およびドレイン後に oc コマンドが使用できない場合があります。SSH でノードに接続し、リブートを実行することができます。

    $ ssh core@<master-node>.<cluster_name>.<base_domain>
    $ sudo systemctl reboot
  6. 再起動が完了したら、以下のコマンドを実行して、ノードをスケジューリング可能な状態にします。

    $ oc adm uncordon <node1>
    注記

    一部のシングルノード OpenShift クラスターでは、openshift-oauth-apiserver Pod が実行されていないため、ノードの遮断およびドレイン後に oc コマンドが使用できない場合があります。SSH を使用してノードに接続し、ノードの遮断を解除します。

    $ ssh core@<target_node>
    $ sudo oc adm uncordon <node> --kubeconfig /etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost.kubeconfig
  7. ノードの準備ができていることを確認します。

    $ oc get node <node1>

    出力例

    NAME    STATUS  ROLES    AGE     VERSION
    <node1> Ready   worker   6d22h   v1.18.3+b0068a8

関連情報

etcd データのバックアップの詳細については、Backing up etcd data を参照してください。