

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ハイブリッドデプロイのベストプラクティス
<a name="hybrid"></a>

このガイドでは、EKS Hybrid Nodes または EKS Anywhere を使用してオンプレミス環境またはエッジ環境でデプロイを実行するためのガイダンスを提供します。

現在、以下のトピックに関するガイドを公開しています。
+  [EKS Hybrid Nodes とネットワーク切断のベストプラクティス](hybrid-nodes-network-disconnections.md) 

# EKS Hybrid Nodes とネットワーク切断
<a name="hybrid-nodes-network-disconnections"></a>

EKS Hybrid Nodes アーキテクチャは、独自のデータセンターまたはエッジロケーションでローカル Kubernetes クラスターを完全に実行することに慣れているお客様にとって初めて使用できます。EKS Hybrid Nodes では、Kubernetes コントロールプレーンは AWS リージョンで実行され、ノードのみがオンプレミスで実行されるため、Kubernetes クラスターアーキテクチャが「拡張」または「拡張」されます。

これは、「ノードが Kubernetes コントロールプレーンから切断されるとどうなりますか？」という一般的な質問につながります。

このガイドでは、以下のトピックを確認して、この質問に答えます。各アプリケーションの動作は依存関係、設定、環境によって異なる可能性があるため、ネットワークの切断を通じてアプリケーションの安定性と信頼性を検証することをお勧めします。EKS Hybrid Nodes と独自のアプリケーションでネットワーク切断をテストするために参照できるテストのセットアップ、手順、結果については、aws-samples/eks-hybrid-examples GitHub リポジトリを参照してください。GitHub リポジトリには、このガイドで説明されている動作の検証に使用されるテストの追加の詳細も含まれています。
+  [ネットワーク切断による安定性のベストプラクティス](hybrid-nodes-network-disconnection-best-practices.md) 
+  [ネットワーク切断による Kubernetes ポッドのフェイルオーバー動作](hybrid-nodes-kubernetes-pod-failover.md) 
+  [ネットワーク切断によるアプリケーションネットワークトラフィック](hybrid-nodes-app-network-traffic.md) 
+  [ネットワークの切断による認証情報のホスト](hybrid-nodes-host-creds.md) 

# ネットワーク切断による安定性のベストプラクティス
<a name="hybrid-nodes-network-disconnection-best-practices"></a>

## 高可用性ネットワーク
<a name="_highly_available_networking"></a>

ハイブリッドノードと Kubernetes コントロールプレーン間のネットワーク切断を回避する最善の方法は、オンプレミス環境と AWS との間の冗長で回復力のある接続を使用することです。これらのソリューションを使用した高可用性ハイブリッドネットワークの設計の詳細については、[AWS Direct Connect Resiliency Toolkit](https://docs.aws.amazon.com/directconnect/latest/UserGuide/resiliency_toolkit.html) と [AWS Site-to-Site VPN のドキュメント](https://docs.aws.amazon.com/vpn/latest/s2svpn/vpn-redundant-connection.html)を参照してください。

## 可用性の高いアプリケーション
<a name="_highly_available_applications"></a>

アプリケーションを設計するときは、障害ドメインとさまざまなタイプの停止の影響を考慮してください。Kubernetes には、ノード、ゾーン、リージョンのドメイン間でアプリケーションレプリカをデプロイおよび維持する組み込みメカニズムが用意されています。これらのメカニズムの使用は、アプリケーションのアーキテクチャ、環境、可用性の要件によって異なります。例えば、ステートレスアプリケーションは多くの場合、複数のレプリカでデプロイでき、任意のホストとインフラストラクチャ容量を移動できます。また、ノードセレクタとトポロジ分散制約を使用して、異なるドメイン間でアプリケーションのインスタンスを実行できます。Kubernetes で回復力のあるアプリケーションを構築するためのアプリケーションレベルの手法の詳細については、[「EKS ベストプラクティスガイド](https://aws.github.io/aws-eks-best-practices/reliability/docs/application/)」を参照してください。

Kubernetes は、ポッドを他のノードに移動するかどうかを決定するときに、Kubernetes コントロールプレーンから切断されたノードのゾーン情報を評価します。ゾーン内のすべてのノードに到達できない場合、Kubernetes はそのゾーン内のノードのポッドエビクションをキャンセルします。ベストプラクティスとして、複数のデータセンターまたは物理的なロケーションでノードが実行されているデプロイがある場合は、データセンターまたは物理的なロケーションに基づいて各ノードにゾーンを割り当てます。クラウド内のノードで EKS を実行すると、このゾーンラベルは AWS cloud-controller-manager によって自動的に適用されます。ただし、cloud-controller-managerハイブリッドノードでは使用されないため、この情報を kubelet 設定で渡すことができます。ハイブリッドノードのノード設定でゾーンを設定する方法の例を以下に示します。ハイブリッドノード CLI () を使用してハイブリッドノードをクラスターに接続すると、設定が渡されます`nodeadm`。`topology.kubernetes.io/zone` ラベルの詳細については、[Kubernetes ドキュメント](https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone)を参照してください。ハイブリッドノード CLI の詳細については、[「ハイブリッドノード nodeadm リファレンス](https://docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-nodeadm.html)」を参照してください。

```
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    name: my-cluster
    region: my-region
  kubelet:
    flags:
       - --node-labels=topology.kubernetes.io/zone=dc1
  hybrid:
    ...
```

## ネットワークモニタリング
<a name="_network_monitoring"></a>

ハイブリッド接続に AWS Direct Connect または AWS Site-to-Site VPN を使用する場合は、CloudWatch アラーム、ログ、メトリクスを活用してハイブリッド接続の状態を観察し、問題を診断できます。詳細については、[「AWS Direct Connect リソースのモニタリング](https://docs.aws.amazon.com/directconnect/latest/UserGuide/monitoring-overview.html)」および[「AWS Site-to-Site VPN 接続のモニタリング](https://docs.aws.amazon.com/vpn/latest/s2svpn/monitoring-overview-vpn.html)」を参照してください。

EKS コントロールプレーンで実行されている node-lifecycle-controller によって報告された`NodeNotReady`イベントのアラームを作成することをお勧めします。これにより、ハイブリッドノードでネットワークの切断が発生している可能性があります。このアラームを作成するには、 Controller Manager の EKS コントロールプレーンのログ記録を有効にし、「ノードのステータス変更イベントメッセージの記録」メッセージのメトリクスフィルターを status=NodeNotReady」で CloudWatch に作成します。メトリクスフィルターを作成したら、目的のしきい値に基づいてこのフィルターのアラームを作成できます。詳細については、[CloudWatch ドキュメントの「ログのアラーム](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Alarm-On-Logs.html)」を参照してください。

Transit Gateway (TGW) と Virtual Private Gateway (VGW) の組み込みメトリクスを使用して、TGW または VGW との間で送受信されるネットワークトラフィックを監視できます。これらのメトリクスのアラームを作成して、ハイブリッドノードと EKS コントロールプレーン間の潜在的なネットワーク問題を示すネットワークトラフィックが通常のレベルを下回るシナリオを検出できます。TGW および VGW メトリクスを次の表に示します。


| ゲートウェイ | メトリクス | 説明 | 
| --- | --- | --- | 
|  Transit Gateway  |  BytesIn  |  TGW がアタッチメント (EKS コントロールプレーンからハイブリッドノード) から受信したバイト数  | 
|  Transit Gateway  |  BytesOut  |  TGW からアタッチメント (ハイブリッドノードから EKS コントロールプレーン) に送信されたバイト数  | 
|  仮想プライベートゲートウェイ  |  TunnelDataIn  |  VPN トンネルを介して接続の AWS 側からカスタマーゲートウェイ (EKS コントロールプレーンからハイブリッドノード) に送信されたバイト数  | 
|  仮想プライベートゲートウェイ  |  TunnelDataOut  |  VPN トンネルを介してカスタマーゲートウェイ (ハイブリッドノードから EKS コントロールプレーン) から接続の AWS 側で受信したバイト数  | 

[CloudWatch Network Monitor](https://aws.amazon.com/blogs/networking-and-content-delivery/monitor-hybrid-connectivity-with-amazon-cloudwatch-network-monitor/) を使用してハイブリッド接続をより深く把握し、平均復旧時間を短縮し、ネットワークの問題が AWS またはお客様の環境のどちらに起因するかを判断することもできます。CloudWatch Network Monitor を使用して、ハイブリッドネットワーク接続のパケット損失とレイテンシーを視覚化し、アラートとしきい値を設定し、ネットワークパフォーマンスを向上させるためのアクションを実行できます。詳細については、[Amazon CloudWatch Network Monitor の使用](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/what-is-network-monitor.html)」を参照してください。

EKS には、クラスターとアプリケーションのヘルスをモニタリングするためのオプションがいくつか用意されています。クラスターの状態については、EKS コンソールのオブザーバビリティダッシュボードを使用して、問題を迅速に検出、トラブルシューティング、修正できます。Amazon Managed Service for Prometheus、AWS Distro for Open Telemetry (ADOT)、CloudWatch を使用して、クラスター、アプリケーション、インフラストラクチャのモニタリングを行うこともできます。EKS オブザーバビリティオプションの詳細については、[「クラスターのパフォーマンスをモニタリングし、ログを表示する](https://docs.aws.amazon.com/eks/latest/userguide/eks-observe.html)」を参照してください。

## ローカルトラブルシューティング
<a name="_local_troubleshooting"></a>

ハイブリッドノードと EKS コントロールプレーン間のネットワーク切断に備えるために、セカンダリモニタリングとログバックエンドを設定して、リージョンの AWS サービスに到達できない場合にアプリケーションのオブザーバビリティを維持できます。たとえば、AWS Distro for Open Telemetry (ADOT) コレクターを設定して、メトリクスとログを複数のバックエンドに送信できます。`crictl` CLI などのローカルツールを使用して、通常 Kubernetes API サーバーエンドポイントをクエリする`kubectl`他の Kubernetes API 互換クライアントの代わりに、ポッドやコンテナをローカルで操作することもできます。の詳細については`crictl`、cri-tools GitHub の[`crictl`ドキュメント](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)を参照してください。以下に、いくつかの便利な`crictl`コマンドを示します。

ホストで実行されているポッドを一覧表示します。

```
crictl pods
```

ホストで実行されているコンテナを一覧表示します。

```
crictl ps
```

ホストで実行されているイメージを一覧表示します。

```
crictl images
```

ホストで実行されているコンテナのログを取得します。

```
crictl logs CONTAINER_NAME
```

ホストで実行されているポッドの統計を取得します。

```
crictl statsp
```

## アプリケーションネットワークトラフィック
<a name="_application_network_traffic"></a>

ハイブリッドノードを使用する場合は、アプリケーショントラフィックのネットワークフローと、アプリケーションをクラスターの外部に公開するために使用するテクノロジーを検討して理解することが重要です。アプリケーションの負荷分散と進入のテクノロジーは、ネットワークの切断時に動作が異なります。たとえば、アプリケーションの負荷分散に Cilium の BGP コントロールプレーン機能を使用している場合、ネットワークの切断中にポッドとサービスの BGP セッションがダウンする可能性があります。これは、BGP スピーカー機能が Cilium エージェントと統合されており、Kubernetes コントロールプレーンから切断されると Cilium エージェントが継続的に再起動するためです。再起動の理由は、そのヘルスが Kubernetes コントロールプレーンへのアクセスと組み合わされているため、Cilium のヘルスチェックが失敗したためです ([「CFP: \$131702](https://github.com/cilium/cilium/issues/31702) with an opt-in improvement in Cilium v1.17」を参照）。同様に、AWS リージョンが発信するアプリケーショントラフィックに Application Load Balancer (ALB) または Network Load Balancer (NLB) を使用している場合、オンプレミス環境が AWS リージョンへの接続を失った場合、そのトラフィックは一時的にダウンする可能性があります。本稼働環境にデプロイする前に、ロードバランシングとイングレスに使用するテクノロジーがネットワークの切断中も安定していることを検証することをお勧めします。[aws-samples/eks-hybrid-examples](https://github.com/aws-samples/eks-hybrid-examples) GitHub リポジトリの例では、[L2 モードで](https://metallb.universe.tf/concepts/layer2/)の負荷分散に MetalLB を使用しています。これは、ハイブリッドノードと EKS コントロールプレーン間のネットワーク切断中も安定しています。

## リモート AWS サービスへの依存関係を確認する
<a name="_review_dependencies_on_remote_aws_services"></a>

ハイブリッドノードを使用する場合は、オンプレミス環境またはエッジ環境の外部にあるリージョンの AWS サービスに対する依存関係に注意してください。例としては、アプリケーションデータ用の Amazon S3 または Amazon RDS へのアクセス、メトリクスとログ用の Amazon Managed Service for Prometheus または CloudWatch の使用、リージョンが発信するトラフィック用の Application and Network Load Balancer の使用、Amazon Elastic Container Registry からのコンテナのプルなどがあります。これらのサービスは、オンプレミス環境と AWS 間のネットワーク切断中はアクセスできません。オンプレミス環境が AWS とのネットワーク切断を起こしやすい場合は、AWS のサービスの使用を確認し、それらのサービスへの接続が失われてもアプリケーションの静的安定性が損なわれないことを確認してください。

## Kubernetes ポッドのフェイルオーバー動作を調整する
<a name="_tune_kubernetes_pod_failover_behavior"></a>

ホスト間で移植できないアプリケーションのネットワーク切断中、またはポッドフェイルオーバー用の予備容量がないリソースに制約のある環境では、ポッドフェイルオーバー動作を調整するオプションがあります。一般的に、アプリケーションのリソース要件を考慮し、ノードに障害が発生した場合にアプリケーションの 1 つ以上のインスタンスが別のホストにフェイルオーバーするのに十分な容量を持つことが重要です。
+  オプション 1 - DaemonSets を使用する: このオプションは、クラスター内のすべてのノードで実行できるアプリケーションと実行する必要があるアプリケーションに適用されます。DaemonSets は到達不可能なテイントを許容するように自動的に設定されます。これにより、DaemonSet ポッドはネットワーク切断によってノードにバインドされます。
+  オプション 2 - 到達不可能なテイント`tolerationSeconds`に合わせて調整する: ネットワーク切断中にポッドがノードにバインドされたままになる時間を調整できます。これを行うには、アプリケーションポッドを設定して到達不可能なテイントを許容し、指定した期間 (`tolerationSeconds`アプリケーション仕様の ) `NoExecute`効果を使用します。このオプションでは、ネットワークが切断されると、アプリケーションポッドは `tolerationSeconds`の有効期限が切れるまでノードにバインドされたままになります。を使用して到達不可能なテイント`tolerationSeconds`に対して を増やす`NoExecute`と、到達不可能なホストで実行されているポッドが他の到達可能な正常なホストに移動するのに時間がかかる可能性があるため、慎重に検討してください。
+  オプション 3: カスタムコントローラー: `NoExecute`Kubernetes で到達不可能なテイントをモニタリングするカスタムコントローラー (またはその他のソフトウェア) を作成して実行できます。このテイントが検出されると、カスタムコントローラーはアプリケーション固有のメトリクスをチェックしてアプリケーションのヘルスを評価できます。アプリケーションが正常であれば、カスタムコントローラーは到達不可能なテイントを削除し、ネットワークの切断中のノードからのポッドのエビクションを防ぐことができます。

到達不可能なテイント`tolerationSeconds`に対して を使用してデプロイを設定する方法の例を以下に示します。この例では、 `tolerationSeconds`は `1800` (30 分) に設定されています。つまり、到達できないノードで実行されているポッドは、ネットワークの切断が 30 分以上続く場合にのみ削除されます。

```
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
      tolerations:
      - key: "node.kubernetes.io/unreachable"
        operator: "Exists"
        effect: "NoExecute"
        tolerationSeconds: 1800
```

# ネットワーク切断による Kubernetes ポッドのフェイルオーバー
<a name="hybrid-nodes-kubernetes-pod-failover"></a>

まず、ノードと Kubernetes コントロールプレーン間のネットワーク切断時の Kubernetes の動作に影響する主要な概念、コンポーネント、設定を確認します。EKS はアップストリーム Kubernetes に準拠しているため、ここで説明するすべての Kubernetes の概念、コンポーネント、設定は、EKS および EKS Hybrid Nodes のデプロイに適用されます。

ネットワーク切断中のポッドフェイルオーバー動作を改善するために、特に EKS が改善されました。詳細については、アップストリーム Kubernetes リポジトリのGitHub の問題 [\$1131294](https://github.com/kubernetes/kubernetes/pull/131294)」と[「\$1131481](https://github.com/kubernetes/kubernetes/issues/131481)」を参照してください。

## 概念
<a name="_concepts"></a>

 テイントと許容範囲: テイントと許容範囲は、ノードへのポッドのスケジュールを制御するために Kubernetes で使用されます。テイントは node-lifecycle-controller によって設定され、ノードがスケジューリングの対象ではないか、それらのノードのポッドを削除する必要があることを示します。ネットワークの切断が原因でノードに到達できない場合、node-lifecycle-controller は NoSchedule 効果で node.kubernetes.io/unreachable テイントを適用し、特定の条件が満たされた場合は NoExecute 効果を適用します。node.kubernetes.io/unreachable テイントは、NodeCondition Ready が不明であることに対応します。ユーザーは、PodSpec のアプリケーションレベルでテイントの許容範囲を指定できます。
+ NoSchedule: 許容値が一致しない限り、テイントされたノードに新しいポッドはスケジュールされません。ノードで既に実行されているポッドは削除されません。
+ NoExecute: テイントを許容しないポッドはすぐに削除されます。(tolerationSeconds を指定せずに) テイントを許容するポッドは、永久にバインドされます。tolerationSeconds が指定されたテイントを許容するポッドは、指定された時間バインドされたままになります。その時間が経過すると、ノードライフサイクルコントローラーはノードからポッドを削除します。

 ノードリース: Kubernetes は、リース API を使用して kubelet ノードハートビートを Kubernetes API サーバーに通信します。ノードごとに、一致する名前の Lease オブジェクトがあります。内部的には、各 kubelet ハートビートは Lease オブジェクトの spec.renewTime フィールドを更新します。Kubernetes コントロールプレーンは、このフィールドのタイムスタンプを使用してノードの可用性を判断します。ノードが Kubernetes コントロールプレーンから切断されている場合、リースの spec.renewTime を更新できず、コントロールプレーンはそれを NodeCondition Ready が不明であると解釈します。

## コンポーネント
<a name="_components"></a>

![\[ポッドのフェイルオーバー動作に関連する Kubernetes コンポーネント\]](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/hybrid/k8s-components-pod-failover.png)



| コンポーネント | サブコンポーネント | 説明 | 
| --- | --- | --- | 
|  Kubernetes コントロールプレーン  |  kube-api-server  |  API サーバーは、Kubernetes API を公開する Kubernetes コントロールプレーンのコアコンポーネントです。  | 
|  Kubernetes コントロールプレーン  |  node-lifecycle-controller  |  kube-controller-manager が実行するコントローラーの 1 つ。ノードの問題を検出して対応します。  | 
|  Kubernetes コントロールプレーン  |  kube-scheduler  |  ノードが割り当てられていない新しく作成された Pod を監視し、それらを実行するノードを選択するコントロールプレーンコンポーネント。  | 
|  Kubernetes ノード  |  kubelet  |  クラスター内の各ノードで実行されるエージェント。kubelet は PodSpecs を監視し、それらの PodSpecs で説明されているコンテナが実行中で正常であることを確認します。  | 

## 構成設定
<a name="_configuration_settings"></a>


| コンポーネント | 設定 | 説明 | K8s デフォルト | EKS デフォルト | EKS で設定可能 | 
| --- | --- | --- | --- | --- | --- | 
|  kube-api-server  |  default-unreachable-toleration-seconds  |  このような許容範囲がまだないすべてのポッドにデフォルトで追加`unreachable:NoExecute`される の許容範囲`tolerationSeconds`の を示します。  |  300  |  300  |  いいえ  | 
|  node-lifecycle-controller  |  node-monitor-grace-period  |  ノードが異常とマークされるまでに応答しない時間。kubelet の の N 倍にする必要があります。N は`nodeStatusUpdateFrequency`、kubelet がノードステータスをポストするために許可される再試行回数です。  |  40  |  40  |  いいえ  | 
|  node-lifecycle-controller  |  large-cluster-size-threshold  |  node-lifecycle-controller がクラスターをエビクションロジック用に大規模として扱うノードの数。このサイズ以下のクラスターでは、 `--secondary-node-eviction-rate`は 0 に上書きされます。  |  50  |  100,000  |  いいえ  | 
|  node-lifecycle-controller  |  unhealthy-zone-threshold  |  ゾーン内のノードのうち、そのゾーンが異常として扱われるために準備中である必要があるノードの割合。  |  55%  |  55%  |  いいえ  | 
|  kubelet  |  node-status-update-frequency  |  kubelet がノードステータスをコントロールプレーンに投稿する頻度。node-lifecycle-controller `nodeMonitorGracePeriod`で と互換性がある必要があります。  |  10  |  10  |  [Yes (はい)]  | 
|  kubelet  |  ノードラベル  |  クラスターにノードを登録するときに追加するラベル。ラベルは、ハイブリッドノードで指定して、ノードをゾーンにグループ化`topology.kubernetes.io/zone`できます。  |  なし  |  なし  |  はい  | 

## ネットワーク切断による Kubernetes ポッドのフェイルオーバー
<a name="_kubernetes_pod_failover_through_network_disconnections"></a>

ここで説明する動作は、ポッドがデフォルト設定で Kubernetes デプロイとして実行されており、EKS が Kubernetes プロバイダーとして使用されていることを前提としています。実際の動作は、環境、ネットワーク切断のタイプ、アプリケーション、依存関係、クラスター設定によって異なる場合があります。このガイドのコンテンツは、特定のアプリケーション、クラスター設定、プラグインのサブセットを使用して検証されました。本番環境に移行する前に、独自の環境と独自のアプリケーションで動作をテストすることを強くお勧めします。

ノードと Kubernetes コントロールプレーンの間にネットワーク切断がある場合、切断された各ノードの kubelet は Kubernetes コントロールプレーンと通信できません。したがって、kubelet は接続が復元されるまでそれらのノードのポッドを削除できません。つまり、ネットワークの切断前にノードで実行されているポッドは、切断中に引き続き実行され、他の障害が原因でシャットダウンされないと仮定します。つまり、ノードと Kubernetes コントロールプレーン間のネットワーク切断中に静的安定性を実現できますが、接続が復元されるまでノードまたはワークロードに対して変更オペレーションを実行することはできません。

ネットワーク切断の性質に基づいて異なるポッドフェイルオーバー動作を生成する主なシナリオは 5 つあります。すべてのシナリオで、ノードが Kubernetes コントロールプレーンに再接続されると、クラスターはオペレーターの介入なしで再び正常になります。以下のシナリオでは、観測結果に基づいて期待される結果を概説しますが、これらの結果は、考えられるすべてのアプリケーションおよびクラスター設定に適用されるとは限りません。

### シナリオ 1: クラスターの完全な中断
<a name="_scenario_1_full_cluster_disruption"></a>

 **期待される結果**: 到達できないノードのポッドは削除されず、それらのノードで引き続き実行されます。

クラスターの完全な中断とは、クラスター内のすべてのノードが Kubernetes コントロールプレーンから切断されることを意味します。このシナリオでは、コントロールプレーンの node-lifecycle-controller は、クラスター内のすべてのノードに到達できないことを検出し、ポッドの削除をキャンセルします。

クラスター管理者は、切断`Not Ready`中にステータスが のすべてのノードを表示します。Pod のステータスは変更されず、切断後の再接続中にノードに新しいポッドがスケジュールされることはありません。

### シナリオ 2: フルゾーンの中断
<a name="_scenario_2_full_zone_disruption"></a>

 **期待される結果**: 到達できないノードのポッドは削除されず、それらのノードで引き続き実行されます。

フルゾーン中断とは、ゾーン内のすべてのノードが Kubernetes コントロールプレーンから切断されることを意味します。このシナリオでは、コントロールプレーンの node-lifecycle-controller は、ゾーン内のすべてのノードに到達できないことを検出し、ポッドの削除をキャンセルします。

クラスター管理者は、切断`Not Ready`中にステータスが のすべてのノードを表示します。Pod のステータスは変更されず、切断後の再接続中にノードに新しいポッドがスケジュールされることはありません。

### シナリオ 3: メジャーゾーンの中断
<a name="_scenario_3_majority_zone_disruption"></a>

 **期待される結果**: 到達できないノードのポッドは削除されず、それらのノードで実行され続けます。

過半数ゾーンの中断は、特定のゾーンのほとんどのノードが Kubernetes コントロールプレーンから切断されることを意味します。Kubernetes のゾーンは、同じ`topology.kubernetes.io/zone`ラベルを持つノードによって定義されます。クラスターにゾーンが定義されていない場合、大部分の中断はクラスター全体のノードの大部分が切断されることを意味します。デフォルトでは、過半数は node-lifecycle-controller の によって定義され`unhealthy-zone-threshold`、Kubernetes と EKS の両方で 55% に設定されます。EKS では `large-cluster-size-threshold`が 100,000 に設定されているため、ゾーン内のノードの 55% 以上に到達できない場合、ポッドの削除はキャンセルされます (ほとんどのクラスターが 100,000 ノードよりはるかに小さい場合）。

クラスター管理者は、切断`Not Ready`中にゾーン内のほとんどのノードのステータスが になりますが、ポッドのステータスは変更されず、他のノードでも再スケジュールされません。

上記の動作は、3 ノードを超えるクラスターにのみ適用されます。3 つ以下のノードのクラスターでは、到達できないノード上のポッドは削除がスケジュールされ、新しいポッドは正常なノードでスケジュールされます。

テスト中に、ゾーンのノードの大部分に到達できない場合でも、ネットワーク切断中にポッドが 1 つの到達不可能なノードから完全に削除されたことが確認されることがあります。この動作の原因として、Kubernetes node-lifecycle-controller で考えられる競合状態をまだ調査中です。

### シナリオ 4: マイノリティゾーンの中断
<a name="_scenario_4_minority_zone_disruption"></a>

 **期待される結果**: ポッドは到達できないノードから削除され、新しいポッドは利用可能な適格なノードでスケジュールされます。

少数中断とは、ゾーン内のノードのごく一部が Kubernetes コントロールプレーンから切断されることを意味します。クラスターにゾーンが定義されていない場合、クラスター全体のノードの少数が切断されることを意味します。前述のように、少数は、デフォルトで 55% の node-lifecycle-controller `unhealthy-zone-threshold`の設定によって定義されます。このシナリオでは、ネットワークの切断が `default-unreachable-toleration-seconds` (5 分) および `node-monitor-grace-period` (40 秒) より長く、ゾーン内のノードの 55% 未満に到達できない場合、新しいポッドは正常なノードでスケジュールされ、到達できないノードのポッドは削除対象としてマークされます。

クラスター管理者は正常なノードで作成された新しいポッドを表示し、切断されたノードのポッドは として表示されます`Terminating`。切断されたノードのポッドには `Terminating`ステータスがありますが、ノードが Kubernetes コントロールプレーンに再接続されるまで完全には削除されないことに注意してください。

## シナリオ 5: ネットワーク中断中のノードの再起動
<a name="_scenario_5_node_restart_during_network_disruption"></a>

 **期待される結果**: 到達不可能なノードのポッドは、ノードが Kubernetes コントロールプレーンに再接続されるまで開始されません。ポッドフェイルオーバーは、到達できないノードの数に応じて、シナリオ 1～3 で説明されているロジックに従います。

ネットワーク中断中のノードの再起動は、ネットワーク切断と同時にノードで別の障害 (電源サイクル、out-of-memoryイベント、その他の問題など) が発生したことを意味します。ネットワーク切断の開始時にそのノードで実行されていたポッドは、kubelet も再起動した場合、切断中に自動的に再起動されません。kubelet は、起動時に Kubernetes API サーバーにクエリを実行して、実行するポッドを確認します。ネットワークの切断が原因で kubelet が API サーバーに到達できない場合、ポッドの起動に必要な情報を取得できません。

このシナリオでは、CLI `crictl` などのローカルトラブルシューティングツールを使用して、ポッドを「ブレークグラス」メジャーとして手動で起動することはできません。Kubernetes は通常、失敗したポッドを削除し、既存のポッドを再起動するのではなく、新しいポッドを作成します (詳細については、containerd GitHub リポジトリの [\$110213](https://github.com/containerd/containerd/pull/10213) を参照してください）。静的ポッドは、kubelet によって制御される唯一の Kubernetes ワークロードオブジェクトであり、これらのシナリオ中に再起動できます。ただし、アプリケーションのデプロイに静的ポッドを使用することは一般的にお勧めしません。代わりに、異なるホストに複数のレプリカをデプロイして、ノード障害やノードと Kubernetes コントロールプレーン間のネットワーク切断など、複数の同時障害が発生した場合にアプリケーションの可用性を確保します。

# ネットワーク切断によるアプリケーションネットワークトラフィック
<a name="hybrid-nodes-app-network-traffic"></a>

このページのトピックは、Kubernetes クラスターネットワークと、ノードと Kubernetes コントロールプレーン間のネットワーク切断中のアプリケーショントラフィックに関連しています。

## Cilium
<a name="_cilium"></a>

Cilium には、IP アドレス管理 (IPAM)、カプセル化、ロードバランシング、クラスタールーティングのためのいくつかのモードがあります。このガイドで検証されたモードは、クラスタースコープ IPAM、VXLAN オーバーレイ、BGP 負荷分散、kube-proxy を使用していました。Cilium も BGP 負荷分散なしで使用され、MetalLB L2 負荷分散に置き換えられました。

Cilium インストールのベースは、Cilium 演算子と Cilium エージェントで構成されます。Cilium 演算子はデプロイとして実行され、Cilium Custom Resource Definitions (CRDs を登録し、IPAM を管理し、クラスターオブジェクトを [https://docs.cilium.io/en/stable/internals/cilium_operator/](https://docs.cilium.io/en/stable/internals/cilium_operator/)Kubernetes API サーバーと同期します。Cilium エージェントは、各ノードで DaemonSet として実行され、クラスターで実行されているワークロードのネットワークルールを制御する eBPF プログラムを管理します。

一般的に、Cilium によって設定されたクラスター内ルーティングは、ネットワーク切断中も引き続き利用可能であり、インプレースです。これは、ポッドネットワークのクラスター内トラフィックフローと IP テーブル (iptables) ルールを監視することで確認できます。

```
ip route show table all | grep cilium
```

```
10.86.2.0/26 via 10.86.3.16 dev cilium_host proto kernel src 10.86.3.16 mtu 1450
10.86.2.64/26 via 10.86.3.16 dev cilium_host proto kernel src 10.86.3.16 mtu 1450
10.86.2.128/26 via 10.86.3.16 dev cilium_host proto kernel src 10.86.3.16 mtu 1450
10.86.2.192/26 via 10.86.3.16 dev cilium_host proto kernel src 10.86.3.16 mtu 1450
10.86.3.0/26 via 10.86.3.16 dev cilium_host proto kernel src 10.86.3.16
10.86.3.16 dev cilium_host proto kernel scope link
...
```

ただし、ネットワークの切断中、Cilium オペレーターと Cilium エージェントは、ヘルスチェックと Kubernetes API サーバーとの接続の正常性が結合されているため、再起動します。ネットワークの切断中に Cilium オペレーターと Cilium エージェントのログに以下が表示されることが予想されます。ネットワークの切断中に、 CLI `crictl` などのツールを使用して、ログを含むこれらのコンポーネントの再起動を監視できます。

```
msg="Started gops server" address="127.0.0.1:9890" subsys=gops
msg="Establishing connection to apiserver" host="https://<k8s-cluster-ip>:443" subsys=k8s-client
msg="Establishing connection to apiserver" host="https://<k8s-cluster-ip>:443" subsys=k8s-client
msg="Unable to contact k8s api-server" error="Get \"https://<k8s-cluster-ip>:443/api/v1/namespaces/kube-system\": dial tcp <k8s-cluster-ip>:443: i/o timeout" ipAddr="https://<k8s-cluster-ip>:443" subsys=k8s-client
msg="Start hook failed" function="client.(*compositeClientset).onStart (agent.infra.k8s-client)" error="Get \"https://<k8s-cluster-ip>:443/api/v1/namespaces/kube-system\": dial tcp <k8s-cluster-ip>:443: i/o timeout"
msg="Start failed" error="Get \"https://<k8s-cluster-ip>:443/api/v1/namespaces/kube-system\": dial tcp <k8s-cluster-ip>:443: i/o timeout" duration=1m5.003834026s
msg=Stopping
msg="Stopped gops server" address="127.0.0.1:9890" subsys=gops
msg="failed to start: Get \"https://<k8s-cluster-ip>:443/api/v1/namespaces/kube-system\": dial tcp <k8s-cluster-ip>:443: i/o timeout" subsys=daemon
```

アプリケーションの負荷分散に Cilium の BGP コントロールプレーン機能を使用している場合、BGP スピーカー機能は Cilium エージェントと統合されており、Kubernetes コントロールプレーンから切断されると Cilium エージェントは継続的に再起動するため、ポッドとサービスの BGP セッションがネットワークの切断中にダウンする可能性があります。詳細については、Cilium ドキュメントの「Cilium BGP コントロールプレーンオペレーションガイド」を参照してください。さらに、電源サイクルやマシンの再起動など、ネットワークの切断中に同時に障害が発生した場合、Cilium ルートはこれらのアクションによって保持されませんが、ノードが Kubernetes コントロールプレーンに再接続して Cilium が再び起動すると、ルートは再作成されます。

## Calico
<a name="_calico"></a>

 *近日リリース* 

## MetalLB
<a name="_metallb"></a>

MetalLB には、L2 モードと BGP モードの [L2 ](https://metallb.universe.tf/concepts/layer2/)つのロードバランシングモードがあります。 [https://metallb.universe.tf/concepts/bgp/](https://metallb.universe.tf/concepts/bgp/)これらの負荷分散モードの仕組みとその制限の詳細については、MetalLB ドキュメントを参照してください。このガイドの検証では、L2 モードで MetalLB を使用し、クラスター内の 1 台のマシンが Kubernetes サービスの所有権を取得し、IPv4 の ARP を使用してロードバランサーの IP アドレスをローカルネットワークで到達可能にします。MetalLB を実行する場合、IP 割り当てを担当するコントローラーと、割り当てられた IP アドレスを持つ サービスをアドバタイズする各ノードで実行されるスピーカーがあります。MetalLB コントローラーはデプロイとして実行され、MetalLB スピーカーは DaemonSet として実行されます。ネットワークの切断中、MetalLB コントローラーとスピーカーはクラスターリソースの Kubernetes API サーバーを監視できませんが、実行は続行されます。最も重要なのは、外部接続に MetalLB を使用しているサービスは、ネットワークの切断中も引き続き利用可能でアクセス可能です。

## kube-proxy
<a name="_kube_proxy"></a>

EKS クラスターでは、kube-proxy は各ノードで DaemonSet として実行され、ネットワークルールを管理して、サービス IP アドレスを基盤となるポッドの IP アドレスに変換することで、サービスとポッド間の通信を有効にします。kube-proxy によって設定された IP テーブル (iptables) ルールは、ネットワークの切断中に維持され、クラスター内ルーティングは引き続き機能し、kube-proxy ポッドは引き続き実行されます。

kube-proxy ルールは、次の iptables コマンドで確認できます。最初のコマンドは、`PREROUTING`チェーンを通過するパケットが`KUBE-SERVICES`チェーンに誘導されることを示しています。

```
iptables -t nat -L PREROUTING
```

```
Chain PREROUTING (policy ACCEPT)
target         prot opt source      destination
KUBE-SERVICES  all  --  anywhere    anywhere      /* kubernetes service portals */
```

`KUBE-SERVICES` チェーンを調べると、さまざまなクラスターサービスのルールを確認できます。

```
Chain KUBE-SERVICES (2 references)
target                     prot opt source      destination
KUBE-SVL-NZTS37XDTDNXGCKJ  tcp  --  anywhere    172.16.189.136  /* kube-system/hubble-peer:peer-service cluster IP /
KUBE-SVC-2BINP2AXJOTI3HJ5  tcp  --  anywhere    172.16.62.72    / default/metallb-webhook-service cluster IP /
KUBE-SVC-LRNEBRA3Z5YGJ4QC  tcp  --  anywhere    172.16.145.111  / default/redis-leader cluster IP /
KUBE-SVC-I7SKRZYQ7PWYV5X7  tcp  --  anywhere    172.16.142.147  / kube-system/eks-extension-metrics-api:metrics-api cluster IP /
KUBE-SVC-JD5MR3NA4I4DYORP  tcp  --  anywhere    172.16.0.10     / kube-system/kube-dns:metrics cluster IP /
KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  anywhere    172.16.0.10     / kube-system/kube-dns:dns cluster IP /
KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  anywhere    172.16.0.10     / kube-system/kube-dns:dns-tcp cluster IP /
KUBE-SVC-ENODL3HWJ5BZY56Q  tcp  --  anywhere    172.16.7.26     / default/frontend cluster IP /
KUBE-EXT-ENODL3HWJ5BZY56Q  tcp  --  anywhere    <LB-IP>    / default/frontend loadbalancer IP /
KUBE-SVC-NPX46M4PTMTKRN6Y  tcp  --  anywhere    172.16.0.1      / default/kubernetes:https cluster IP /
KUBE-SVC-YU5RV2YQWHLZ5XPR  tcp  --  anywhere    172.16.228.76   / default/redis-follower cluster IP /
KUBE-NODEPORTS             all  --  anywhere    anywhere        / kubernetes service nodeports; NOTE: this must be the last rule in this chain */
```

フロントエンドサービスのチェーンでアプリケーションを調べると、サービスを支えるポッド IP アドレスを確認できます。

```
iptables -t nat -L KUBE-SVC-ENODL3HWJ5BZY56Q
```

```
Chain KUBE-SVC-ENODL3HWJ5BZY56Q (2 references)
target                     prot opt source    destination
KUBE-SEP-EKXE7ASH7Y74BGBO  all  --  anywhere  anywhere    /* default/frontend -> 10.86.2.103:80 / statistic mode random probability 0.33333333349
KUBE-SEP-GCY3OUXWSVMSEAR6  all  --  anywhere  anywhere    / default/frontend -> 10.86.2.179:80 / statistic mode random probability 0.50000000000
KUBE-SEP-6GJJR3EF5AUP2WBU  all  --  anywhere  anywhere    / default/frontend -> 10.86.3.47:80 */
```

次の kube-proxy ログメッセージは、Kubernetes API サーバーがノードおよびエンドポイントリソースの更新を監視しようとしたときに、ネットワークの切断中に予期されます。

```
"Unhandled Error" err="k8s.io/client-go/informers/factory.go:160: Failed to watch *v1.Node: failed to list *v1.Node: Get \"https://<k8s-endpoint>/api/v1/nodes?fieldSelector=metadata.name%3D<node-name>&resourceVersion=2241908\": dial tcp <k8s-ip>:443: i/o timeout" logger="UnhandledError"
"Unhandled Error" err="k8s.io/client-go/informers/factory.go:160: Failed to watch *v1.EndpointSlice: failed to list *v1.EndpointSlice: Get \"https://<k8s-endpoint>/apis/discovery.k8s.io/v1/endpointslices?labelSelector=%21service.kubernetes.io%2Fheadless%2C%21service.kubernetes.io%2Fservice-proxy-name&resourceVersion=2242090\": dial tcp <k8s-ip>:443: i/o timeout" logger="UnhandledError"
```

## CoreDNS
<a name="_coredns"></a>

デフォルトでは、EKS クラスターのポッドは、クラスター内 DNS クエリのネームサーバーとして CoreDNS クラスター IP アドレスを使用します。EKS クラスターでは、CoreDNS はノードのデプロイとして実行されます。ハイブリッドノードでは、ハイブリッドノードでローカルに実行されている CoreDNS レプリカがある場合、ポッドはネットワークの切断中に CoreDNS と通信し続けることができます。クラウドにノードを持つ EKS クラスターがあり、オンプレミス環境にハイブリッドノードがある場合は、各環境に少なくとも 1 つの CoreDNS レプリカを持つことをお勧めします。CoreDNS は、ネットワークの切断前に作成されたレコードの DNS クエリの処理を継続し、静的安定性のためにネットワーク再接続を通じて実行を継続します。

Kubernetes API サーバーからオブジェクトを一覧表示しようとすると、ネットワークの切断中に次の CoreDNS ログメッセージが予期されます。

```
Failed to watch *v1.Namespace: failed to list *v1.Namespace: Get "https://<k8s-cluster-ip>:443/api/v1/namespaces?resourceVersion=2263964": dial tcp <k8s-cluster-ip>:443: i/o timeout
Failed to watch *v1.Service: failed to list *v1.Service: Get "https://<k8s-cluster-ip>:443/api/v1/services?resourceVersion=2263966": dial tcp <k8s-cluster-ip>:443: i/o timeout
Failed to watch *v1.EndpointSlice: failed to list *v1.EndpointSlice: Get "https://<k8s-cluster-ip>:443/apis/discovery.k8s.io/v1/endpointslices?resourceVersion=2263896": dial tcp <k8s-cluster-ip>: i/o timeout
```

# ネットワーク切断による認証情報のホスト
<a name="hybrid-nodes-host-creds"></a>

EKS Hybrid Nodes は、AWS Systems Manager (SSM) ハイブリッドアクティベーションおよび AWS IAM Roles Anywhere と統合され、EKS コントロールプレーンでノードを認証するために使用される一時的な IAM 認証情報を提供します。SSM と IAM Roles Anywhere の両方が、オンプレミスホストで管理する一時的な認証情報を自動的に更新します。クラスター内のハイブリッドノード全体で単一の認証情報プロバイダーを使用することをお勧めします。SSM ハイブリッドアクティベーションまたは IAM Roles Anywhere のいずれかですが、両方を使用することはできません。

## SSM ハイブリッドアクティベーション
<a name="_ssm_hybrid_activations"></a>

SSM によってプロビジョニングされた一時的な認証情報は 1 時間有効です。SSM を認証情報プロバイダーとして使用する場合、認証情報の有効期間を変更することはできません。一時的な認証情報は、有効期限が切れる前に SSM によって自動的にローテーションされ、ローテーションはノードまたはアプリケーションのステータスには影響しません。ただし、SSM エージェントと SSM リージョンエンドポイントの間にネットワーク切断がある場合、SSM は認証情報を更新できず、認証情報の有効期限が切れる可能性があります。

SSM リージョンエンドポイントに接続できない場合、SSM は認証情報の更新の再試行にエクスポネンシャルバックオフを使用します。SSM エージェントバージョン `3.3.808.0` 以降 (2024 年 8 月リリース) では、エクスポネンシャルバックオフの上限は 30 分です。ネットワークの切断時間によっては、SSM が認証情報を更新するまでに最大 30 分かかる場合があり、ハイブリッドノードは認証情報が更新されるまで EKS コントロールプレーンに再接続しません。このシナリオでは、SSM エージェントを再起動して認証情報を強制的に更新できます。現在の SSM 認証情報の更新動作の副作用として、ノードは、各ノードの SSM エージェントが認証情報の更新を管理するタイミングに応じて、異なるタイミングで再接続することがあります。このため、再接続済みのノードにまだ再接続されていないノードからのポッドフェイルオーバーが発生する可能性があります。

SSM エージェントのバージョンを取得します。SSM コンソールの Fleet Manager セクションを確認することもできます。

```
# AL2023, RHEL
yum info amazon-ssm-agent
# Ubuntu
snap list amazon-ssm-agent
```

SSM エージェントを再起動します。

```
# AL2023, RHEL
systemctl restart amazon-ssm-agent
# Ubuntu
systemctl restart snap.amazon-ssm-agent.amazon-ssm-agent
```

SSM エージェントログを表示します。

```
tail -f /var/log/amazon/ssm/amazon-ssm-agent.log
```

ネットワーク切断中に予想されるログメッセージ:

```
INFO [CredentialRefresher] Credentials ready
INFO [CredentialRefresher] Next credential rotation will be in 29.995040663666668 minutes
ERROR [CredentialRefresher] Retrieve credentials produced error: RequestError: send request failed
INFO [CredentialRefresher] Sleeping for 35s before retrying retrieve credentials
ERROR [CredentialRefresher] Retrieve credentials produced error: RequestError: send request failed
INFO [CredentialRefresher] Sleeping for 56s before retrying retrieve credentials
ERROR [CredentialRefresher] Retrieve credentials produced error: RequestError: send request failed
INFO [CredentialRefresher] Sleeping for 1m24s before retrying retrieve credentials
```

## IAM Roles Anywhere
<a name="_iam_roles_anywhere"></a>

IAM Roles Anywhere によってプロビジョニングされた一時的な認証情報は、デフォルトで 1 時間有効です。IAM Roles Anywhere プロファイルの [https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-create-session.html#credentials-object](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-create-session.html#credentials-object)フィールドを使用して、IAM Roles Anywhere で認証情報の有効期間を設定できます。認証情報の最大有効期間は 12 時間です。Hybrid Nodes IAM ロール[https://docs.aws.amazon.com/managedservices/latest/ctref/management-advanced-identity-and-access-management-iam-update-maxsessionduration.html](https://docs.aws.amazon.com/managedservices/latest/ctref/management-advanced-identity-and-access-management-iam-update-maxsessionduration.html)の設定は、IAM Roles Anywhere プロファイル`durationSeconds`の設定よりも大きくする必要があります。

ハイブリッドノードの認証情報プロバイダーとして IAM Roles Anywhere を使用する場合は、kubelet が `aws_signing_helper credential-process`を呼び出してオンデマンドで認証情報を取得するため、通常、ネットワークの切断後数秒以内に EKS コントロールプレーンに再接続します。ハイブリッドノードやネットワークの切断に直接関係ありませんが、IAM Roles Anywhere の使用時に証明書の有効期限の通知とアラートを設定できます。詳細については、[「IAM Roles Anywhere で通知設定をカスタマイズ](https://docs.aws.amazon.com/rolesanywhere/latest/userguide/customize-notification-settings.html)する」を参照してください。