Knowledge Center Monthly Newsletter - March 2025
Stay up to date with the latest from the Knowledge Center. See all new and updated Knowledge Center articles published in the last month and re:Post’s top contributors.
如何在 Amazon EKS 中使用多个 CIDR 范围?
我想在 Amazon Elastic Kubernetes Service(Amazon EKS)中使用多个 CIDR 范围来解决我的容器组(pod)的问题。
简短描述
在完成解决方法部分的步骤之前,请确认您已有:
- 正在运行的 Amazon EKS 集群
- 最新版本的 AWS 命令行界面(AWS CLI)
- 管理 Amazon Virtual Private Cloud(Amazon VPC)的 AWS Identity and Access Management(IAM)权限
- 具有创建自定义资源和编辑 DaemonsSet 权限的 kubectl
- 已安装到您的系统上的某个版本的 jq
**注意:**要下载和安装 jq,请参阅 jq 网站上的 Download jq。 - 带有 Bash shell 的基于 Unix 的系统
- 已配置的 VPC
注意:
- 在创建集群之前或之后,您可以将私有(RFC 1918)和公有(非 RFC 1918)CIDR 块关联到 VPC。
- 在运营商级网络地址转换(NAT)场景中,100.64.0.0/10 是一个私有网络范围。私有网络范围用于共享地址空间,以用于服务提供商与订阅用户之间的通信。要让容器组(pod)与互联网通信,您必须在路由表上配置 NAT 网关。AWS Fargate 集群不支持 DaemonSets。要将辅助 CIDR 范围添加到 Fargate 配置文件,请使用 VPC 的辅助 CIDR 块中的子网。然后,在将子网添加到 Fargate 配置文件之前,标记新子网。
**重要信息:**在某些情况下,Amazon EKS 无法与您在创建集群后添加到 VPC 的 CIDR 块的子网中启动的节点通信。当您向现有集群添加 CIDR 块时,更新的范围显示最长可能需要等待 5 小时。
解决方法
**注意:**如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 AWS CLI 错误。此外,请确保您使用的是最新版本的 AWS CLI。
在以下解决方法中,首先设置您的 VPC。然后,配置 CNI 插件以使用新的 CIDR 范围。
添加更多 CIDR 范围来扩展您的 VPC 网络
完成以下步骤:
-
找到 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'
-
要将 VPC 连接到 VPC_ID 变量,运行以下命令:
export VPC_ID=vpc-xxxxxxxxxxxx
要将另一个带有 100.64.0.0/16 范围的 CIDR 块关联到 VPC,运行以下命令:
aws ec2 associate-vpc-cidr-block --vpc-id $VPC_ID --cidr-block 100.64.0.0/16
使用新 CIDR 范围创建子网
完成以下步骤:
-
要列出您的区域的所有可用区,运行以下命令:
aws ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[*].ZoneName'
**注意:**将 us-east-1 替换为您的区域。
-
选择要添加子网的可用区,然后将可用区分配给变量。例如:
export AZ1=us-east-1a export AZ2=us-east-1b export AZ3=us-east-1c
**注意:**要添加更多可用区,创建其他变量。
-
要在 VPC 下使用新 CIDR 范围创建新子网,运行以下命令:
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)
-
(可选)设置键值对,为子网添加名称标签。例如:
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
将新子网关联到路由表
完成以下步骤:
-
要列出 VPC 下的整个路由表,运行以下命令:
aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'
-
要将路由表导出到变量,运行以下命令:
export RTASSOC_ID=rtb-abcabcabc
**注意:**将 rtb-abcabcabc 替换为上一步中的值。
-
将路由表关联到所有新子网。例如:
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
有关更多信息,请参阅以下文章中的 Routing 部分:Example: VPC with servers in private subnets and NAT。
配置 CNI 插件以使用新的 CIDR 范围
完成以下步骤:
-
将最新版本的 vpc-cni 插件添加到集群中。要验证集群中的版本,运行以下命令:
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
要启用 CNI 插件的自定义网络配置,运行以下命令:
kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
-
要添加 ENIConfig 标签来标识 Worker 节点,运行以下命令:
kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone
-
要为所有子网和可用区创建 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 必须与 Worker 节点的可用区匹配。
-
启动 Worker 节点,让 CNI 插件(ipamd)可以将新 CIDR 范围中的 IP 地址分配给新的 Worker 节点。
如果使用自定义网络,主网络接口不会用于放置容器组(pod)。在这种情况下,您必须先使用以下公式更新 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 的管理器节点组,托管节点组会自动计算最大容器组(pod)值。按照创建托管节点组中的步骤进行操作。或者,使用 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>
如果使用具有指定 AMI ID 的托管节点组启动模板,请在启动模板中指定 Amazon EKS 优化的 AMI ID。或者,基于 Amazon EKS 优化的 AMI 使用自定义 AMI。然后,使用启动模板部署节点组,并在启动模板中提供以下用户数据:
#!/bin/bash /etc/eks/bootstrap.sh <my-cluster-name> --kubelet-extra-args <'--max-pods=20'>
-
记下子网的安全组,并将安全组应用于关联的 ENIConfig:
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
**注意:**将 sg-xxxxxxxxxxxx 替换为您的安全组。
-
启动新部署来测试配置:
kubectl create deployment nginx-test --image=nginx --replicas=10 kubectl get pods -o wide --selector=app=nginx-test
**注意:**在前面的测试部署中,添加了 10 个新的容器组(pod),并且为新的 Worker 节点安排了新的 CIDR 范围。

相关内容
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 1 年前