Amazon EKS で複数の CIDR 範囲を使用する方法を教えてください。

最終更新日: 2021 年 12 月 10 日

Amazon Elastic Kubernetes Service (Amazon EKS) で複数の CIDR 範囲を使用して、ポッドの問題に対処したいと考えています。例えば、Amazon Virtual Private Cloud (Amazon VPC) に追加された異なる CIDR 範囲でポッドを実行するにはどうすればよいですか? また、サブネットで IP アドレスが不足したときに、どうすればサブネットに IP アドレスを追加できますか? 最後に、ワーカーノードで実行されているポッドの IP 範囲が異なることを確認する方法を教えてください。

簡単な説明

解決方法セクションの手順を実行する前に、以下があることを確認してください。

以下の点にご注意ください。

  • 異なる CIDR 範囲でポッドを実行すると、Amazon EKS で管理されるポッドで利用可能な IP アドレスが増えます。また、ネットワーキングアーキテクチャの柔軟性が向上します。2 つの条件下において、ポッドは VPC 内の RFC 1918 IP アドレスを消費しません。最初の条件は、100.64.0.0/10198.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= 」の追加引数を指定します。起動テンプレートで、Amazon EKS 最適化 AMI ID、または Amazon EKS 最適化 AMI から構築されたカスタム AMI を指定します。次に、 起動テンプレートを使用してノードグループをデプロイし、起動テンプレートに次のユーザーデータを入力します。

  • 指定した 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 範囲が新しいワーカーノードにスケジュールされます。


この記事は役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?