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

4 分钟阅读
0

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

简短描述

在完成解决方法部分的步骤之前,请确认您已有:

注意:

**重要信息:**在某些情况下,Amazon EKS 无法与您在创建集群后添加到 VPC 的 CIDR 块的子网中启动的节点通信。当您向现有集群添加 CIDR 块时,更新的范围显示最长可能需要等待 5 小时。

解决方法

**注意:**如果在运行 AWS 命令行界面(AWS CLI)命令时收到错误,请参阅排查 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

    要将另一个带有 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 ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[*].ZoneName'

    **注意:**将 us-east-1 替换为您的区域。

  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)
  4. (可选)设置键值对,为子网添加名称标签。例如:

    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

将新子网关联到路由表

完成以下步骤:

  1. 要列出 VPC 下的整个路由表,运行以下命令:

    aws ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID |jq -r '.RouteTables[].RouteTableId'
  2. 要将路由表导出到变量,运行以下命令:

    export RTASSOC_ID=rtb-abcabcabc

    **注意:**将 rtb-abcabcabc 替换为上一步中的值。

  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

    有关更多信息,请参阅以下文章中的 Routing 部分:Example: VPC with servers in private subnets and NAT

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

完成以下步骤:

  1. 将最新版本的 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
  2. 要添加 ENIConfig 标签来标识 Worker 节点,运行以下命令:

    kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone
  3. 要为所有子网和可用区创建 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 节点的可用区匹配。

  4. 启动 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'>
  5. 记下子网的安全组,并将安全组应用于关联的 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 替换为您的安全组。

  6. 终止旧 Worker 节点

  7. 启动新部署来测试配置:

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

    **注意:**在前面的测试部署中,添加了 10 个新的容器组(pod),并且为新的 Worker 节点安排了新的 CIDR 范围。

AWS 官方
AWS 官方已更新 1 个月前