容器组(pod)的自定义网络 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

容器组(pod)的自定义网络

默认情况下,当 Amazon VPC CNI plugin for Kubernetes 为您的 Amazon EC2 节点创建辅助弹性网络接口时,它会在与该节点的主网络接口相同的子网中创建它们。它还将相同的安全组关联到与主网络接口关联的辅助网络接口。出于以下一个或多个原因,您可能希望该插件在不同子网中创建辅助网络接口,或者希望将不同的安全组与辅助网络接口关联,或者希望同时实现此两者:

  • 主网络接口所在子网中可用的 IPv4 地址数量有限。这可能会限制您可以在子网中创建的 Pods 的数量。通过对辅助网络接口使用不同的子网,您可以增加可用于 Pods 的 IPv4 地址的数量。

  • 出于安全原因,您的 Pods 可能需要使用与节点的主网络接口不同的子网或安全组。

  • 节点在公有子网中配置,并且您希望将 Pods 放在私有子网中。与公有子网关联的路由表包含指向互联网网关的路由。与私有子网关联的路由表不包含指向互联网网关的路由。

注意事项
  • 启用自定义联网后,不会将分配给主网络接口的 IP 地址分配给 Pods。仅会将辅助网络接口的 IP 地址分配给 Pods

  • 如果您的集群使用 IPv6 系列,您无法使用自定义联网。

  • 如果您计划仅为帮助缓解 IPv4 地址耗尽而使用自定义联网,您可以改为使用 IPv6 系列创建集群。有关更多信息,请参阅 教程:将 IPv6 地址分配给 Pods 和 services

  • 尽管部署到为辅助网络接口指定的子网的 Pods 可以使用与节点的主网络接口不同的子网和安全组,子网和安全组也必须与节点位于同一 VPC 中。

先决条件
  • 熟悉 Amazon VPC CNI plugin for Kubernetes 如何创建辅助网络接口并将 IP 地址分配给 Pods。有关更多信息,请参阅 GitHub 上的 ENI 分配

  • 在您的设备或 Amazon CloudShell 上安装和配置了 Amazon Command Line Interface(Amazon CLI)的版本 2.12.3 或更高版本,或版本 1.27.160 或更高版本。要查看当前版本,请使用 aws --version | cut -d / -f2 | cut -d ' ' -f1。软件包管理器(如 yumapt-get 或适用于 macOS 的 Homebrew)通常比 Amazon CLI 的最新版本落后几个版本。要安装最新版本,请参阅《Amazon Command Line Interface 用户指南》中的安装、更新和卸载 Amazon CLI,以及使用 aws configure 快速配置。Amazon CloudShell 中安装的 Amazon CLI 版本也可能比最新版本落后几个版本。如需更新,请参阅《Amazon CloudShell 用户指南》中的将 Amazon CLI 安装到主目录

  • 您的设备或 Amazon CloudShell 上安装了 kubectl 命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为 1.28,则可以将 kubectl1.271.281.29 版本与之配合使用。要安装或升级 kubectl,请参阅 安装或更新 kubectl

  • 我们建议您在 Bash shell 中完成本主题中的步骤。如果您没有使用 Bash shell,则某些脚本命令(例如行延续字符以及变量的设置和使用方式)需要调整 shell。此外,您的 Shell 的引用和转义规则可能有所不同。有关更多信息,请参阅《Amazon Command Line Interface 用户指南》中的在 Amazon CLI 中将引号和字符串结合使用

在本教程中,我们建议使用 example values,除非注意到要替换它们。您可以在完成生产集群的步骤时替换任何 example value。我们建议在同一终端完成所有步骤。这是因为变量是在整个步骤中设置和使用的,并且不会存在于不同的终端中。

本主题中的命令使用使用 Amazon CLI 示例中列出的惯例进行格式化。如果您从命令行运行命令,该命令行针对的资源位于与您正在使用的 Amazon CLI 配置文件中定义的默认 Amazon Web Services 区域不同的 Amazon Web Services 区域,则需要向命令中添加 --region region-code

当您想将自定义联网部署到生产集群时,请跳至 步骤 2:配置 VPC

步骤 1:创建测试 VPC 和集群

创建集群

以下步骤帮助您创建测试 VPC 和集群并为该集群配置自定义联网。我们不建议将测试集群用于生产工作负载,因为本主题没有涵盖在生产集群上可能使用的几种不相关的功能。有关更多信息,请参阅创建 Amazon EKS 集群

  1. 定义一些要在其余步骤中使用的变量。

    export cluster_name=my-custom-networking-cluster account_id=$(aws sts get-caller-identity --query Account --output text)
  2. 创建 VPC。

    1. 使用 Amazon EKS Amazon CloudFormation 模板创建 VPC。

      aws cloudformation create-stack --stack-name my-eks-custom-networking-vpc \ --template-url https://s3.cn-north-1.amazonaws.com.cn/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml \ --parameters ParameterKey=VpcBlock,ParameterValue=192.168.0.0/24 \ ParameterKey=PrivateSubnet01Block,ParameterValue=192.168.0.64/27 \ ParameterKey=PrivateSubnet02Block,ParameterValue=192.168.0.96/27 \ ParameterKey=PublicSubnet01Block,ParameterValue=192.168.0.0/27 \ ParameterKey=PublicSubnet02Block,ParameterValue=192.168.0.32/27

      Amazon CloudFormation 堆栈需要几分钟的时间来创建。要检查堆栈的部署状态,请运行以下命令。

      aws cloudformation describe-stacks --stack-name my-eks-custom-networking-vpc --query Stacks\[\].StackStatus --output text

      在命令的输出变成 CREATE_COMPLETE 之前,请勿继续执行下一步。

    2. 使用模板创建的私有子网 ID 的值定义变量。

      subnet_id_1=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \ --query "StackResources[?LogicalResourceId=='PrivateSubnet01'].PhysicalResourceId" --output text) subnet_id_2=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \ --query "StackResources[?LogicalResourceId=='PrivateSubnet02'].PhysicalResourceId" --output text)
    3. 使用上一步中检索到的子网的可用区定义变量。

      az_1=$(aws ec2 describe-subnets --subnet-ids $subnet_id_1 --query 'Subnets[*].AvailabilityZone' --output text) az_2=$(aws ec2 describe-subnets --subnet-ids $subnet_id_2 --query 'Subnets[*].AvailabilityZone' --output text)
  3. 创建集群 IAM 角色。

    1. 运行以下命令以创建 IAM 信任策略 JSON 文件。

      cat >eks-cluster-role-trust-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
    2. 创建 Amazon EKS 集群 IAM 角色。如有必要,使用您在上一步中将文件写入到的计算机上的路径为 eks-cluster-role-trust-policy.json 添加前缀。该命令将您在上一步中创建的信任策略与角色关联。要创建 IAM 角色,必须为正在创建角色的 IAM 主体分配 iam:CreateRole 操作(权限)。

      aws iam create-role --role-name myCustomNetworkingAmazonEKSClusterRole --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
    3. 将名为 AmazonEKSClusterPolicy 的 Amazon EKS 托管 IAM policy 附加到角色。要将 IAM policy 附加到某个 IAM 主体,必须为附加该策略的主体分配以下 IAM 操作(权限)之一:iam:AttachUserPolicyiam:AttachRolePolicy

      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name myCustomNetworkingAmazonEKSClusterRole
  4. 创建 Amazon EKS 集群并配置您的设备以与其进行通信。

    1. 创建集群。

      aws eks create-cluster --name my-custom-networking-cluster \ --role-arn arn:aws:iam::$account_id:role/myCustomNetworkingAmazonEKSClusterRole \ --resources-vpc-config subnetIds=$subnet_id_1","$subnet_id_2
      注意

      您可能会收到一个错误,指示请求中的可用区之一没有足够容量来创建 Amazon EKS 集群。如果发生这种情况,错误输出将包含可支持新集群的可用区。再次尝试使用至少两个位于您账户中支持的可用区的子网创建集群。有关更多信息,请参阅容量不足

    2. 创建集群需要几分钟时间。要检查集群的部署状态,请运行以下命令。

      aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status

      在命令的输出变成 "ACTIVE" 之前,请勿继续执行下一步。

    3. 配置 kubectl 以与集群通信。

      aws eks update-kubeconfig --name my-custom-networking-cluster

步骤 2:配置 VPC

本教程需要在 步骤 1:创建测试 VPC 和集群 中创建的 VPC。对于生产集群,通过将所有 example values 替换为您自己的值来相应调整 VPC 的步骤。

  1. 确认您当前安装的 Amazon VPC CNI plugin for Kubernetes 为最新版本。要确定 Amazon EKS 附加组件类型的最新版本并将您的版本更新至此版本,请参阅 更新附加组件。要确定自行管理的附加组件类型的最新版本并将您的版本更新至此版本,请参阅 使用 Amazon VPC CNI plugin for Kubernetes Amazon EKS 附加组件

  2. 检索您的集群 VPC 的 ID,并将其存储在变量中,以便在后续步骤中使用。对于生产集群,请将 my-custom-networking-cluster 替换为集群的名称。

    vpc_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query "cluster.resourcesVpcConfig.vpcId" --output text)
  3. 将另一个无类别域间路由(CIDR)块与集群的 VPC 关联。CIDR 块不能与任何现有关联的 CIDR 块重叠。

    1. 查看与您的 VPC 关联的当前 CIDR 块。

      aws ec2 describe-vpcs --vpc-ids $vpc_id \ --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table

      示例输出如下。

      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      +-----------------+--------------+
    2. 将额外 CIDR 块与 VPC 关联。有关更多信息,请参阅《Amazon VPC 用户指南》中的将额外的 IPv4 CIDR 块与 VPC 关联

      aws ec2 associate-vpc-cidr-block --vpc-id $vpc_id --cidr-block 192.168.1.0/24
    3. 确认新区块已关联。

      aws ec2 describe-vpcs --vpc-ids $vpc_id --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table

      示例输出如下。

      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      |  192.168.1.0/24 |  associated  |
      +-----------------+--------------+

    在您的新 CIDR 区块的 Stateassociated 之前,请勿继续执行下一步。

  4. 在现有子网所在的每个可用区中创建要使用的任意数量的子网。指定一个在之前的步骤中与 VPC 关联的 CIDR 块内的 CIDR 块。

    1. 创建新子网。子网必须在不同于现有子网所在的 VPC CIDR 块中创建子网,但与现有子网位于同一可用区中。在此示例中,在当前私有子网所在的每个可用区的新 CIDR 块中创建一个子网。创建的子网的 ID 存储在变量中以供后续步骤使用。Name 值与分配给上一步中使用 Amazon EKS VPC 模板创建的子网的值相匹配。名称不是必填项。您可以使用不同的名称。

      new_subnet_id_1=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_1 --cidr-block 192.168.1.0/27 \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet01},{Key=kubernetes.io/role/internal-elb,Value=1}]' \ --query Subnet.SubnetId --output text) new_subnet_id_2=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_2 --cidr-block 192.168.1.32/27 \ --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet02},{Key=kubernetes.io/role/internal-elb,Value=1}]' \ --query Subnet.SubnetId --output text)
      重要

      默认情况下,您的新子网与您的 VPC 的主路由表隐式关联。此路由表允许在 VPC 中部署的所有资源之间进行通信。但是,它不允许与 IP 地址位于与您的 VPC 关联的 CIDR 块之外的资源进行通信。您可以将自己的路由表关联到子网以改变此行为。有关更多信息,请参阅《Amazon VPC 用户指南》中的子网路由表

    2. 查看 VPC 中的当前子网。

      aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" \ --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \ --output table

      示例输出如下。

      ----------------------------------------------------------------------
      |                           DescribeSubnets                          |
      +------------------+--------------------+----------------------------+
      | AvailabilityZone |     CidrBlock      |         SubnetId           |
      +------------------+--------------------+----------------------------+
      |  cn-north-1d      |  192.168.0.0/27    |     subnet-example1        |
      |  cn-north-1a      |  192.168.0.32/27   |     subnet-example2        |
      |  cn-north-1a      |  192.168.0.64/27   |     subnet-example3        |
      |  cn-north-1d      |  192.168.0.96/27   |     subnet-example4        |
      |  cn-north-1a      |  192.168.1.0/27    |     subnet-example5        |
      |  cn-north-1d      |  192.168.1.32/27   |     subnet-example6        |
      +------------------+--------------------+----------------------------+

      您可以看到您创建的 192.168.1.0 CIDR 块中的子网与 192.168.0.0 CIDR 块中的子网在同一个可用区中。

步骤 3:配置 Kubernetes 资源

要配置 Kubernetes 资源
  1. AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG 环境变量设置为 aws-node DaemonSet 中的 true

    kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
  2. 检索集群安全组的 ID,并将其存储在变量中,以便在后续步骤中使用。当您创建集群时,Amazon EKS 会自动创建此安全组。

    cluster_security_group_id=$(aws eks describe-cluster --name $cluster_name --query cluster.resourcesVpcConfig.clusterSecurityGroupId --output text)
  3. 为您希望在其中部署 Pods 的每个子网创建 ENIConfig 自定义资源。

    1. 为每个网络接口配置创建一个唯一的文件。

      以下命令为您在上一步中创建的两个子网创建单独的 ENIConfig 文件。name 的值必须是唯一的。该名称与子网所在的可用区相同。将集群安全组分配给 ENIConfig

      cat >$az_1.yaml <<EOF apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: $az_1 spec: securityGroups: - $cluster_security_group_id subnet: $new_subnet_id_1 EOF
      cat >$az_2.yaml <<EOF apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: $az_2 spec: securityGroups: - $cluster_security_group_id subnet: $new_subnet_id_2 EOF

      对于生产集群,您可以对以前的命令进行以下更改:

      • $cluster_security_group_id 替换为您想要用于每个 ENIConfig 的现有安全组的 ID。

      • 我们建议将将您的 ENIConfigs 尽可能命名为与您将 ENIConfig 用于的可用区相同。您可能需要出于各种原因为您的 ENIConfigs 使用与可用区名称不同的名称。例如,如果您在同一可用区中有两个以上的子网,并且想将它们同时用于自定义联网,则需要将多个 ENIConfigs 用于同一个可用区。由于每个 ENIConfig 都需要一个唯一名称,您不能使用可用区名称命名多个 ENIConfigs

        如果您的 ENIConfig 名称与可用区名称不一样,将 $az_1$az_2 替换为上一个命令中您自己的名称,并且稍后在本教程中使用 ENIConfig 注释您的节点

      注意

      如果您未指定与生产集群一起使用的有效安全组并且您正在使用:

      • 版本 1.8.0 或更高版本的 Amazon VPC CNI plugin for Kubernetes,则使用与节点的主弹性网络接口关联的安全组。

      • 1.8.0 之前的 Amazon VPC CNI plugin for Kubernetes 版本,则 VPC 的默认安全组将分配给辅助网络接口。

      重要
      • AWS_VPC_K8S_CNI_EXTERNALSNAT=false 是适用于 Kubernetes 的 Amazon VPC CNI 插件配置中的默认设置。如果您使用的是默认设置,则发往不在与 VPC 关联的 CIDR 块之一内的 IP 地址的流量将使用节点主网络接口的安全组和子网。在用于创建辅助网络接口的 ENIConfigs 中定义的子网和安全组不用于此流量。有关该设置的更多信息,请参阅 适用于 Pods 的 SNAT

      • 如果您还将安全组用于 Pods,则使用 SecurityGroupPolicy 中指定的安全组而不是 ENIConfigs 中指定的安全组。有关更多信息,请参阅Pods 的安全组

    2. 使用以下命令将您创建的每个自定义资源文件应用于您的集群。

      kubectl apply -f $az_1.yaml kubectl apply -f $az_2.yaml
  4. 确认您的 ENIConfigs 已创建。

    kubectl get ENIConfigs

    示例输出如下。

    NAME AGE cn-north-1a 117s cn-north-1d 105s
  5. 如果您在生产集群上启用自定义联网并将您的 ENIConfigs 命名为您将它们用于的可用区之外的其他名称,然后跳到下一步以部署 Amazon EC2 节点。

    启用 Kubernetes 以将可用区的 ENIConfig 自动应用于在您的集群中创建的任何新 Amazon EC2 节点。

    1. 对于本教程中的测试集群,请跳至下一步

      对于生产集群,请检查带有 ENI_CONFIG_ANNOTATION_DEF 环境变量的键 k8s.amazonaws.com/eniConfig 的 annotation 是否存在于 aws-node DaemonSet 的容器规范中。

      kubectl describe daemonset aws-node -n kube-system | grep ENI_CONFIG_ANNOTATION_DEF

      如果返回输出,则注释存在。如果没有返回输出,则未设置此变量。对于生产集群,您可以使用此设置或以下步骤中的设置。如果使用此设置,它将覆盖以下步骤中的设置。在本教程中,将使用下一步中的设置。

    2. 更新您的 aws-node DaemonSet 以将可用区的 ENIConfig 自动应用于在您的集群中创建的任何新 Amazon EC2 节点。

      kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone

步骤 4:部署 Amazon EC2 节点

要部署 Amazon EC2 节点
  1. 创建节点 IAM 角色。

    1. 运行以下命令以创建 IAM 信任策略 JSON 文件。

      cat >node-role-trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF
    2. 运行以下命令设置角色名称的变量。您可以将 myCustomNetworkingAmazonEKSNodeRole 替换为您选择的任何名称。

      export node_role_name=myCustomNetworkingAmazonEKSNodeRole
    3. 创建 IAM 角色并将返回的 Amazon 资源名称(ARN)存储在变量中以供后续步骤使用。

      node_role_arn=$(aws iam create-role --role-name $node_role_name --assume-role-policy-document file://"node-role-trust-relationship.json" \ --query Role.Arn --output text)
    4. 将三个所需的 IAM 托管策略附加到 IAM 角色。

      aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \ --role-name $node_role_name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \ --role-name $node_role_name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \ --role-name $node_role_name
      重要

      为简单起见,在本教程中,AmazonEKS_CNI_Policy 策略附加到节点 IAM 角色。在生产集群中,我们建议将该策略附加到仅用于 Amazon VPC CNI plugin for Kubernetes 的单独 IAM 角色。有关更多信息,请参阅配置 Amazon VPC CNI plugin for Kubernetes 将 IAM 角色用于服务账户

  2. 创建以下一种类型的节点组。要确定您想要部署的实例类型,请参阅 选择 Amazon EC2 实例类型。在本教程中,请完成 Managed(托管)、Without a launch template or with a launch template without an AMI ID specified(没有启动模板或带有未指定 AMI ID 的启动模板)选项。如果要将节点组用于生产工作负载,那么我们建议您在部署节点组之前自定熟悉所有的托管自行管理节点组选项。

    • 托管:使用以下选项之一部署您的节点组:

      • 没有启动模板或者带有未指定 AMI ID 的启动模板 – 运行以下命令。在本教程中,请使用 example values。对于生产节点组,将所有的 example values 替换为您自己的值。节点组名称的长度不能超过 63 个字符。它必须以字母或数字开头,但也可以包括其余字符的连字符和下划线。

        aws eks create-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup \ --subnets $subnet_id_1 $subnet_id_2 --instance-types t3.medium --node-role $node_role_arn
      • 使用具有指定 AMI ID 的启动模板

        1. 确定 Amazon EKS 为您的节点推荐的最大 Pods 数量。按照 Amazon EKS 建议每种 Amazon EC2 实例类型的最大 Pods 数量 中的说明进行操作,将 --cni-custom-networking-enabled 添加到该主题的步骤 3。请记下输出的内容,以便在下一个步骤中使用。

        2. 在启动模板中,指定 Amazon EKS 优化的 AMI ID,或者指定基于 Amazon EKS 优化 AMI 构建的自定义 AMI,然后使用启动模板部署节点组并在启动模板中提供以下用户数据。此用户数据会将实际参数传递到 bootstrap.sh 文件中。有关引导文件的更多信息,请参阅 GitHub 上的 bootstrap.sh。您可以将 20 替换为上一步的值(建议)或您自己的值。

          /etc/eks/bootstrap.sh my-cluster --use-max-pods false --kubelet-extra-args '--max-pods=20'

          如果您创建的自定义 AMI 不是基于 Amazon EKS 优化 AMI 构建的,则需要自行自定义创建配置。

    • 自行管理

      1. 确定 Amazon EKS 为您的节点推荐的最大 Pods 数量。按照 Amazon EKS 建议每种 Amazon EC2 实例类型的最大 Pods 数量 中的说明进行操作,将 --cni-custom-networking-enabled 添加到该主题的步骤 3。请记下输出的内容,以便在下一个步骤中使用。

      2. 按照 启动自行管理的 Amazon Linux 节点 中的说明部署节点组。为 BootstrapArguments 参数指定以下文本。您可以将 20 替换为上一步的值(建议)或您自己的值。

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

    节点组创建需要几分钟时间。您可以使用以下命令检查托管节点组创建的状态。

    aws eks describe-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup --query nodegroup.status --output text

    在返回的输出为 ACTIVE 之前,请勿继续执行下一步。

  3. 在本教程中,您可以跳过此步骤。

    对于生产集群,如果您没有将您的 ENIConfigs 命名为您将其用于的可用区相同,则必须使用应与节点一起使用的 ENIConfig 名称对节点进行注释。如果您在每个可用区中只有一个子网并且将 ENIConfigs 命名为与可用区相同的名称,则此步骤不需要。这是因为当您在上一步中启用了它执行此操作时,Amazon VPC CNI plugin for Kubernetes 会自动为您将正确的 ENIConfig 与节点关联。

    1. 获取集群中的节点列表。

      kubectl get nodes

      示例输出如下。

      NAME STATUS ROLES AGE VERSION ip-192-168-0-126.cn-north-1.compute.internal Ready <none> 8m49s v1.22.9-eks-810597c ip-192-168-0-92.cn-north-1.compute.internal Ready <none> 8m34s v1.22.9-eks-810597c
    2. 确定每个节点所在的可用区。运行上一步中返回的每个节点的以下命令。

      aws ec2 describe-instances --filters Name=network-interface.private-dns-name,Values=ip-192-168-0-126.cn-north-1.compute.internal \ --query 'Reservations[].Instances[].{AvailabilityZone: Placement.AvailabilityZone, SubnetId: SubnetId}'

      示例输出如下。

      [ { "AvailabilityZone": "cn-north-1d", "SubnetId": "subnet-Example5" } ]
    3. 使用您为子网 ID 和可用区创建的 ENIConfig 注释每一个节点。您只能使用一个 ENIConfig 注释节点,尽管使用同一个 ENIConfig 可以注释多个节点。将 example values 替换为您自己的值。

      kubectl annotate node ip-192-168-0-126.cn-north-1.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName1 kubectl annotate node ip-192-168-0-92.cn-north-1.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName2
  4. 如果您在切换到使用自定义联网功能之前在具有运行的 Pods 的生产集群中有节点,请完成以下任务:

    1. 确保您有可用的节点正在使用自定义联网功能。

    2. 封锁并耗尽节点以正常关闭 Pods。有关更多信息,请参阅 Kubernetes 文档中的安全耗尽节点

    3. 终止节点。如果节点位于现有的托管节点组中,则可以删除该节点组。将以下命令复制到您的设备。根据需要对该命令进行以下修改,然后运行修改后的命令:

      • my-cluster 替换为您的集群的名称。

      • my-nodegroup 替换为您的节点组的名称。

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

    只有注册有 k8s.amazonaws.com/eniConfig 标注的新节点将使用新的自定义联网功能。

  5. 确认从 CIDR 块中为 Pods 分配一个 IP 地址,该地址与您在上一步中创建的其中一个子网相关联。

    kubectl get pods -A -o wide

    示例输出如下。

    NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system aws-node-2rkn4 1/1 Running 0 7m19s 192.168.0.92 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system aws-node-k96wp 1/1 Running 0 7m15s 192.168.0.126 ip-192-168-0-126.us-west-2.compute.internal <none> <none> kube-system coredns-657694c6f4-smcgr 1/1 Running 0 56m 192.168.1.23 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system coredns-657694c6f4-stwv9 1/1 Running 0 56m 192.168.1.28 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system kube-proxy-jgshq 1/1 Running 0 7m19s 192.168.0.92 ip-192-168-0-92.us-west-2.compute.internal <none> <none> kube-system kube-proxy-wx9vk 1/1 Running 0 7m15s 192.168.0.126 ip-192-168-0-126.us-west-2.compute.internal <none> <none>

    您可以看到 coredns Pods 从您添加到 VPC 中的 192.168.1.0 CIDR 块中分配到了 IP 地址。如果没有自定义联网,他们就会从 192.168.0.0 CIDR 块分配地址,因为它是最初与 VPC 关联的唯一 CIDR 块。

    如果 Pod's spec 包含 hostNetwork=true,则会被分配节点的主 IP 地址。不会从您添加的子网中向其分配地址。默认情况下,该值设置为 false。对于在集群上运行的 kube-proxy 和 Amazon VPC CNI plugin for Kubernetes(aws-node)Pods,此值设置为 true。这就是 kube-proxy 和插件的 aws-node Pods 在上一个输出中没有被分配 192.168.1.x 地址的原因。有关的 Pod's hostNetwork 设置的更多信息,请参阅 Kubernetes API 参考中的 PodSpec v1 核心

步骤 5:删除教程资源

完成本教程后,我们建议您删除创建的资源。然后,您可以调整步骤以为生产集群启用自定义联网。

要删除教程资源
  1. 如果您创建的节点组只是为了测试,那么请将其删除。

    aws eks delete-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup

    即使在 Amazon CLI 输出显示集群已删除,删除过程实际上可能尚未完成。删除过程需要几分钟时间。通过运行以下命令确认已完成。

    aws eks describe-nodegroup --cluster-name $cluster_name --nodegroup-name my-nodegroup --query nodegroup.status --output text

    在返回的输出类似于以下输出之前,请勿继续执行。

    An error occurred (ResourceNotFoundException) when calling the DescribeNodegroup operation: No node group found for name: my-nodegroup.
  2. 如果您创建的节点组只是为了测试,则请删除节点 IAM 角色。

    1. 将策略与角色分离。

      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    2. 删除角色。

      aws iam delete-role --role-name myCustomNetworkingAmazonEKSNodeRole
  3. 请删除集群。

    aws eks delete-cluster --name $cluster_name

    通过以下命令确认集群已删除。

    aws eks describe-cluster --name $cluster_name --query cluster.status --output text

    返回类似以下内容的输出时,将成功删除集群。

    An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-cluster.
  4. 删除集群 IAM 角色。

    1. 将策略与角色分离。

      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSClusterRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
    2. 删除角色。

      aws iam delete-role --role-name myCustomNetworkingAmazonEKSClusterRole
  5. 删除您在上一步中创建的子网。

    aws ec2 delete-subnet --subnet-id $new_subnet_id_1 aws ec2 delete-subnet --subnet-id $new_subnet_id_2
  6. 删除您创建的 VPC。

    aws cloudformation delete-stack --stack-name my-eks-custom-networking-vpc