第8章 ネットワークエッジ上にあるリモートワーカーノード
8.1. ネットワークエッジでのリモートワーカーノードの使用
ネットワークエッジにあるノードで OpenShift Container Platform クラスターを設定できます。このトピックでは、リモートワーカーノード と呼ばれます。リモートワーカーノードを含む通常のクラスターは、オンプレミスのマスターとワーカーノードを、クラスターに接続する他の場所にあるワーカーノードと統合します。このトピックは、リモートワーカーノードの使用のベストプラクティスに関するガイダンスを提供することを目的としており、特定の設定に関する詳細情報は含まれません。
リモートワーカーノードでのデプロイメントパターンの使用に関しては、さまざまな業界 (通信、小売、製造、政府など) で複数のユースケースがあります。たとえば、リモートワーカーノードを Kubernetes ゾーン に結合することで、プロジェクトとワークロードを分離して分離できます。
ただし、リモートワーカーノードを使用すると、高いレイテンシーの発生や、ネットワーク接続が断続的に失われるなどの問題が発生する可能性があります。リモートワーカーノードを含むクラスターの課題には、以下のようなものがあります。
- ネットワーク分離: OpenShift Container Platform コントロールプレーンとリモートワーカーノードは、相互に通信できる必要があります。コントロールプレーンとリモートワーカーノードの間に距離があるため、ネットワークの問題が発生すると、この通信が妨げられる可能性があります。OpenShift Container Platform がネットワーク分離にどのように応答するか、およびクラスターへの影響を軽減する方法については、リモートワーカーノードを使用したネットワーク分離 を参照してください。
- 停電: コントロールプレーンとリモートワーカーノードは別々の場所にあるため、リモートの場所での停電、またはそれぞれの場所からの任意の場所での停電により、クラスターに悪影響を及ぼす可能性があります。OpenShift Container Platform がノードの電力損失にどのように応答するか、およびクラスターへの影響を軽減する方法については、リモートワーカーノードの電力損失 を参照してください。
- 急激な高レイテンシーまたは一時的なスループットの低下: ネットワークの場合と同様に、クラスターとリモートワーカーノード間のネットワーク状態の変更は、クラスターに悪影響を及ぼす可能性があります。このような状況は、本書の対象外となります。
リモートワーカーノードを含むクラスターを計画する場合には、以下の制限に注意してください。
- OpenShift Container Platform は、オンプレミスクラスターが使用するクラウドプロバイダー以外のクラウドプロバイダーを使用するリモートワーカーノードをサポートしません。
- ワークロードを 1 つの Kubernetes ゾーンから別の Kubernetes ゾーンに移動すると、(特定のタイプのメモリーが異なるゾーンで利用できないなどの) システムや環境に関する課題により、問題が発生する可能性があります。
- プロキシーおよびファイアウォールでは、本書では扱われていない追加的制限が出てくる可能性があります。ファイアウォールの設定 など、このような制限に対処する方法については、関連する OpenShift ContainerPlatform のドキュメントを参照してください。
- コントロールプレーンとネットワークエッジノード間の L2/L3 レベルのネットワーク接続を設定および維持する必要があります。
8.1.1. リモートワーカーノードによるネットワーク分離
すべてのノードは、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 が NoExecute
の node.kubernetes.io/unreachable
テイントをノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。
Deployment
オブジェクト、または StatefulSet
オブジェクトなどのワークロードコントローラーが、正常でないノードの Pod にトラフィックを転送し、他のノードがクラスターに到達できる場合、OpenShift Container Platform はトラフィックをノードの Pod から遠ざけます。クラスターに到達できないノードは、新しいトラフィックルーティングでは更新されません。その結果、それらのノードのワークロードは、正常でないノードに到達しようとします。
以下の方法で接続損失の影響を軽減できます。
- デーモンセットを使用したテイントを容認する Pod の作成
- ノードがダウンした場合に自動的に再起動する静的 Pod の使用
- Kubernetes ゾーンを使用した Pod エビクションの制御
- Pod のエビクションを遅延または回避するための Pod 容認の設定
- ノードを正常でないとマークするタイミングを制御するように kubelet を設定します。
リモートワーカーノードのあるクラスターでこれらのオブジェクトを使用する方法の詳細については、リモートワーカーノードの戦略について を参照してください。
8.1.2. リモートワーカーノードの電源損失
リモートワーカーノードの電源がなくなったり、強制的な再起動を行う場合、OpenShift Container Platform は複数のデフォルトメカニズムを使用して応答します。
設定した期間後に Kubernetes Controller Manager Operator (kube コントローラー) のノードとの接続が解除された場合、コントロールプレーンはノードの正常性を Unhealthy
に更新し、ノードの Ready
状態を Unknown
とマークします。この操作に応じて、スケジューラーはそのノードへの Pod のスケジューリングを停止します。オンプレミスノードコントローラーは、effect が NoExecute
の node.kubernetes.io/unreachable
テイントをノードに追加し、デフォルトで 5 分後に、エビクション用にノード上で Pod をスケジュールします。
ノードでは、ノードが電源を回復し、コントロールプレーンに再接続する際に、Pod を再起動する必要があります。
再起動時に Pod をすぐに再起動する必要がある場合は、静的 Pod を使用します。
ノードの再起動後に kubelet も再起動し、ノードにスケジュールされた Pod の再起動を試行します。コントロールプレーンへの接続にデフォルトの 5 分よりも長い時間がかかる場合、コントロールプレーンはノードの正常性を更新して node.kubernetes.io/unreachable
テイントを削除することができません。ノードで、kubelet は実行中の Pod をすべて終了します。これらの条件がクリアされると、スケジューラーはそのノードへの Pod のスケジューリングを開始できます。
以下の方法で、電源損失の影響を軽減できます。
- デーモンセットを使用したテイントを容認する Pod の作成
- ノードを使用して自動的に再起動する静的 Pod の使用
- Pod のエビクションを遅延または回避するための Pod 容認の設定
- ノードコントローラーがノードを正常でないとマークするタイミングを制御するための kubelet の設定
リモートワーカーノードのあるクラスターでこれらのオブジェクトを使用する方法の詳細については、リモートワーカーノードの戦略について を参照してください。
8.1.3. リモートワーカーノードストラテジー
リモートワーカーノードを使用する場合は、アプリケーションを実行するために使用するオブジェクトを考慮してください。
ネットワークの問題や電源の損失時に必要とされる動作に基づいて、デーモンセットまたは静的 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
または Unknown
の Ready
状態が見られる、ゾーンが完全に中断された状態の場合、コントロールプレーンは 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-status-report-frequency
設定を使用します。これは OpenShift Container Platform クラスターのデフォルト状態です。ノードリース機能ゲートが無効にされている場合、ノードは 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"
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 が
NoExecute
のnode.kubernetes.io/unreachable
テイントを到達できないノードに追加する場合、Pod 容認を使用して effect を軽減することができます。
effect が NoExecute
のテイントは、ノードですでに実行中の Pod に以下のような影響を及ぼします。
- テイントを容認しない Pod は、エビクションのキューに置かれます。
-
容認の仕様に
tolerationSeconds
値を指定せずにテイントを容認する Pod は、永久にバインドされたままになります。 -
指定された
tolerationSeconds
値でテイントを容認する Pod は、指定された期間バインドされます。時間が経過すると、Pod はエビクションのキューに置かれます。
effect が NoExecute
の node.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 ...
OpenShift Container Platform は、pod-eviction-timeout
値の経過後、tolerationSeconds
値を使用します。
- OpenShift Container Platform オブジェクトの他のタイプ
- レプリカセット、デプロイメント、およびレプリケーションコントローラーを使用できます。スケジューラーは、ノードが 5 分間切断された後、これらの Pod を他のノードに再スケジュールできます。他のノードへの再スケジュールは、管理者が特定数の Pod を確実に実行し、アクセスできるようにする REST API などの一部のワークロードにとって有益です。
リモートワーカーノードを使用する際に、リモートワーカーノードが特定の機能用に予約されることが意図されている場合、異なるノードでの Pod の再スケジュールは許容されない可能性があります。
ステートフルセット は、停止時に再起動されません。Pod は、コントロールプレーンが Pod の終了を認識できるまで、terminating
状態のままになります。
同じタイプの永続ストレージにアクセスできないノードにスケジュールしないようにするため、OpenShift Container Platform では、ネットワークの分離時に永続ボリュームを必要とする Pod を他のゾーンに移行することはできません。
関連情報
- Daemonesets の詳細については、DaemonSets を参照してください。
- 汚染と許容範囲の詳細については、Controlling pod placement using node taints を参照してください。
-
KubeletConfig
オブジェクトの設定の詳細についてはCreating a KubeletConfig CRDを参照してください。 - レプリカセットの詳細については、 ReplicaSets を参照してください。
- 展開の詳細については、デプロイメント を参照してください。
- レプリケーション・コントローラーの詳細については、レプリケーション・コントローラー を参照してください。
- コントローラーマネージャーの詳細は、Kubernetes Controller Manager Operator を参照してください。