跳至内容

如何在 Amazon EKS 中使用多个 CIDR 范围?

3 分钟阅读
0

我想在 Amazon Elastic Kubernetes Service (Amazon EKS) 中使用多个 CIDR 范围来解决我的容器组的问题。

简短描述

要在 Amazon EKS 中使用多个 CIDR 范围,请完成以下步骤:

  1. 添加更多 CIDR 范围以扩展您的虚拟私有云 (VPC) 网络。
  2. 使用新 CIDR 范围创建子网。
  3. 将新子网关联到路由表。
  4. 配置 Amazon Virtual Private Cloud (Amazon VPC) 容器网络接口 (CNI) 插件,以使用新的 CIDR 范围。

**注意:**最佳做法是使用运营商级 NAT (CGN) 空间中的 CIDR (/16),例如 100.64.0.0/10198.19.0.0/16。在自定义网络中,您可以使用有效的 VPC 范围作为辅助 CIDR 范围。但是,这些范围不太可能在企业环境中使用。有关自定义网络要求的详细信息,请参阅注意事项

解决方法

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

**先决条件:**您必须拥有以下配置:

添加更多 CIDR 范围来扩展您的 VPC 网络

完成以下步骤:

  1. 要检索集群 VPC 的 ID 并将其存储在变量中,请运行以下 AWS CLI describe-cluster 命令:
    VPC_ID=$(aws eks describe-cluster --name CLUSTER_NAME --region REGION_CODE --query "cluster.resourcesVpcConfig.vpcId" --output text)
    **注意:**请将 CLUSTER_NAME 替换为您的集群名称,将 REGION_CODE 替换为您部署集群的 AWS 区域。
  2. 要将另一个 CIDR 块(范围为 100.64.0.0/16)关联到 VPC,请运行以下 associate-vpc-cidr-block 命令:
    aws ec2 associate-vpc-cidr-block --vpc-id $VPC_ID --cidr-block 100.64.0.0/16

使用新 CIDR 范围创建子网

完成以下步骤:

  1. 要列出您所在区域中的所有可用区,请运行以下 describe-availability-zones 命令:
    aws ec2 describe-availability-zones --region REGION_CODE --query 'AvailabilityZones[*].ZoneName'
    **注意:**请将 REGION_CODE 替换为您部署资源的区域。
  2. 在现有子网所在的每个可用区中创建您要使用的子网。要在 VPC 下使用新 CIDR 范围创建新子网,请运行以下 create-subnet 命令。
    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)
    **注意:**请将 AZ1AZ2AZ3 替换为您现有子网所在的可用区。
  3. (可选)要设置键值对以向子网添加名称标签,请运行以下 create-tags 命令:
    aws ec2 create-tags --resources $CUST_SNET1 --tags Key=KEY,Value=VALUE
    aws ec2 create-tags --resources $CUST_SNET2 --tags Key=KEY,Value=VALUE
    aws ec2 create-tags --resources $CUST_SNET3 --tags Key=KEY,Value=VALUE
    **注意:**请将 KEY 替换为标签键,将 VALUE 替换为标签值。

将新子网关联到路由表

默认情况下,Amazon VPC 会将新子网与 VPC 的主路由表相关联。此路由表仅允许在 VPC 中部署的资源之间进行通信。要允许与 VPC CIDR 块之外的 IP 地址进行通信,您必须为您的子网创建自己的路由表

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

完成以下步骤:

  1. 确保为 Kubernetes 版本运行正确的插件版本。要验证版本,请运行以下命令:

    kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

    如果您没有正确的插件版本,请更新 Amazon VPC CNI

  2. 要激活 Amazon VPC CNI 插件的自定义网络配置,请运行以下命令:

    kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
  3. 要添加 ENIConfig 标签来标识 Worker 节点,请运行以下命令:

    kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone
  4. 要为所有子网和可用区创建 ENIConfig 自定义资源,请运行以下命令:

    cat <<EOF  | kubectl apply -f -apiVersion: crd.k8s.amazonaws.com/v1alpha1
    kind: ENIConfig
    metadata:
     name: $AZ1
    spec:
      securityGroups:
        - cluster_security_group_id
      subnet: $CUST_SNET1
    EOF
    
    cat <<EOF | kubectl apply -f -
    apiVersion: crd.k8s.amazonaws.com/v1alpha1
    kind: ENIConfig
    metadata:
     name: $AZ2
    spec:
      securityGroups:
        - cluster_security_group_id
      subnet: $CUST_SNET2
    EOF
    
    cat <<EOF | kubectl apply -f -
    apiVersion: crd.k8s.amazonaws.com/v1alpha1
    kind: ENIConfig
    metadata:
     name: $AZ3
    spec:
      securityGroups:
        - cluster_security_group_id
      subnet: $CUST_SNET3
    EOF

    **注意:**请将 cluster_security_group_id 替换为要用于每个 ENIConfig 资源的现有安全组的 ID。ENIConfig 资源的名称与您创建新子网所在的可用区相同。

  5. 如果您使用自主管理型节点组,请启动自主管理型 Worker 节点,以便插件能够为这些节点分配 IP 地址。对于 Subnets(子网),请使用您在创建集群时选择的原始子网,而非在 ENIConfig 资源中使用的新子网。您也可以使用带有启动模板的托管节点组来启动节点。在这两种情况下,您都必须为您的实例类型确定正确的 max-pods 值。这是因为 Amazon EKS 中的自定义网络不会使用主网络接口来放置容器组。运行 max-pods-calculator.sh 脚本时,请务必添加 --cni-custom-networking-enabled 参数。
    然后,运行以下命令为您的自主管理型节点指定 max-pods 值:

    --use-max-pods false --kubelet-extra-args '--max-pods=20'

    注意:请将 20 替换为您计算出的 max-pods 值。
    对于托管节点组,请将以下脚本添加到
    用户数据
    中:

    #!/bin/bash
    /etc/eks/bootstrap.sh my-cluster-name --use-max-pods false --kubelet-extra-args '--max-pods=20'

    注意:请将 my-cluster-name 替换为您的集群名称,将 20 替换为您计算出的 max-pods 值。在启动模板中,请指定 Amazon EKS 优化型亚马逊机器映像 (AMI) ID,或基于 Amazon EKS 优化型 AMI 构建的自定义 AMI。Amazon Linux 2023 (AL2023) AMI 使用 nodeadm 进程。有关这如何更改用户数据配置的信息,请参阅“从 Amazon Linux 2 升级到 Amazon Linux 2023”。
    如果您使用不带启动模板或指定的 AMI ID 的托管节点组,则托管节点组会自动计算 max-pods 值。

  6. 新节点就绪后,请清空之前的节点,以正常关闭容器组。有关详细信息,请参阅 Kubernetes 网站上的安全地清空一个节点。如果这些节点位于现有的托管节点组中,请运行以下命令删除该节点组:

    aws eks delete-nodegroup --cluster-name CLUSTER_NAME --nodegroup-name my-nodegroup

    **注意:**请将 CLUSTER_NAME 替换为您的集群名称,将 my-nodegroup 替换为您的节点组名称。

  7. 要启动新部署以测试配置,请运行以下命令:

    kubectl create deployment nginx-test --image=nginx --replicas=10   
    kubectl get pods -o wide --selector=app=nginx-test

    **注意:**上述命令会添加 10 个新容器组,并将其调度到新 Worker 节点上的新 CIDR 范围内。

**重要事项:**集群可能需要长达 5 小时才能识别您与 VPC 关联的新 CIDR 块并将其加入允许列表。在此期间,Amazon EKS 控制面板将无法与您在新子网中启动的容器组通信。如果 api-server 通过 webhook、kubectl logs 命令或 kubectl exec 命令与容器组通信,则您可能会收到以下错误消息:

"failed calling webhook "linkerd-proxy-injector.linkerd.io": failed to call webhook: Post "https://linkerd-proxy-injector.linkerd.svc:443/?timeout=10s": Address is not allowed"

AWS 官方已更新 4 个月前