我该如何通过 Amazon EKS 使用多个 CIDR 范围?
我想通过 Amazon Elastic Kubernetes Service(Amazon EKS)使用多个 CIDR 范围以解决我的容器组(pod)遇到的问题。例如,如何通过添加到我的 Amazon Virtual Private Cloud (Amazon VPC) 的不同 CIDR 范围运行 Pod? 此外,当子网的 IP 地址耗尽时,如何为它增加更多 IP 地址? 最后,我要如何确保在工作线程节点上运行的 Pod 有不同的 IP 范围?
简短描述
在您完成解决方法部分的步骤前,确保您有以下各项:
- 处于运行状态的 Amazon EKS 集群
- 可访问版本号不低于 1.16.284 的 AWS 命令行界面 (AWS CLI) 的权限
- 可管理 Amazon VPC 的 AWS Identity and Access Management (IAM) 权限
- kubectl 和创建自定义资源及编辑 DaemonsSet 的权限
- 系统上已安装的 jq 版本(来自 jq 网站)
- 带有 Bash shell 的基于 Unix 的系统
请记住:
- 在创建集群之前或之后,您可以将私有(RFC 1918)和公有(非 RFC 1918)CIDR 数据块关联到您的 VPC。
- 在运营商级网络地址转换(NATI)的情况下,100.64.0.0/10 是专用网络范围。此专用网络范围用于共享地址空间,以实现服务提供商与其订阅者之间的通信。您的 NAT 网关必须在路由表中被配置为用于容器组(pod)和互联网之间的通信。AWS Fargate 集群不支持 Daemonsets。要将辅助 CIDR 范围添加到 Fargate 配置文件,使用 VPC 的辅助 CIDR 数据块中的子网。然后,标记新子网后再将子网添加到您的 Fargate 配置文件。
**重要提示:**在某些情况下,创建集群后,Amazon EKS 无法与通过添加到 VPC 的其他 CIDR 数据块在子网中启动的节点进行通信。向现有集群添加 CIDR 数据块所导致的更新范围可能需要长达 5 小时才能显示。
解决方法
**注意:**如果在运行 AWS CLI 命令时收到错误,请确保您使用的是最新版本的 AWS CLI。
在以下解决方案中,您首先需要设置 VPC。然后,配置 CNI 插件以使用新的 CIDR 范围。
添加额外的 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. 要将范围为 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 范围创建子网
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. 要在 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)
为新子网贴标签
对于在 Kubernetes 1.18 及更早版本上运行的集群,您必须为全部子网贴标签,以便 Amazon EKS 可以发现这些子网。
**注意:**从 Kubernetes 版本 1.19 开始,Amazon EKS 支持自动发现子网,而不需要任何 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 集群的名称。
如果您计划使用弹性负载均衡,则考虑添加其他标签。
将您的新子网关联到路由表
1. 要列出 VPC 下方的完整路由表,运行以下命令:
aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'
2. 对于要与子网关联的路由表,请运行以下命令以导出到变量。然后,用步骤 1 中的值替换 rtb-xxxxxxxxx:
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
有关更多信息,请参阅路由。
配置 CNI 插件以使用新的 CIDR 范围
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 必须与您的 Worker 节点的可用区匹配。
5. 启动新的 Worker 节点。
**注意:**此步骤允许 CNI 插件(ipamd)从新的 CIDR 范围中为新的 Worker 节点分配 IP 地址。
当您使用自定义联网时,主网络接口不会用于容器组(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 的启动模板,则托管节点组会自动计算 Amazon EKS 建议的最大容器组(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>
**注意:**对于子网字段,请勿指定您在 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. 终止旧的 Worker 节点。然后,通过启动新部署来测试配置。添加了 10 个新的容器组(pod),并且为新的 Worker 节点安排了新的 CIDR 范围:
kubectl create deployment nginx-test --image=nginx --replicas=10 kubectl get pods -o wide --selector=app=nginx-test

相关内容
- 已提问 5 个月前lg...
- 已提问 7 个月前lg...
- AWS 官方已更新 8 个月前
- AWS 官方已更新 2 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 8 个月前