第9章 ネットワークエッジ上にあるリモートワーカーノード

9.1. ネットワークエッジでのリモートワーカーノードの使用

ネットワークエッジにあるノードで OpenShift Container Platform クラスターを設定できます。このトピックでは、リモートワーカーノード と呼ばれます。リモートワーカーノードを含む通常のクラスターは、オンプレミスのマスターとワーカーノードを、クラスターに接続する他の場所にあるワーカーノードと統合します。このトピックは、リモートワーカーノードの使用のベストプラクティスに関するガイダンスを提供することを目的としており、特定の設定に関する詳細情報は含まれません。

リモートワーカーノードでのデプロイメントパターンの使用に関しては、さまざまな業界 (通信、小売、製造、政府など) で複数のユースケースがあります。たとえば、リモートワーカーノードを Kubernetes ゾーン に結合することで、プロジェクトとワークロードを分離して分離できます。

ただし、リモートワーカーノードを使用すると、高いレイテンシーの発生や、ネットワーク接続が断続的に失われるなどの問題が発生する可能性があります。リモートワーカーノードを含むクラスターの課題には、以下のようなものがあります。

  • ネットワーク分離: OpenShift Container Platform コントロールプレーンとリモートワーカーノードは、相互に通信できる必要があります。コントロールプレーンとリモートワーカーノードの間に距離があるため、ネットワークの問題が発生すると、この通信が妨げられる可能性があります。OpenShift Container Platform がネットワークの分離にどのように対応するか、およびクラスターへの影響を軽減する方法については、リモートワーカーノードを使用したネットワークの分離 を参照してください。
  • 停電: コントロールプレーンとリモートワーカーノードは別々の場所にあるため、リモートの場所での停電、またはそれぞれの場所からの任意の場所での停電により、クラスターに悪影響を及ぼす可能性があります。ノードの電力損失に OpenShift Container Platform がどのように対応するか、およびクラスターへの影響を軽減する方法については、リモートワーカーノードの電力損失 を参照してください。
  • 急激な高レイテンシーまたは一時的なスループットの低下: ネットワークの場合と同様に、クラスターとリモートワーカーノード間のネットワーク状態の変更は、クラスターに悪影響を及ぼす可能性があります。OpenShift Container Platform は、レイテンシーの問題に対するクラスターの反応を制御できる複数の ワーカーレイテンシープロファイル を提供します。

リモートワーカーノードを含むクラスターを計画する場合には、以下の制限に注意してください。

  • OpenShift Container Platform は、オンプレミスクラスターが使用するクラウドプロバイダー以外のクラウドプロバイダーを使用するリモートワーカーノードをサポートしません。
  • ワークロードを 1 つの Kubernetes ゾーンから別の Kubernetes ゾーンに移動すると、(特定のタイプのメモリーが異なるゾーンで利用できないなどの) システムや環境に関する課題により、問題が発生する可能性があります。
  • プロキシーおよびファイアウォールでは、本書では扱われていない追加的制限が出てくる可能性があります。ファイアウォールの設定 など、このような制限に対処する方法については、関連する OpenShift ContainerPlatform のドキュメントを参照してください。
  • コントロールプレーンとネットワークエッジノード間の L2/L3 レベルのネットワーク接続を設定および維持する必要があります。

9.1.1. リモートワーカーノードの追加

リモートワーカーノードをクラスターに追加するには、追加の考慮事項がいくつかあります。

  • コントロールプレーンとすべてのリモートワーカーノードの間でトラフィックをルーティングするには、ルートまたはデフォルトゲートウェイが配置されていることを確認する必要があります。
  • Ingress VIP をコントロールプレーンに配置する必要があります。
  • ユーザープロビジョニングインフラストラクチャー (UPI) を使用してリモートワーカーノードを追加することは、他のワーカーノードを追加することと同じです。
  • インストール時にインストーラーがプロビジョニングしたクラスターにリモートワーカーノードを追加するには、インストール前に install-config.yaml ファイルで各ワーカーノードのサブネットを指定します。DHCP サーバーに追加の設定は必要ありません。リモートワーカーノードはローカルプロビジョニングネットワークにアクセスできないため、仮想メディアを使用する必要があります。
  • プロビジョニングネットワークでデプロイされたインストーラーでプロビジョニングされたクラスターにリモートワーカーノードを追加するには、仮想メディアを使用してノードを追加するように、install-config.yaml ファイルで virtualMediaViaExternalNetwork フラグが true に設定されていることを確認します。リモートワーカーノードは、ローカルプロビジョニングネットワークにアクセスできません。PXE ではなく、仮想メディアを使用してデプロイする必要があります。さらに、DHCP サーバー内のリモートワーカーノードの各グループとコントロールプレーンノードの各サブネットを指定します。

9.1.2. リモートワーカーノードによるネットワーク分離

すべてのノードは、10 秒ごとに OpenShift Container Platform クラスターの Kubernetes Controller Manager Operator (kube コントローラー) にハートビートを送信します。クラスターがノードからハートビートを受信しない場合、OpenShift Container Platform は複数のデフォルトメカニズムを使用して応答します。

OpenShift Container Platform は、ネットワークパーティションやその他の中断に対して回復性を持たせるように設計されています。ソフトウェアのアップグレードの中断、ネットワーク分割、ルーティングの問題など、より一般的な中断の一部を軽減することができます。軽減策には、リモートワーカーノードの Pod が正しい CPU およびメモリーリソースの量を要求すること、適切なレプリケーションポリシーの設定、ゾーン間の冗長性の使用、ワークロードでの Pod の Disruption Budget の使用などが含まれます。

設定した期間後に kube コントローラーのノードとの接続が解除された場合、コントロールプレーンのノードコントローラーはノードの正常性を Unhealthy に更新し、ノードの Ready 状態を Unknown とマークします。この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。オンプレミスノードコントローラーは、effect が NoExecutenode.kubernetes.io/unreachable テイントをノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。

Deployment オブジェクト、または StatefulSet オブジェクトなどのワークロードコントローラーが、正常でないノードの Pod にトラフィックを転送し、他のノードがクラスターに到達できる場合、OpenShift Container Platform はトラフィックをノードの Pod から遠ざけます。クラスターに到達できないノードは、新しいトラフィックルーティングでは更新されません。その結果、それらのノードのワークロードは、正常でないノードに到達しようとします。

以下の方法で接続損失の影響を軽減できます。

  • デーモンセットを使用したテイントを容認する Pod の作成
  • ノードがダウンした場合に自動的に再起動する静的 Pod の使用
  • Kubernetes ゾーンを使用した Pod エビクションの制御
  • Pod のエビクションを遅延または回避するための Pod 容認の設定
  • ノードを正常でないとマークするタイミングを制御するように kubelet を設定します。

リモートワーカーノードを含むクラスターでこれらのオブジェクトを使用する方法の詳細は、リモートワーカーノードの戦略について を参照してください。

9.1.3. リモートワーカーノードの電源損失

リモートワーカーノードの電源がなくなったり、強制的な再起動を行う場合、OpenShift Container Platform は複数のデフォルトメカニズムを使用して応答します。

設定した期間後に Kubernetes Controller Manager Operator (kube コントローラー) のノードとの接続が解除された場合、コントロールプレーンはノードの正常性を Unhealthy に更新し、ノードの Ready 状態を Unknown とマークします。この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。オンプレミスノードコントローラーは、effect が NoExecutenode.kubernetes.io/unreachable テイントをノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。

ノードでは、ノードが電源を回復し、コントロールプレーンに再接続する際に、Pod を再起動する必要があります。

注記

再起動時に Pod をすぐに再起動する必要がある場合は、静的 Pod を使用します。

ノードの再起動後に kubelet も再起動し、ノードにスケジュールされた Pod の再起動を試行します。コントロールプレーンへの接続にデフォルトの 5 分よりも長い時間がかかる場合、コントロールプレーンはノードの正常性を更新して node.kubernetes.io/unreachable テイントを削除することができません。ノードで、kubelet は実行中の Pod をすべて終了します。これらの条件がクリアされると、スケジューラーはそのノードへの Pod のスケジューリングを開始できます。

以下の方法で、電源損失の影響を軽減できます。

  • デーモンセットを使用したテイントを容認する Pod の作成
  • ノードを使用して自動的に再起動する静的 Pod の使用
  • Pod のエビクションを遅延または回避するための Pod 容認の設定
  • ノードコントローラーがノードを正常でないとマークするタイミングを制御するための kubelet の設定

リモートワーカーノードを含むクラスターでこれらのオブジェクトを使用する方法の詳細は、リモートワーカーノードの戦略について を参照してください。

9.1.4. リモートワーカーへのレイテンシーの急上昇またはスループットの一時的な低下

クラスター管理者が遅延テストを実行してプラットフォームを検証した際に、遅延が大きい場合でも安定性を確保するために、クラスターの動作を調整する必要性が判明することがあります。クラスター管理者が変更する必要があるのは、ファイルに記録されている 1 つのパラメーターだけです。このパラメーターは、監視プロセスがステータスを読み取り、クラスターの健全性を解釈する方法に影響を与える 4 つのパラメーターを制御するものです。1 つのパラメーターのみを変更し、サポートしやすく簡単な方法でクラスターをチューニングできます。

Kubelet プロセスは、クラスターの健全性を監視する上での出発点です。Kubelet は、OpenShift Container Platform クラスター内のすべてのノードのステータス値を設定します。Kubernetes コントローラーマネージャー (kube controller) は、デフォルトで 10 秒ごとにステータス値を読み取ります。ノードのステータス値を読み取ることができない場合、設定期間が経過すると、kube controller とそのノードとの接続が失われます。デフォルトの動作は次のとおりです。

  1. コントロールプレーン上のノードコントローラーが、ノードの健全性を Unhealthy に更新し、ノードの Ready 状態を `Unknown` とマークします。
  2. この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。
  3. ノードライフサイクルコントローラーが、NoExecute effect を持つ node.kubernetes.io/unreachable テイントをノードに追加し、デフォルトでノード上のすべての Pod を 5 分後にエビクトするようにスケジュールします。

この動作は、ネットワークが遅延の問題を起こしやすい場合、特にネットワークエッジにノードがある場合に問題が発生する可能性があります。場合によっては、ネットワークの遅延が原因で、Kubernetes コントローラーマネージャーが正常なノードから更新を受信できないことがあります。Kubelet は、ノードが正常であっても、ノードから Pod を削除します。

この問題を回避するには、ワーカーレイテンシープロファイル を使用して、Kubelet と Kubernetes コントローラーマネージャーがアクションを実行する前にステータスの更新を待機する頻度を調整できます。これらの調整により、コントロールプレーンとワーカーノード間のネットワーク遅延が最適でない場合に、クラスターが適切に動作するようになります。

これらのワーカーレイテンシープロファイルには、3 つのパラメーターセットが含まれています。パラメーターは、遅延の増加に対するクラスターの反応を制御するように、慎重に調整された値で事前定義されています。試験により手作業で最良の値を見つける必要はありません。

クラスターのインストール時、またはクラスターネットワークのレイテンシーの増加に気付いたときはいつでも、ワーカーレイテンシープロファイルを設定できます。

9.1.5. リモートワーカーノードストラテジー

リモートワーカーノードを使用する場合は、アプリケーションを実行するために使用するオブジェクトを考慮してください。

ネットワークの問題や電源の損失時に必要とされる動作に基づいて、デーモンセットまたは静的 Pod を使用することが推奨されます。さらに、Kubernetes ゾーンおよび容認を使用して、コントロールプレーンがリモートワーカーノードに到達できない場合に Pod エビクションを制御したり、回避したりできます。

デーモンセット
デーモンセットは、以下の理由により、リモートワーカーノードでの Pod の管理に最適な方法です。
  • デーモンセットは通常、動作の再スケジュールを必要としません。ノードがクラスターから切断される場合、ノードの Pod は実行を継続できます。OpenShift Container Platform はデーモンセット Pod の状態を変更せず、Pod を最後に報告された状態のままにします。たとえば、デーモンセット Pod が Running 状態の際にノードが通信を停止する場合、Pod は実行し続けますが、これは OpenShift Container Platform によって実行されていることが想定されます。
  • デーモンセット Pod はデフォルトで、tolerationSeconds 値のない node.kubernetes.io/unreachable テイントおよび node.kubernetes.io/not-ready テイントの NoExecute 容認で作成されます。これらのデフォルト値により、コントロールプレーンがノードに到達できなくても、デーモンセット Pod がエビクトされることはありません。以下に例を示します。

    デフォルトでデーモンセット Pod に容認を追加

      tolerations:
        - key: node.kubernetes.io/not-ready
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/unreachable
          operator: Exists
          effect: NoExecute
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/memory-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/pid-pressure
          operator: Exists
          effect: NoSchedule
        - key: node.kubernetes.io/unschedulable
          operator: Exists
          effect: NoSchedule

  • デーモンセットは、ワークロードが一致するワーカーノードで実行されるように、ラベルを使用することができます。
  • OpenShift Container Platform サービスエンドポイントを使用してデーモンセット Pod の負荷を分散できます。
注記

デーモンセットは、OpenShift Container Platform がノードに到達できない場合、ノードの再起動後に Pod をスケジュールしません。

静的 Pod
ノードの再起動時に Pod を再起動する必要がある場合 (電源が切れた場合など)、静的な Pod を考慮してください。ノードの kubelet は、ノードの再起動時に静的 Pod を自動的に再起動します。
注記

静的 Pod はシークレットおよび設定マップを使用できません。

Kubernetes ゾーン
Kubernetes ゾーン は、速度を落としたり、または場合によっては Pod エビクションを完全に停止したりすることができます。

コントロールプレーンがノードに到達できない場合、デフォルトでノードコントローラーは node.kubernetes.io/unreachable テイントを適用し、1 秒あたり 0.1 ノードのレートで Pod をエビクトします。ただし、Kubernetes ゾーンを使用するクラスターでは、Pod エビクションの動作が変更されます。

ゾーンのすべてのノードに False または UnknownReady 状態が見られる、ゾーンが完全に中断された状態の場合、コントロールプレーンは node.kubernetes.io/unreachable テイントをそのゾーンのノードに適用しません。

(ノードの 55% 超が False または Unknown 状態である) 部分的に中断されたゾーンの場合、Pod のエビクションレートは 1 秒あたり 0.01 ノードに低減されます。50 未満の小規模なクラスターにあるノードにテイントは付けられません。これらの動作を有効にするには、クラスターに 4 つ以上のゾーンが必要です。

ノード仕様に topology.kubernetes.io/region ラベルを適用して、ノードを特定のゾーンに割り当てます。

Kubernetes ゾーンのノードラベルの例

kind: Node
apiVersion: v1
metadata:
  labels:
    topology.kubernetes.io/region=east

KubeletConfig オブジェクト

kubelet が各ノードの状態をチェックする時間を調整することができます。

オンプレミスノードコントローラーがノードを Unhealthy または Unreachable 状態にマークするタイミングに影響を与える間隔を設定するには、node-status-update-frequency および node-status-report-frequency パラメーターが含まれる KubeletConfig オブジェクトを作成します。

各ノードの kubelet は node-status-update-frequency 設定で定義されたノードのステータスを判別し、node-status-report-frequency 設定に基づいてそのステータスをクラスターに報告します。デフォルトで、kubelet は 10 秒ごとに Pod のステータスを判別し、毎分ごとにステータスを報告します。ただし、ノードの状態が変更されると、kubelet は変更をクラスターに即時に報告します。OpenShift Container Platform は、Node Lease フィーチャーゲートが有効にされている場合にのみ、node-status-report-frequency 設定を使用します。これは OpenShift Container Platform クラスターのデフォルト状態です。Node Lease フィーチャーゲートが無効になっている場合、ノードは node-status-update-frequency 設定に基づいてノードのステータスを報告します。

kubelet 設定の例

apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  name: disable-cpu-units
spec:
  machineConfigPoolSelector:
    matchLabels:
      machineconfiguration.openshift.io/role: worker 1
  kubeletConfig:
    node-status-update-frequency: 2
      - "10s"
    node-status-report-frequency: 3
      - "1m"

1
MachineConfig オブジェクトのラベルを使用して、この KubeletConfig オブジェクトが適用されるノードタイプを指定します。
2
kubelet がこの MachineConfig オブジェクトに関連付けられたノードのステータスをチェックする頻度を指定します。デフォルト値は 10s です。このデフォルト値を変更すると、node-status-report-frequency の値は同じ値に変更されます。
3
kubelet がこの MachineConfig オブジェクトに関連付けられたノードのステータスを報告する頻度を指定します。デフォルト値は 1m です。

node-status-update-frequency パラメーターは node-monitor-grace-period および pod-eviction-timeout パラメーターと共に機能します。

  • node-monitor-grace-period パラメーターは、コントローラーマネージャーがハートビートを受信しない場合に、この MachineConfig オブジェクトに関連付けられたノードが Unhealthy とマークされた後に、OpenShift Container Platform が待機する時間を指定します。この待機時間後も、ノード上のワークロードは引き続き実行されます。node-monitor-grace-period の期限が切れた後にリモートワーカーノードがクラスターに再度加わる場合、Pod は実行を継続します。新規 Pod をノードにスケジュールできます。node-monitor-grace-period の間隔は 40s です。node-status-update-frequency の値は、node-monitor-grace-period の値よりも低い値である必要があります。
  • pod-eviction-timeout パラメーターは、MachineConfig オブジェクトに関連付けられたノードを Unreachable としてマークした後、エビクション用に Pod のマークを開始するまでに OpenShift Container Platform が待機する時間を指定します。エビクトされた Pod は、他のノードで再スケジュールされます。pod-eviction-timeout の期限が切れた後にリモートワーカーノードがクラスターに再結合する場合、ノードコントローラーがオンプレミスで Pod をエビクトしたため、リモートワーカーノードで実行されている Pod は終了します。続いて、Pod をそのノードに再スケジュールできます。pod-eviction-timeout の期間は 5m0s です。
注記

node-monitor-grace-period および pod-eviction-timeout パラメーターを変更することはサポートされていません。

容認
オンプレミスノードコントローラーが、effect が NoExecutenode.kubernetes.io/unreachable テイントを到達できないノードに追加する場合、Pod 容認を使用して effect を軽減することができます。

effect が NoExecute のテイントは、ノードですでに実行中の Pod に以下のような影響を及ぼします。

  • テイントを容認しない Pod は、エビクションのキューに置かれます。
  • 容認の仕様に tolerationSeconds 値を指定せずにテイントを容認する Pod は、永久にバインドされたままになります。
  • 指定された tolerationSeconds 値でテイントを容認する Pod は、指定された期間バインドされます。時間が経過すると、Pod はエビクションのキューに置かれます。

effect が NoExecutenode.kubernetes.io/unreachable テイントおよび node.kubernetes.io/not-ready テイントで Pod の容認を設定し、Pod のエビクションを遅延したり回避したりできます。

Pod 仕様での容認の例

...
tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute" 1
- key: "node.kubernetes.io/not-ready"
  operator: "Exists"
  effect: "NoExecute" 2
  tolerationSeconds: 600
...

1
tolerationSeconds のない NoExecute effect により、コントロールプレーンがノードに到達する場合は Pod が永続的に残ります。
2
tolerationSeconds: 600 の NoExecute effect により、コントロールプレーンがノードに Unhealthy のマークを付ける場合に Pod が 10 分間そのまま残ります。

OpenShift Container Platform は、pod-eviction-timeout 値の経過後、tolerationSeconds 値を使用します。

OpenShift Container Platform オブジェクトの他のタイプ
レプリカセット、デプロイメント、およびレプリケーションコントローラーを使用できます。スケジューラーは、ノードが 5 分間切断された後、これらの Pod を他のノードに再スケジュールできます。他のノードへの再スケジュールは、管理者が特定数の Pod を確実に実行し、アクセスできるようにする REST API などの一部のワークロードにとって有益です。
注記

リモートワーカーノードを使用する際に、リモートワーカーノードが特定の機能用に予約されることが意図されている場合、異なるノードでの Pod の再スケジュールは許容されない可能性があります。

ステートフルセット は、停止時に再起動されません。Pod は、コントロールプレーンが Pod の終了を認識できるまで、terminating 状態のままになります。

同じタイプの永続ストレージにアクセスできないノードにスケジュールしないようにするため、OpenShift Container Platform では、ネットワークの分離時に永続ボリュームを必要とする Pod を他のゾーンに移行することはできません。

関連情報