Amazon Web Services ブログ
Amazon EKS ワーカーノードの謎を解くクラスターネットワーク
AWS で Kubernetes を実行するには、AWS のネットワーク設定と Kubernetes のネットワーク要件の両方を理解する必要があります。デフォルトの Amazon Elastic Kubernetes Service (Amazon EKS) の AWS CloudFormation テンプレートを使用して、Amazon Virtual Private Cloud (Amazon VPC) と Amazon EC2 ワーカーノードをデプロイすると、通常の場合、すべて機能します。しかし、設定に小さな問題があると、エラーが発生してイライラさせられることがあります。
このブログでは、Amazon VPC を設定するさまざまな方法を見ながら、Amazon EKS が管理する Kubernetes クラスターの EC2 ワーカーノードを実行します。ノードがクラスターコントロールプレーンに接続できるようにサブネットが適切に設定されていることを確認する方法について、特に注目します。
このブログでは、VPC CNI、サブネットのサイズ設定、ポッドの IP アドレス割り当てなどのポッドネットワーキングの概念については取り上げません。これらのトピックの詳細については、EKS ドキュメントをご覧ください。
注 – VPC とノードの Cloudformation テンプレート、および EK が管理するノードグループがパブリック IP アドレスをノードに割り当てる方法を変更しています。詳しくは ブログをご覧ください。
EKS クラスターのアーキテクチャ
EKS クラスターは 2 つの VPC で構成されています。1 つは Kubernetes コントロールプレーンをホストする AWS が管理する VPC、もう 1 つはコンテナを実行する Kubernetes ワーカーノード (EC2 インスタンス) およびクラスターが使用するその他の AWS インフラストラクチャ (ロードバランサーなど) をホストする顧客が管理する VPCです。すべてのワーカーノードには、マネージド API サーバーエンドポイントに接続できる必要があります。 この接続により、ワーカーノードはそれ自体を Kubernetes コントロールプレーンに登録したり、アプリケーションポッドを実行するリクエストを受信したりできるようになります。
ワーカーノードは、パブリックエンドポイントに接続するか、クラスターの作成時に指定したサブネットに配置された EKS マネージド Elastic Network Interface (ENI) を介して接続します。ワーカーノードが接続に使用するルートは、クラスターのプライベートエンドポイントを有効にしたか、または無効にしたかによって決まります。プライベートエンドポイントが無効になっている場合でも、EKS は引き続き ENI をプロビジョニングして、Kubernetes API サーバーから発生するアクション (kubectl exec やログなど) を許可します。
下の図はこのシステムを表しています。

ワーカーノードがオンラインになり、コントロールプレーンからコマンドの受信を開始する操作の順序は、次のようになります。
- EC2 インスタンスを開始します。Kubelet と Kubernetes ノードエージェントを、各インスタンスの起動プロセスの一部として開始します。
- Kubelet は Kubernetes クラスターエンドポイントに到達し、ノードを登録します。Kubelet は VPC の外部のパブリックエンドポイント、または VPC 内のプライベートエンドポイントに接続します。
- Kubelet は API コマンドを受信し、定期的なステータスとハートビートをエンドポイントに送信します。APIサーバー (
kubectl get nodes
) にクエリを送信すると、各ノードの Kubelet が API サーバーに報告した最新のステータスが表示されます。
ノードがクラスターエンドポイントに到達できない場合、ノードはコントロールプレーンに登録できないため、ポッドを開始または停止するコマンドを受信できません。このため、新しいノードが接続できない場合、これらのノードをクラスターの一部として使用できなくなります。
ネットワーキングモード
EKSには、クラスターエンドポイントへのアクセスを制御する 2 つの方法があります。エンドポイントアクセスコントロールを使用すると、パブリックインターネットから、または VPC を介して、エンドポイントに到達可能か否かを設定できます。 パブリックエンドポイント (デフォルト)、プライベートエンドポイント、または両方のエンドポイントを同時に有効にすることができますパブリックエンドポイントが有効になっている場合は、CIDR 制限を追加することもできます。これで、パブリックエンドポイントに接続できるクライアント IP アドレスを制限できます。
ノードがマネージド Kubernetes コントロールプレーンに接続する方法は、クラスターに対して設定したエンドポイント設定によって決まります。これらのエンドポイント設定は、EKS コンソールまたは API を介していつでも変更できます。
パブリックエンドポイント専用
これは、新しい Amazon EKS クラスターのデフォルトの動作です。 クラスターのパブリックエンドポイントのみが有効になっている場合、クラスターの VPC 内から発生した Kubernetes API リクエスト (ワーカーノードからコントロールプレーンへの通信など) は VPC を離れますが、Amazon のネットワークを離れることはありません。ノードがコントロールプレーンに接続するには、ノードにパブリック IP アドレスとインターネットゲートウェイへのルート、または NAT ゲートウェイのパブリック IP アドレスを使用できる NAT ゲートウェイへのルートが必要です。

パブリックエンドポイントとプライベートエンドポイント
パブリックエンドポイントとプライベートエンドポイントの両方が有効になっている場合、VPC 内からの Kubernetes API リクエストは、VPC 内の EKS マネージド ENI を介してコントロールプレーンと通信します。クラスター API サーバーはインターネットからアクセスできます。

プライベートエンドポイント専用
プライベートエンドポイントのみが有効になっている場合、クラスター API サーバーへのすべてのトラフィックは、クラスターの VPC または接続されたネットワーク内から送信される必要があります。インターネットから API サーバーへのパブリックアクセスはありません。kubectl コマンドは、VPC または接続されたネットワーク内から実行する必要があります。これは通常、VPCにAWS VPN または AWS DirectConnect を使って行われます。エンドポイントへのアクセスを制限したいが、AWS VPN または AWS DirectConnect がない場合、パブリックエンドポイントに CIDR 制限を追加すると、ネットワーク設定を追加することなくエンドポイントへの接続を制限できます。
接続オプションの詳細については、「プライベート専用 API サーバーへのアクセス」をご覧ください。

サイドバー: ワーカーノードは、クラスターを起動したときに指定したものと同じサブネットにある必要がありますか?
いいえ。ワーカーノードは同じ VPC で実行する必要があるだけです。ワーカーノードは、クラスターの起動時に指定したサブネットとは別のサブネットで実行できます。これにより、IP スペースを増やしたり、複数のアベイラビリティーゾーンでノードを実行したりできます。ノードに使用するサブネットには適切なタグを付ける (クラスターの作成時に EKS が自動的に処理するステップ) 必要があるため、追加したサブネットには手動でタグを付ける必要があります。詳細については、「VPC 設定に関する EKS ドキュメント」をご参照ください。
VPC の設定
接続の基礎が完了したので、Amazon EKS を使ってクラスターネットワークをセットアップする一般的なシナリオをいくつか見ていきましょう。
一般に、ノードはパブリックサブネット、またはプライベートサブネットで実行されます。サブネットがパブリックかプライベートかは、サブネット内のトラフィックがインターネットゲートウェイを介してルーティングされているかどうかを示します。サブネットのトラフィックにインターネットゲートウェイを通るデフォルトルートがない場合、このサブネットはプライベートであると見なされます。
他の場所から発信してノードに到達するトラフィックの機能は、イングレスと呼ばれます。ノードから発信され、ネットワークを離れるトラフィックは、エグレスと呼ばれます。 インターネットゲートウェイで設定したサブネット内にパブリック IP アドレスまたは Elastic IP アドレスを持つノードは、VPC 外部からのイングレスを許可します。プライベートサブネットには通常、NAT ゲートウェイが含まれます。これにより、VPC 内からのノードへのイングレストラフィックのみが許可され、ノードからのトラフィックは VPC を離れる (エグレス) ことができます。
Amazon EKS クラスターの VPC を設定するには、3 つの一般的な方法があります。
- パブリックサブネットのみを使用します。ノードとイングレスリソース (ロードバランサーなど) は、すべて同じパブリックサブネットでインスタンスを作成します。
- パブリックサブネットとプライベートサブネットを使用します。ノードはプライベートサブネットで、イングレスリソース (ロードバランサーなど) はパブリックサブネットでインスタンスを作成します。
- プライベートサブネットのみを使用します。ノードはプライベートサブネットでインスタンスを作成します。この設定は、パブリックインターネットからの通信を受信する必要がないワークロードにのみ使用されるため、パブリックイングレスリソースはありません。
パブリック専用サブネット
これはシンプルかつ簡単な VPC アーキテクチャで、基本的なウェブアプリや、一般的にインターネットからノードへのイングレスが問題とならないアプリケーションであればどれにも適しています。この設定では、ノードとイングレスリソース (ロードバランサーなど) は、すべて同じパブリックサブネットでインスタンスを作成します。
設定のベストプラクティス
- すべてのサブネットは
mapPublicIpOnLaunch
を TRUE に設定し、インターネットゲートウェイへのルートを設定する必要があります。 - ノードは
AssociatePublicIpAddress
の値を必要としません (この値を CFN テンプレートまたは API 呼び出しに含めないでください)。 - クラスターエンドポイントは、パブリック、プライベート、またはその両方 (パブリックとプライベート) を有効にするように設定できます。

このアーキテクチャについては、Amazon VPC のドキュメントをご参照ください。この CloudFormation テンプレートを使用して、パブリック専用のサブネット設定で VPC を開始します。
パブリックサブネットとプライベートサブネット
この VPC アーキテクチャは、AWS での一般的な Kubernetes ワークロードのベストプラクティスと考えられています。この設定では、ノードはプライベートサブネットで、イングレスリソース (ロードバランサーなど) はパブリックサブネットでインスタンスを作成します。これで、ノードへのトラフィックを最大限に制御でき、Kubernetes アプリケーションの大部分でもうまく機能します。
設定のベストプラクティス
- パブリックサブネットでノードを起動しないため、パブリックサブネットに
mapPublicIpOnLaunch
を設定する必要がありません。 - プライベートサブネットの
mapPublicIpOnLaunch
は FALSE に設定する必要があります。 - ノードは
AssociatePublicIpAddress
の値を必要としません (この値を CFN テンプレートまたは API 呼び出しに含めないでください)。 - クラスターエンドポイントは、パブリック、プライベート、またはその両方 (パブリックとプライベート) を有効にするように設定できます。クラスターエンドポイントの設定に応じて、ノードトラフィックは NAT ゲートウェイまたは ENI を通過します。

このアーキテクチャについては、Amazon VPC のドキュメントをご参照ください。この CloudFormation テンプレートを使用して、パブリックとプライベート両方のサブネット設定で VPC を開始します。
また、これは eksctl のデフォルトの VPC 設定であることに留意してください。
プライベート専用サブネット
これは上記のバリアントですが、パブリックサブネットとパブリックエンドポイントが有効になっていません。
- プライベートサブネットの
mapPublicIpOnLaunch
は FALSE に設定する必要があります。 - ノードは
AssociatePublicIpAddress
の値を必要としません (この値を CFN テンプレートまたは API 呼び出しに含めないでください)。 - パブリックとプライベートの両方のクラスターエンドポイントを有効にする必要があります。

完全にプライベートなクラスター
これはあまり一般的ではない VPC アーキテクチャです。アプリケーションがパブリックインターネットからの通信を受信する必要がない場合、このアーキテクチャを使用してください。ローカルコンピュータからプライベートクラスターエンドポイントへの接続を確保する必要があります。
設定のベストプラクティス
- プライベートサブネットの
mapPublicIpOnLaunch
は FALSE に設定する必要があります。 - ノードは
AssociatePublicIpAddress
の値を必要としません (この値を CFN テンプレートまたは API 呼び出しに含めないでください)。 - プライベートクラスターエンドポイントのみを有効にする必要があります (パブリックエンドポイントを無効にします)。クラスターエンドポイントにアクセスするには、VPN 接続が必要です。
- EC2 とすべての Amazon ECR および S3 リポジトリで AWS PrivateLink を有効にします。 PrivateLink インターフェイスやゲートウェイエンドポイントを設定して、Kubernetes アプリケーションが他の AWS のサービスにアクセスできるようにする必要があります。
- クラスターで起動するすべてのコンテナイメージは、VPC 用に設定したエンドポイントを持つ ECR リポジトリから取得する必要があります。これには、ClusterAutoscaler やメトリクスサーバーなどの運用ツールのコンテナイメージが含まれます。

まとめ
このブログで、Amazon EKS VPC アーキテクチャのオプションについて理解を深めることができたでしょうか?VPC 設定の詳細については、Amazon EKS ドキュメントのネットワークセクションをご参照ください。
Nate