Amazon EKS で複数の CIDR 範囲を使用するにはどうすればよいですか?
最終更新日: 2022 年 12 月 27 日
Amazon Elastic Kubernetes Service (Amazon EKS) で複数の CIDR 範囲を使用して、ポッドの問題に対処したいと考えています。例えば、Amazon Virtual Private Cloud (Amazon VPC) に追加された異なる CIDR 範囲でポッドを実行するにはどうすればよいですか? また、サブネットで IP アドレスが不足したときに、どうすればサブネットに IP アドレスを追加できますか? 最後に、ワーカーノードで実行されているポッドの IP 範囲が異なることを確認する方法を教えてください。
簡単な説明
解決方法セクションの手順を実行する前に、以下があることを確認してください。
- 実行中の Amazon EKS クラスター
- AWS コマンドラインインターフェイス (AWS CLI) のバージョン (1.16.284 以降) へのアクセス
- Amazon VPC を管理するための AWS Identity and Access Management (IAM) アクセス許可
- カスタムリソースを作成して DaemonsSet を編集するアクセス許可を持つ kubectl
- システムに (jq Web サイトから) インストールされている jq のバージョン
- Bash シェルを備えた Unix ベースのシステム
次の点にご注意ください。
- クラスターの作成前または作成後に、プライベート (RFC 1918) およびパブリック (非 RFC 1918) の CIDR ブロックを VPC に関連付けることができます。
- キャリアグレードのネットワークアドレス変換 (NAT) を使用するシナリオでは、100.64.0.0/10 はプライベートネットワーク範囲です。このプライベートネットワーク範囲は、サービスプロバイダーとそのサブスクライバー間の通信に共有アドレス空間で使用されます。ポッドがインターネットと通信するには、ルートテーブルで NAT ゲートウェイを設定する必要があります。Daemonsets は、AWS Fargate クラスターではサポートされていません。セカンダリ CIDR 範囲を Fargate プロファイルに追加するには、VPC のセカンダリ CIDR ブロックのサブネットを使用します。その後、サブネットを Fargate プロファイルに追加する前に、新しいサブネットにタグを付けます。
重要: 特定の状況では、Amazon EKS は、クラスターの作成後に VPC にさらに追加された CIDR ブロックからサブネットで起動されたノードと通信できません。CIDR ブロックを既存のクラスターに追加することによって更新された範囲が表示されるまでに、最長で 5 時間かかる場合があります。
解決方法
注: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください。
次の解決方法では、最初に VPC を設定します。その後、新しい CIDR 範囲を使用するように CNI プラグインを設定します。
CIDR 範囲を追加して VPC ネットワークを拡張する
1. VPC を見つけます。
VPC にタグがある場合は、次のコマンドを実行して VPC を見つけます。
VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=yourVPCName | jq -r '.Vpcs[].VpcId')
VPC にタグがない場合は、次のコマンドを実行して AWS リージョン内のすべての VPC を一覧表示させます。
aws ec2 describe-vpcs --filters | jq -r '.Vpcs[].VpcId'
2. VPC を VPC_ID 変数にアタッチするには、次のコマンドを実行します。
export VPC_ID=vpc-xxxxxxxxxxxx
3. 追加の CIDR ブロックを 100.64.0.0/16 の範囲で VPC に関連付けるには、次のコマンドを実行します。
aws ec2 associate-vpc-cidr-block --vpc-id $VPC_ID --cidr-block 100.64.0.0/16
新しい CIDR 範囲でサブネットを作成する
1. AWS リージョンのすべてのアベイラビリティーゾーンを一覧表示するには、次のコマンドを実行します。
aws ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[*].ZoneName'
注: us-east-1 を AWS リージョンに置き換えます。
2. サブネットを追加するアベイラビリティーゾーンを選択し、そのアベイラビリティーゾーンを変数に割り当てます。以下はその例です。
export AZ1=us-east-1a
export AZ2=us-east-1b
export AZ3=us-east-1c
注: さらに変数を作成して、アベイラビリティーゾーンを追加できます。
3. 新しい CIDR 範囲で VPC に新しいサブネットを作成するには、次のコマンドを実行します。
CUST_SNET1=$(aws ec2 create-subnet --cidr-block 100.64.0.0/19 --vpc-id $VPC_ID --availability-zone $AZ1 | jq -r .Subnet.SubnetId)
CUST_SNET2=$(aws ec2 create-subnet --cidr-block 100.64.32.0/19 --vpc-id $VPC_ID --availability-zone $AZ2 | jq -r .Subnet.SubnetId)
CUST_SNET3=$(aws ec2 create-subnet --cidr-block 100.64.64.0/19 --vpc-id $VPC_ID --availability-zone $AZ3 | jq -r .Subnet.SubnetId)
新しいサブネットにタグを付ける
Kubernetes 1.18 以前で実行されているクラスターでは、Amazon EKS がサブネットを検出できるように、すべてのサブネットにタグを付ける必要があります。
注意: Amazon EKS は、Kubernetes バージョン 1.19 から始まる kubernetes.io タグのないサブネットの自動検出をサポートしています。詳細については、Kubernetes GitHub サイトの変更履歴を参照してください。
1. (オプション) キーと値のペアを設定して、サブネットの名前タグを追加します。以下はその例です。
aws ec2 create-tags --resources $CUST_SNET1 --tags Key=Name,Value=SubnetA
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=Name,Value=SubnetB
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=Name,Value=SubnetC
2. Kubernetes 1.18 以下で実行されているクラスターの場合は、Amazon EKS による検出のためにサブネットにタグを付けます。以下はその例です。
aws ec2 create-tags --resources $CUST_SNET1 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET2 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
aws ec2 create-tags --resources $CUST_SNET3 --tags Key=kubernetes.io/cluster/yourClusterName,Value=shared
注: yourClusterName を Amazon EKS クラスターの名前に置き換えます。
Elastic Load Balancing を使用する予定の場合は、タグをさらに追加することを検討してください。
新しいサブネットをルートテーブルに関連付ける
1. VPC の下のルートテーブル全体を一覧表示するには、次のコマンドを実行します。
aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'
2. サブネットに関連付けるルートテーブルについて、次のコマンドを実行して変数にエクスポートします。その後、rtb-xxxxxxxxx をステップ 1 の値に置き換えます。
export RTASSOC_ID=rtb-xxxxxxxxx
3. ルートテーブルをすべての新しいサブネットに関連付けます。以下はその例です。
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET1
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET2
aws ec2 associate-route-table --route-table-id $RTASSOC_ID --subnet-id $CUST_SNET3
詳細については、ルーティングを参照してください。
新しい CIDR 範囲を使用するように CNI プラグインを設定する
1. vpc-cni プラグインの最新推奨バージョンがクラスターで実行されていることを確認してください。
クラスターで実行されているバージョンを確認するには、次のコマンドを実行します。
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2<br>
vpc-cni の最新推奨バージョンを確認し、必要に応じてプラグインを更新するには、「Updating the Amazon VPC CNI plugin for Kubernetes add-on」(Kubernetes アドオン用 Amazon VPC CNI プラグインの更新) を参照してください。
2. CNI プラグインのカスタムネットワーク設定を有効にするには、次のコマンドを実行します。
kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
3. ワーカーノードを識別するための ENIConfig ラベルを追加するには、次のコマンドを実行します。
kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone
4. すべてのサブネットとアベイラビリティーゾーン用に ENIConfig カスタムリソースを作成するには、次のコマンドを実行します。
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ1
spec:
subnet: $CUST_SNET1
EOF
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ2
spec:
subnet: $CUST_SNET2
EOF
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ3
spec:
subnet: $CUST_SNET3
EOF
注: ENIConfig は、ワーカーノードのアベイラビリティーゾーンと一致する必要があります。
5. 新しいワーカーノードを起動します。
注: このステップにより、CNI プラグイン (ipamd) は、新しいワーカーノードの新しい CIDR 範囲から IP アドレスを割り当てることができます。
カスタムネットワークを使用している場合、プライマリネットワークインターフェイスはポッド配置には使用されません。この場合、次の数式を使用して max-pods を更新する必要があります。
maxPods = (number of interfaces - 1) * (max IPv4 addresses per interface - 1) + 2
- セルフマネージドノードグループ: 「セルフマネージド型の Amazon Linux ノードの起動」の手順に従ってノードグループをデプロイします。デプロイした ENIConfig リソースで使用したサブネットを指定しないでください。代わりに、BootstrapArguments パラメータに次のテキストを指定します。
--use-max-pods false --kubelet-extra-args '--max-pods=<20>'
- 起動テンプレートなし、または AMI ID を指定しない起動テンプレートを使用した、マネージドノードグループ: マネージドノードグループは Amazon EKS が推奨する最大ポッド数を自動的に計算します。「マネージド型ノードグループの作成」のステップに従います。または、Amazon EKS CLI を使用してマネージドノードグループを作成します。
aws eks create-nodegroup --cluster-name <sample-cluster-name> --nodegroup-name <sample-nodegroup-name> --subnets <subnet-123 subnet-456> --node-role <arn:aws:iam::123456789012:role/SampleNodeRole>
注: サブネットフィールドには、ENIConfig リソースで指定したサブネットを指定しないでください。必要に応じて、さらにオプションを指定できます。
- 指定した AMI ID を持つ起動テンプレートを使用したマネージドノードグループ: 起動テンプレートのユーザーデータとして「--max-pods=
」 の追加引数を指定します。起動テンプレートで、Amazon EKS 最適化 AMI ID、または Amazon EKS 最適化 AMI から構築されたカスタム AMI を指定します。その後、起動テンプレートを使用してノードグループをデプロイし、起動テンプレートに次のユーザーデータを入力します。
#!/bin/bash
/etc/eks/bootstrap.sh <my-cluster-name> --kubelet-extra-args <'--max-pods=20'>
6. ノードグループを作成したら、サブネットのセキュリティグループをメモし、関連付けられた ENIConfig にセキュリティグループを適用します。
次の例では、sg-xxxxxxxxxxxx をセキュリティグループに置き換えます。
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ1
spec:
securityGroups:
- sg-xxxxxxxxxxxx
subnet: $CUST_SNET1
EOF
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ2
spec:
securityGroups:
- sg-xxxxxxxxxxxx
subnet: $CUST_SNET2
EOF
cat <<EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata:
name: $AZ3
spec:
securityGroups:
- sg-xxxxxxxxxxxx
subnet: $CUST_SNET3
EOF
7. 古いワーカーノードを終了します。その後、新しいデプロイを起動して設定をテストします。10 個の新しいポッドが追加され、新しい CIDR 範囲が新しいワーカーノードにスケジュールされます。
kubectl create deployment nginx-test --image=nginx --replicas=10
kubectl get pods -o wide --selector=app=nginx-test