Amazon EKS で複数の CIDR 範囲を使用する方法を教えてください。
最終更新日: 2021 年 12 月 10 日
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 ベースのシステム
以下の点にご注意ください。
- 異なる CIDR 範囲でポッドを実行すると、Amazon EKS で管理されるポッドで利用可能な IP アドレスが増えます。また、ネットワーキングアーキテクチャの柔軟性が向上します。2 つの条件下において、ポッドは VPC 内の RFC 1918 IP アドレスを消費しません。最初の条件は、100.64.0.0/10 と 198.19.0.0/16 の範囲から VPC にセカンダリ CIDR ブロックを追加することです。2 つ目の条件は、CNI カスタムネットワーキングを使用することです。
- キャリアグレードのネットワークアドレス変換 (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. CNI プラグインの最新バージョンがあることを確認するには、次のコマンドを実行します。
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
CNI プラグインのバージョンが 1.5.3 より古い場合、次のコマンドを実行して最新バージョンに更新します。
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/v1.5/aws-k8s-cni.yaml
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 カスタムリソース定義を (Kubernetes ウェブサイトから) インストールするには、次のコマンドを実行します。
cat << EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: eniconfigs.crd.k8s.amazonaws.com
spec:
scope: Cluster
group: crd.k8s.amazonaws.com
version: v1alpha1
names:
plural: eniconfigs
singular: eniconfig
kind: ENIConfig
EOF
5. すべてのサブネットとアベイラビリティーゾーン用に 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 は、ワーカーノードのアベイラビリティーゾーンと一致する必要があります。
6. 新しいワーカーノードを起動します。注: このステップにより、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 が推奨する最大ポッド数を自動的に計算します。マネージドノードグループの作成 のステップに従うか、AWS 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=
- 指定した 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'>
7. ノードグループを作成したら、サブネットのセキュリティグループをメモし、関連付けられた 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
8. 古いワーカーノードを終了し、新しいデプロイを起動して設定をテストします。
kubectl create deployment nginx-test --image=nginx --replicas=10
kubectl get pods -o wide --selector=app=nginx-test
10 個の新しいポッドが追加され、新しい CIDR 範囲が新しいワーカーノードにスケジュールされます。