我该如何通过 Amazon EKS 使用多个 CIDR 范围?

上次更新时间:2020 年 2 月 5 日

我想通过 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 版本
  • 基于 Unix 的系统和 Bash shell

注:如果在不同的 CIDR 范围上运行 Pod,那么您将获得由 Amazon EKS 管理的适用于 Pod 的更多可用 IP 地址,并且能够更灵活地使用您的联网架构。如果从 100.64.0.0/10198.19.0.0/16 范围添加辅助 CIDR 块添加到 VPC,而且使用 CNI 自定义网络,那么,您的 Pod 将不会消耗 VPC 内的任何 RFC 1918 IP 地址。

注:若使用运营商级别的网络地址转换 (NAT),则 100.64.0.0/10 为在共享地址空间中用于服务提供商及其订阅者之间通信的私有网络范围。您的 NAT 网关必须在路由表中被配置为用于 Pod 和互联网之间的通信。

解决方法

在以下解决方法中,您要设置 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.    要将额外的 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.    要在 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)

标记新子网

您必须标记全部子网,以便 Amazon EKS 可以发现这些子网。

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.    进行标记以方便 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,考虑添加更多标签。如需更多信息,见集群 VPC 注意事项

将您的新子网关联到路由表

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

如需更多信息,见路由选择

配置 CNI 插件以使用新的 CIDR 范围

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 自定义资源定义,运行以下命令:

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 地址。

7.    要通过启动 Pod 测试配置,运行以下命令:

kubectl run nginx --image nginx --replicas 10
kubectl get pods -o wide

您应该会看到 10 个新的 Pod,它们通过新工作线程节点上排定的新 CIDR 范围添加。


这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?