ポッド用のカスタムネットワーク - Amazon EKS

ポッド用のカスタムネットワーク

Amazon VPC CNI plugin for Kubernetes が、Amazon EC2 ノード用にセカンダリ Elastic Network Interface (ネットワークインターフェイス) を作成する際には、デフォルトで、ノードのプライマリネットワークインターフェイスと同じサブネットがその格納先になります。また、プライマリネットワークインターフェイスに関連付けられているものと同じセキュリティグループが、セカンダリネットワークインターフェイスにも関連付けられます。以下の 1 つ以上の理由により、プラグインを使用して異なるサブネットにセカンダリネットワークインターフェイスを作成させたり、セカンダリネットワークインターフェイスに異なるセキュリティグループを関連付けたり、また、その両方を行ったりする必要性が生じることがあります。

  • プライマリネットワークインターフェイスが存在するサブネットで使用可能な IPv4 アドレスには、数の上で制限があります。これにより、サブネット内に作成できる Pods の数に制限が生じる可能性があります。セカンダリネットワークインターフェイス用に別のサブネットを指定すると、Pods のために使用可能な IPv4 アドレスの数を増やすことができます。

  • セキュリティ上の理由からも、ノードのプライマリネットワークインターフェイスで使用するものとは異なるセキュリティグループまたはサブネットが、Pods に必要となる場合があります。

  • ノードをパブリックサブネット内に構成した場合、Pods はプライベートサブネット内に配置します。パブリックサブネットに関連付けられているルートテーブルには、インターネットゲートウェイへのルートが含まれています。プライベートサブネットに関連付けられているルートテーブルには、インターネットゲートウェイへのルートは含まれません。

考慮事項
  • カスタムネットワークを有効にすると、プライマリネットワークインターフェイスに割り当てられた IP アドレスは Pods に割り当てられません。Pods には、セカンダリネットワークインターフェイスからの IP アドレスのみが割り当てられます。

  • クラスターで IPv6 ファミリーを使用している場合は、カスタムネットワーキングを使用することはできません。

  • IPv4 アドレスの枯渇を軽減するために、カスタムネットワーキングを使用する予定の場合は、IPv6 ファミリーを使用してクラスターを作成することもできます。詳細については、「チュートリアル: Pods および services への IPv6 アドレスの割り当て」を参照してください。

  • サブネットにデプロイされたセカンダリネットワークインターフェイス用の Pods が、ノードのプライマリネットワークインターフェイスとは異なるサブネットおよびセキュリティグループを使用できるように設定されていても、そのサブネットとセキュリティグループは、ノードと同じ VPC 内に配置される必要があります。

前提条件
  • Amazon VPC CNI plugin for Kubernetes がセカンダリネットワークインターフェイスを作成し、IP アドレスを Pods に割り当てる方法に精通していること。詳細については、GitHub の「ENI Allocation」(ENI 割り当て) を参照してください。

  • ご使用のデバイスまたは AWS CloudShell で、AWS CLI のバージョン 2.12.3 以降または 1.27.160 以降がインストールおよび設定されていること。現在のバージョンは、aws --version | cut -d / -f2 | cut -d ' ' -f1 で確認できます。macOS の yumapt-get、または Homebrew などのパッケージマネージャは、AWS CLI の最新バージョンより数バージョン遅れることがあります。最新バージョンをインストールするには、「AWS Command Line Interface ユーザーガイド」の「AWS CLI のインストール、更新、およびアンインストール」と「aws configure でのクイック設定」を参照してください。AWS CloudShell にインストールされている AWS CLI バージョンは、最新バージョンより数バージョン遅れている可能性もあります。更新するには、「AWS CloudShell ユーザーガイド」の「ホームディレクトリへの AWS CLI のインストール」を参照してください。

  • デバイスまたは AWS CloudShell に、kubectl コマンドラインツールがインストールされていること。バージョンは、ご使用のクラスターの Kubernetes バージョンと同じか、1 つ前のマイナーバージョン以前、あるいはそれより新しいバージョンが使用できます。例えば、クラスターのバージョンが 1.26 である場合、kubectl のバージョン 1.251.26、または 1.27 が使用できます。kubectl をインストールまたはアップグレードする方法については、「kubectl のインストールまたは更新」を参照してください。

  • このトピック内の手順は、 Bash シェル内で実行することが推奨されます。Bash シェルを使用していない場合、行継続文字や、変数の設定と使用に関する方法など、一部のスクリプトコマンドのためにシェルの調整が必要となります。さらに、シェルの引用規則とエスケープ規則は異なる場合があります。詳細については、「AWS Command Line Interface ユーザーガイド」の「AWS CLI での文字列への引用符の使用」を参照してください。

このチュートリアルでは、example values を使用することをお勧めしますが、置き換えるように書かれている箇所はその限りではありません。本番稼働用クラスター向けに手順を完了するときには、どの example value も置き換えることができます。すべての手順は、同一のターミナルで実行することをお勧めします。設定された変数はステップ全体で使用され、また、これらは異なるターミナルには存在しないためです。

このトピックのコマンドは、「AWS CLI 使用例を使用する」に記載されている規則に従ってフォーマットされています。使用している AWS CLI プロファイルで定義されているデフォルトの AWS リージョン とは異なる AWS リージョン にあるリソースに対してコマンドラインからコマンドを実行する場合は、コマンドに --region region-code を追加する必要があります。

カスタムネットワーキングを本番用クラスターにデプロイする場合は、ステップ 2: VPC を設定する にスキップします。

ステップ 1: テスト VPC およびクラスターを作成する

クラスターを作成するには

次の手順により、テスト VPC とクラスターを作成し、そのたクラスターのためにカスタムネットワークを構成できます。本番向けのクラスターで必要になるいくつかの機能で、このトピックに関連のないものについては説明していません。そのため、本番ワークロード向けに、このテストクラスターを使用することはお勧めしません。詳細については、「Amazon EKS クラスターの作成」を参照してください。

  1. 残りのステップで使用する変数をいくつか定義します。

    export cluster_name=my-custom-networking-cluster account_id=$(aws sts get-caller-identity --query Account --output text)
  2. VPC を作成します。

    1. Amazon EKS の AWS CloudFormation テンプレートを使用して VPC を作成します。

      aws cloudformation create-stack --stack-name my-eks-custom-networking-vpc \ --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml \ --parameters ParameterKey=VpcBlock,ParameterValue=192.168.0.0/24 \ ParameterKey=PrivateSubnet01Block,ParameterValue=192.168.0.64/27 \ ParameterKey=PrivateSubnet02Block,ParameterValue=192.168.0.96/27 \ ParameterKey=PublicSubnet01Block,ParameterValue=192.168.0.0/27 \ ParameterKey=PublicSubnet02Block,ParameterValue=192.168.0.32/27

      AWS CloudFormation スタックが作成されるまで数分かかります。次のコマンドを実行して、スタックのデプロイステータスを確認します。

      aws cloudformation describe-stacks --stack-name my-eks-custom-networking-vpc --query Stacks\[\].StackStatus --output text

      コマンドの出力が「CREATE_COMPLETE」になるまで、次のステップに進まないでください。

    2. テンプレートによって作成された、プライベートサブネット ID の値により変数を定義します。

      subnet_id_1=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \ --query "StackResources[?LogicalResourceId=='PrivateSubnet01'].PhysicalResourceId" --output text) subnet_id_2=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \ --query "StackResources[?LogicalResourceId=='PrivateSubnet02'].PhysicalResourceId" --output text)
    3. 前の手順で取得した、サブネットのアベイラビリティーゾーンを使用して変数を定義します。

      az_1=$(aws ec2 describe-subnets --subnet-ids $subnet_id_1 --query 'Subnets[*].AvailabilityZone' --output text) az_2=$(aws ec2 describe-subnets --subnet-ids $subnet_id_2 --query 'Subnets[*].AvailabilityZone' --output text)
  3. クラスターの IAM ロールを作成します。

    1. IAM 信頼ポリシー用の JSON ファイルを作成するには、次のコマンドを実行します。

      cat >eks-cluster-role-trust-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
    2. Amazon EKS クラスター の IAM ロールを作成します。必要に応じて、eks-cluster-role-trust-policy.json の前に、手順でファイルの書き込み先となったコンピュータ上のパスを追加します。このコマンドは、前のステップで作成した信頼ポリシーをロールに関連付けます。IAM ロールを作成するには、ロールを作成する IAM プリンシパルiam:CreateRole アクション (許可) を割り当てる必要があります。

      aws iam create-role --role-name myCustomNetworkingAmazonEKSClusterRole --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
    3. このロールに、Amazon EKS 管理の IAM ポリシー (AmazonEKSClusterPolicy) をアタッチします。IAM ポリシーを IAM プリンシパルにアタッチするには、ポリシーのアタッチを行っているプリンシパルに、次のいずれかの IAM アクション (許可) を割り当てる必要があります: iam:AttachUserPolicy または iam:AttachRolePolicy

      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name myCustomNetworkingAmazonEKSClusterRole
  4. Amazon EKS クラスターを作成し、このクラスターとデバイスの間の通信を設定します。

    1. クラスターを作成する。

      aws eks create-cluster --name my-custom-networking-cluster \ --role-arn arn:aws:iam::$account_id:role/myCustomNetworkingAmazonEKSClusterRole \ --resources-vpc-config subnetIds=$subnet_id_1","$subnet_id_2
      注記

      リクエストで指定したアベイラビリティーゾーンのいずれかに、Amazon EKS クラスターの作成に十分な容量がない場合には、エラーが表示されることがあります。このエラー出力には、新しいクラスターをサポートできるアベイラビリティーゾーンが表示されます。アカウント向けにサポートされているアベイラビリティーゾーンにある 2 つ以上のサブネットを使用して、クラスターを作成します。詳細については、「容量不足」を参照してください。

    2. クラスターが作成されるまでに数分かかります。次のコマンドを実行して、クラスターのデプロイステータスを確認します。

      aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status

      コマンドの出力が「"ACTIVE"」になるまで、次のステップに進まないでください。

    3. クラスターと通信するために kubectl を設定します。

      aws eks update-kubeconfig --name my-custom-networking-cluster

ステップ 2: VPC を設定する

このチュートリアルでは、ステップ 1: テスト VPC およびクラスターを作成する で作成した VPC が必要です。本番クラスターの場合は、すべての example values を独自のものに置き換えて、VPC に応じて手順を調整します。

  1. 現在インストールされている Amazon VPC CNI plugin for Kubernetes のバージョンが最新であることを確認します。Amazon EKS アドオンタイプの最新バージョンを確認し、そのバージョンに更新するには、「アドオンの更新」を参照してください。セルフマネージドアドオンタイプの最新バージョンを確認し、そのバージョンに更新するには、「Amazon VPC CNI plugin for Kubernetes Amazon EKS アドオンの使用」を参照してください。

  2. クラスター VPC の ID を取得し、後の手順で使用するために変数に格納します。本番向けクラスターの場合は、my-custom-networking-cluster を自分のクラスター名に置き換えます

    vpc_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query "cluster.resourcesVpcConfig.vpcId" --output text)
  3. 追加の Classless Inter-Domain Routing (CIDR) ブロックを、クラスターの VPC に関連付けます。CIDR ブロックは、既存の関連付けられた CIDR ブロックと重複することはできません。

    1. 現在 VPC に関連付けられている CIDR ブロックを表示します。

      aws ec2 describe-vpcs --vpc-ids $vpc_id \ --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table

      出力例は次のとおりです。

      ---------------------------------- | DescribeVpcs | +-----------------+--------------+ | CIDRBlock | State | +-----------------+--------------+ | 192.168.0.0/24 | associated | +-----------------+--------------+
    2. 追加の CIDR ブロックを VPC に関連付けます。詳細については、「Amazon VPC ユーザーガイド」の「Associate additional IPv4 CIDR blocks with your VPC」(VPC とセカンダリ IP アドレス CIDR ブロックを関連付ける) を参照してください。

      aws ec2 associate-vpc-cidr-block --vpc-id $vpc_id --cidr-block 192.168.1.0/24
    3. 新しいブロックが関連付けられていることを確認します。

      aws ec2 describe-vpcs --vpc-ids $vpc_id --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table

      出力例は次のとおりです。

      ---------------------------------- | DescribeVpcs | +-----------------+--------------+ | CIDRBlock | State | +-----------------+--------------+ | 192.168.0.0/24 | associated | | 192.168.1.0/24 | associated | +-----------------+--------------+

    新しい CIDR ブロックの Stateassociated に遷移するまで、次のステップには進まないでください。

  4. 既存のサブネットが存在する各アベイラビリティーゾーン内で、使用するサブネットを必要な数だけ作成します。前のステップで VPC に関連付けた、CIDR ブロック内にある CIDR ブロックを指定します。

    1. 新しいサブネットを作成します。サブネットは、既存のサブネットが置かれているものとは異なる VPC CIDR ブロックの中に作成する必要があり、作成するアベイラビリティーゾーンは、既存のサブネットと同じにする必要があります。この例では、現在のプライベートサブネットが存在する各アベイラビリティーゾーンにある新しい CIDR ブロックの中に、1 つのサブネットが作成されます。作成されたサブネットの ID は、後のステップで使用するために変数に格納されます。Name の値は、前のステップで Amazon EKS VPC テンプレートを使用して作成されたサブネットに、割り当てられている値と一致します。名前は必須ではありません。名前には異なる値を使用できます。

      new_subnet_id_1=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_1 --cidr-block 192.168.1.0/27 \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet01},{Key=kubernetes.io/role/internal-elb,Value=1}]' \ --query Subnet.SubnetId --output text) new_subnet_id_2=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_2 --cidr-block 192.168.1.32/27 \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet02},{Key=kubernetes.io/role/internal-elb,Value=1}]' \ --query Subnet.SubnetId --output text)
      重要

      デフォルトで新しいサブネットは、VPC のメインルートテーブルに暗黙的に関連付けられます。このルートテーブルにより、その VPC にデプロイされているすべてのリソース間の通信が可能になります。ただし、VPC に関連付けられた CIDR ブロックの外部にある IP アドレスが割り当てられたリソースとの通信は許可されません。この動作を変更するには、独自のルートテーブルをサブネットに関連付けます。詳細については、「Amazon VPC ユーザーガイド」の「サブネットルートテーブル」を参照してください。

    2. 使用している VPC の現在のサブネットを表示します。

      aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" \ --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \ --output table

      出力例は次のとおりです。

      ---------------------------------------------------------------------- | DescribeSubnets | +------------------+--------------------+----------------------------+ | AvailabilityZone | CidrBlock | SubnetId | +------------------+--------------------+----------------------------+ | us-west-2d | 192.168.0.0/27 | subnet-example1 | | us-west-2a | 192.168.0.32/27 | subnet-example2 | | us-west-2a | 192.168.0.64/27 | subnet-example3 | | us-west-2d | 192.168.0.96/27 | subnet-example4 | | us-west-2a | 192.168.1.0/27 | subnet-example5 | | us-west-2d | 192.168.1.32/27 | subnet-example6 | +------------------+--------------------+----------------------------+

      作成した 192.168.1.0 CIDR ブロック内のサブネットが、192.168.0.0 CIDR ブロック内のサブネットと同じアベイラビリティーゾーンに置かれていることが確認できます。

ステップ 3: Kubernetes リソースを設定する

Kubernetes リソースを設定するには
  1. aws-node DaemonSetAWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG 環境変数を true に設定します。

    kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
  2. クラスターのセキュリティグループの ID を取得し、次のステップで使用するために変数に格納します。このセキュリティグループは、クラスターの作成時に Amazon EKS により自動的に作成されます。

    cluster_security_group_id=$(aws eks describe-cluster --name $cluster_name --query cluster.resourcesVpcConfig.clusterSecurityGroupId --output text)
  3. Pods をデプロイするサブネットごとに ENIConfig カスタムリソースを作成します。

    1. 各ネットワークインターフェイス設定に固有のファイルを作成します。

      次のコマンドでは、前のステップで作成した 2 つのサブネットのそれぞれに、個別の ENIConfig ファイルが作成されます。name の値は一意である必要があります。これらの名前は、サブネットが存在するアベイラビリティーゾーンと同じものが付けられます。クラスターセキュリティグループは、ENIConfig に割り当てられます。

      cat >$az_1.yaml <<EOF apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: $az_1 spec: securityGroups: - $cluster_security_group_id subnet: $new_subnet_id_1 EOF
      cat >$az_2.yaml <<EOF apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: $az_2 spec: securityGroups: - $cluster_security_group_id subnet: $new_subnet_id_2 EOF

      本番向けのクラスターでは、前のコマンドに次の変更を行います。

      • $cluster_security_group_id は、ENIConfig で使用する (既存の) セキュリティグループの ID に置き換えます。

      • 可能な限り、ENIConfig が使用されるアベイラビリティーゾーンと同じ名前を、ENIConfigs に付けることをお勧めします。いくつかの理由から、ENIConfigs に対して、アベイラビリティーゾーンとは異なる名前を使用する必要が生じることがあります。例えば、同じアベイラビリティーゾーンに 3 つ以上のサブネットがあり、そのすべてでカスタムネットワーキングを使用したい場合は、同一のアベイラビリティーゾーンに複数の ENIConfigs が必要になります。各 ENIConfig には一意の名前が必要であるため、複数の ENIConfigs に対しアベイラビリティーゾーンの名前を使用することはできません。

        ENIConfig 名がすべてアベイラビリティーゾーン名と同じでない場合は、前のコマンドで $az_1$az_2 を独自の名前に置き換え、このチュートリアルの後半でノードに ENIConfig の注釈を付けます

      注記

      本番向けクラスターで使用するために有効なセキュリティグループを指定しておらず、かつ:

      • Amazon VPC CNI plugin for Kubernetes のバージョン 1.8.0 以降を使用する場合は、ノードのプライマリ Elastic Network Interface に関連付けられたセキュリティグループが使用されます。

      • 1.8.0 より前のバージョンの Amazon VPC CNI plugin for Kubernetes を使用している場合は、VPC のデフォルトのセキュリティグループが、セカンダリネットワークインターフェースに割り当てられます。

      重要
      • AWS_VPC_K8S_CNI_EXTERNALSNAT=false は、Kubernetes 用の Amazon VPC CNI プラグインの設定のデフォルト設定です。デフォルト設定を使用している場合、VPC に関連付けられた CIDR ブロックのいずれにもない IP アドレスに向けて送信されたトラフィックには、ノードのプライマリネットワークインターフェイスでの、セキュリティグループとサブネットが使用されます。セカンダリネットワークインターフェイスを作成するために使用された、ENIConfigs で定義されているサブネットとセキュリティグループは、このトラフィックでは使用されません。この設定の詳細については、「Pods の SNAT」を参照してください。

      • また、Pods でもセキュリティグループ使用をする場合、そのセキュリティグループは SecurityGroupPolicy で指定されたものとなり、ENIConfigs で指定されたものは使用されません。詳細については、「チュートリアル: Pods のセキュリティグループ」を参照してください。

    2. 以下のコマンドを使用して、作成したカスタムリソースファイルをそれぞれクラスターに適用します。

      kubectl apply -f $az_1.yaml kubectl apply -f $az_2.yaml
  4. ENIConfigs が作成されたことを確認します。

    kubectl get ENIConfigs

    出力例は次のとおりです。

    NAME AGE us-west-2a 117s us-west-2d 105s
  5. 本番向けのクラスターで、カスタムネットワーキングを有効にしており、ENIConfigs の名前を使用されているアベイラビリティーゾーンとは異なるものにした場合は、次のステップに移り、Amazon EC2 ノードをデプロイします。

    クラスターで作成された任意の新しい Amazon EC2 ノードに対し、Kubernetes がアベイラビリティーゾーン用の ENIConfig を自動的に適用することを許可します。

    1. このチュートリアルでのテスト用クラスターの場合は、このまま次のステップに移動します。

      実稼働クラスターの場合は、ENI_CONFIG_ANNOTATION_DEF 環境変数用のキー k8s.amazonaws.com/eniConfig を使用する annotation が、aws-node DaemonSet のためのコンテナ仕様内に存在することを確認します。

      kubectl describe daemonset aws-node -n kube-system | grep ENI_CONFIG_ANNOTATION_DEF

      出力が返される場合は、アノテーションが存在します。出力が返されない場合、その変数は設定されていません。本番向けクラスターの場合には、ここでの設定と、以降のステップで示す設定のどちらも使用可能です。ここでの設定を使用すると、以降のステップの設定は上書きされます。このチュートリアルでは、この後のステップでの設定を使用します。

    2. クラスター内に作成された任意の新しい Amazon EC2 ノードに対し、自動的にアベイラビリティーゾーンのための ENIConfig を適用するように、aws-node DaemonSet を更新します。

      kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone

ステップ 4: Amazon EC2 ノードをデプロイする

Amazon EC2 ノードをデプロイするには
  1. ノードの IAM ロールを作成します。

    1. IAM 信頼ポリシー用の JSON ファイルを作成するには、次のコマンドを実行します。

      cat >node-role-trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
    2. 次のコマンドを実行して、ロール名の変数を設定します。myCustomNetworkingAmazonEKSNodeRole は、任意の名前に置き換えることができます。

      export node_role_name=myCustomNetworkingAmazonEKSNodeRole
    3. IAM ロールを作成し、返された Amazon リソースネーム (ARN) を、後のステップで使用するために変数に格納します。

      node_role_arn=$(aws iam create-role --role-name $node_role_name --assume-role-policy-document file://"node-role-trust-relationship.json" \ --query Role.Arn --output text)
    4. IAM ロールに、3 つの必須な IAM マネージドポリシーをアタッチします。

      aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \ --role-name $node_role_name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \ --role-name $node_role_name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \ --role-name $node_role_name
      重要

      分かりやすくするため、このチュートリアルでは、AmazonEKS_CNI_Policy ポリシーはノードの IAM ロールにアタッチされています。ただし、本番向けクラスターの場合は、Amazon VPC CNI plugin for Kubernetes のみで使用される IAM ロールに、個別にポリシーをアタッチすることをお勧めします。詳細については、「サービスアカウントの IAM ロールを使用する Amazon VPC CNI plugin for Kubernetes の設定」を参照してください。

  2. 次のいずれかのタイプのノードグループを作成します。デプロイするインスタンスタイプを確認するには、「Amazon EC2 インスタンスタイプを選択する」を参照してください。このチュートリアルのために、マネージド型、および起動テンプレートを使用しない、または AMI ID が指定されていない起動テンプレートを使用するオプションを完了します。本番ワークロードでノードグループを使用する場合は、そのグループをデプロイする前に、マネージド型およびセルフマネージド型の、すべてのノードグループオプションについて理解しておくことをお勧めします。

    • マネージド型 — 次のいずれかのオプションを使用して、ノードグループをデプロイします。

      • 起動テンプレートを使用しない、または AMI ID が指定されていない起動テンプレートを使用する — 次のコマンドを実行します。このチュートリアルでは、example values を使用します。本番稼働用のノードグループの場合は、すべての example values を実際の値に置き換えます。ノードグループ名は 63 文字以下である必要があります。先頭は文字または数字でなければなりませんが、残りの文字にはハイフンおよびアンダースコアを含めることもできます。

        aws eks create-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup \ --subnets $subnet_id_1 $subnet_id_2 --instance-types t3.medium --node-role $node_role_arn
      • 指定された AMI ID を持つ起動テンプレートを使用

        1. Amazon EKS で推奨される、ノードでの Pods の最大数を決定します。各 Amazon EC2 インスタンスタイプの Amazon EKS 推奨最大 Pods 数 の手順に従います (--cni-custom-networking-enabled をステップ 3 に追加してください)。後のステップで使用するために、この出力を書き留めます。

        2. 起動テンプレートで、Amazon EKS 最適化 AMI ID を指定するか、Amazon EKS 最適化 AMI から構築されたカスタム AMI を指定します。その後、起動テンプレートを使用してノードグループをデプロイし、さらに、起動テンプレートにある次のユーザーデータを指定します。このユーザーデータは、引数を bootstrap.sh ファイルに渡します。ブートストラップファイルの詳細については、「GitHub」の「bootstrap.sh」を参照してください。20 は、前のステップで使用した値 (推奨) か、または独自の値に置き換えることができます。

          /etc/eks/bootstrap.sh my-cluster --use-max-pods false --kubelet-extra-args '--max-pods=20'

          Amazon EKS 最適化 AMI から構築されていないカスタム AMI を作成した場合は、自分で設定をカスタム作成する必要があります。

    • セルフマネージド型

      1. Amazon EKS で推奨される、ノードでの Pods の最大数を決定します。各 Amazon EC2 インスタンスタイプの Amazon EKS 推奨最大 Pods 数 の手順に従います (--cni-custom-networking-enabled をステップ 3 に追加してください)。後のステップで使用するために、この出力を書き留めます。

      2. セルフマネージド型の Amazon Linux ノードの起動 の手順に従ってノードグループをデプロイします。BootstrapArguments パラメータに、以下のテキストを指定します。20 は、前のステップで使用した値 (推奨) か、または独自の値に置き換えることができます。

        --use-max-pods false --kubelet-extra-args '--max-pods=20'
    注記

    本番クラスター内のノードで、非常に大量の Pods をサポートさせる場合には、各 Amazon EC2 インスタンスタイプの Amazon EKS 推奨最大 Pods 数 のスクリプトを再度実行します。また、このコマンドには --cni-prefix-delegation-enabled オプションを追加します。例えば、m5.large インスタンスタイプの場合は 110 が返されます。この機能を有効化する方法については、「Amazon EC2 ノードで使用可能な IP アドレスの量を増やす」を参照してください。この機能は、カスタムネットワーキングで使用できます。

    ノードグループの作成には数分かかります。次のコマンドを使用すると、マネージド型のノードグループ作成のステータスを確認できます。

    aws eks describe-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup --query nodegroup.status --output text

    出力が「ACTIVE」を返すまで、次のステップに進まないでください。

  3. このチュートリアルでは、このステップをスキップできます。

    本番向けのクラスターにおいて、ENIConfigs の名前を、それが使用されているアベイラビリティーゾーンと同にしなかった場合には、ノードに対し、そのノードで使用すべき ENIConfig の名前をアノテーションします。各アベイラビリティーゾーンにサブネットが 1 つしかなく、ENIConfigs にアベイラビリティーゾーンと同じ名前を付けている場合には、このステップは必要ありません。前のステップで機能を有効化してあるのなら、Amazon VPC CNI plugin for Kubernetes が適切な ENIConfig をノードに対し自動的に関連付けるためです。

    1. クラスター内のノードのリストを取得します。

      kubectl get nodes

      出力例は次のとおりです。

      NAME STATUS ROLES AGE VERSION ip-192-168-0-126.us-west-2.compute.internal Ready <none> 8m49s v1.22.9-eks-810597c ip-192-168-0-92.us-west-2.compute.internal Ready <none> 8m34s v1.22.9-eks-810597c
    2. 各ノードが属するアベイラビリティーゾーンを決定します。前のステップで返された各ノードに対し 次のコマンドを実行します。

      aws ec2 describe-instances --filters Name=network-interface.private-dns-name,Values=ip-192-168-0-126.us-west-2.compute.internal \ --query 'Reservations[].Instances[].{AvailabilityZone: Placement.AvailabilityZone, SubnetId: SubnetId}'

      出力例は次のとおりです。

      [ { "AvailabilityZone": "us-west-2d", "SubnetId": "subnet-Example5" } ]
    3. 各ノードを、サブネット ID とアベイラビリティーゾーンのために作成した ENIConfig でアノテーションします。各ノードのアノテーションに使用できる ENIConfig は 1 つだけです。ただし、複数のノードに対し同じ ENIConfig でアノテーションすることは可能です。example values を自分の値に置き換えます。

      kubectl annotate node ip-192-168-0-126.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName1 kubectl annotate node ip-192-168-0-92.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName2
  4. カスタムネットワーキング機能の使用に切り替える前に、ノードを使用している本番向けクラスター内で Pods を実行していた場合には、以下のタスクを完了してください。

    1. カスタムネットワーク機能を使用しているノードが、使用可能であることを確認します。

    2. ノードを遮断およびドレインして、Pods をスムーズにシャットダウンします。詳細については、「Kubernetes ドキュメント」の「Safely Drain a Node」(ノードを安全にドレインする) を参照してください。

    3. ノードを終了します。ノードが既存のマネージド型ノードグループ内にある場合は、そのノードグループを削除できます。デバイスに沿ったコマンドをコピーします。必要に応じてコマンドに次の変更を加え、変更したコマンドを実行します。

      • my-cluster をクラスターの名前に置き換えます。

      • my-nodegroup をノードグループの名前に置き換えます。

      aws eks delete-nodegroup --cluster-name my-cluster --nodegroup-name my-nodegroup

    カスタムネットワーク機能は、k8s.amazonaws.com/eniConfig ラベルで登録されている新しいノードでのみ使用されます。

  5. Pods に、前の手順で作成したサブネットの 1 つに関連付けられた CIDR ブロックから、 IP アドレスが割り当てられていることを確認します。

    kubectl get pods -A -o wide

    出力例は次のとおりです。

    NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system aws-node-2rkn4 1/1 Running 0 7m19s 192.168.0.92 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system aws-node-k96wp 1/1 Running 0 7m15s 192.168.0.126 ip-192-168-0-126.us-west-2.compute.internal <none> <none> kube-system coredns-657694c6f4-smcgr 1/1 Running 0 56m 192.168.1.23 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system coredns-657694c6f4-stwv9 1/1 Running 0 56m 192.168.1.28 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system kube-proxy-jgshq 1/1 Running 0 7m19s 192.168.0.92 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system kube-proxy-wx9vk 1/1 Running 0 7m15s 192.168.0.126 ip-192-168-0-126.us-west-2.compute.internal <none> <none>

    VPC に追加した 192.168.1.0 CIDR ブロックからの IP アドレスが、coredns Pods に割り当てられていることが確認できます。カスタムネットワーキングを使用していない場合は、ここに 192.168.0.0 CIDR ブロックからのアドレスが割り当てられています。この CIDR ブロックが、元々 VPC に関連付けられている唯一のブロックであるためです。

    Pod's spechostNetwork=true を含む場合には、ノードのプライマリ IP アドレスが割り当てられます。追加したサブネットのアドレスは割り当てられません。デフォルトでは、この値は false に設定されます。この値は、クラスターで実行されている kube-proxy および Amazon VPC CNI plugin for Kubernetes(aws-node)Pods に対して true に設定されます。これが、kube-proxy とプラグインの aws-node Pods に対し、前の出力にある 192.168.1.x アドレスが割り当てられない理由です。Pod's hostNetwork の設定の詳細については、「Kubernetes API リファレンス」の「PodSpec v1 core」を参照してください。

ステップ 5: チュートリアルでのリソースを削除する

このチュートリアル完了後は、作成したリソースを削除することをお勧めします。その後、ここでの手順を調整して、本番向けクラスターのカスタムネットワーキングを有効化することができます。

チュートリアルでのリソースを削除するには
  1. 作成したノードグループが完全にテスト向けである場合は、それを削除してください。

    aws eks delete-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup

    AWS CLI から、クラスターが削除済みだと出力された場合でも、実際には、その削除プロセスが完了していない場合があります。削除のプロセスには数分かかります。次のコマンドを実行して、処理の完了を確認します。

    aws eks describe-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup --query nodegroup.status --output text

    次のように出力されるまで、次に進まないでください。

    An error occurred (ResourceNotFoundException) when calling the DescribeNodegroup operation: No node group found for name: my-nodegroup.
  2. 作成したノードグループが完全にテスト向けである場合は、ノードの IAM ロールを削除します。

    1. ロールからポリシーをデタッチします。

      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    2. ロールを削除します。

      aws iam delete-role --role-name myCustomNetworkingAmazonEKSNodeRole
  3. クラスターを削除します。

    aws eks delete-cluster --name $cluster_name

    以下のコマンドを使用して、クラスターが削除されたことを確認します。

    aws eks describe-cluster --name $cluster_name --query cluster.status --output text

    次のような出力が返された場合は、クラスターが正常に削除されています。

    An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-cluster.
  4. クラスターの IAM ロールを削除します。

    1. ロールからポリシーをデタッチします。

      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSClusterRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
    2. ロールを削除します。

      aws iam delete-role --role-name myCustomNetworkingAmazonEKSClusterRole
  5. 前のステップで作成したサブネットを削除します。

    aws ec2 delete-subnet --subnet-id $new_subnet_id_1 aws ec2 delete-subnet --subnet-id $new_subnet_id_2
  6. 作成した VPC を削除します。

    aws cloudformation delete-stack --stack-name my-eks-custom-networking-vpc