提高 Amazon EC2 节点的可用 IP 地址数量 - Amazon EKS

提高 Amazon EC2 节点的可用 IP 地址数量

预设情况下,可分配给 pods 的 IP 地址数取决于分配给弹性网络接口的 IP 地址数量以及附加到 Amazon EC2 节点的网络接口数。您可以配置 1.9.0 版或更高版本的 Amazon VPC CNI 附加组件以分配 /28 IPv4 地址前缀。使用 1.10.1 或更高版本的附加组件时,您仍然可以分配 /28 IPv4 地址前缀,但如果您的集群是 1.21 版或更高版本,并且您已将其配置为 IPv6,则可以改为分配 /80 IPv6 地址前缀。

配置为前缀分配时,CNI 附加组件可以为网络接口分配的 IP 地址远远超过分配单个 IP 地址时的 IP 地址。然后,节点可以向 pods 分配的可用 IP 地址数量将大幅提升。有关使附加组件能够执行此操作的 Amazon EC2 功能的更多信息,请参阅适用于 Linux 实例的 Amazon EC2 用户指南中的为 Amazon EC2 网络接口分配前缀

如果不启用此功能,附加组件必须进行更多 Amazon EC2 应用程序编程接口(API)调用,以配置 pod 连接所需的网络接口和 IP 地址。这些 API 调用的频率与每个 VPC 中的大量网络接口可能会共同导致 pod 和实例启动时间延长,因为集群要扩展到更大的规模。这会导致扩展延迟以满足大型和尖峰工作负载的需求,并增加成本和管理开销,因为您需要配置额外的集群和 VPC 来满足扩展需求。请参阅 Kubernetes 可扩展性阈值了解更多信息。

注意事项

  • AWS基于 Nitro 的节点使用此功能。不基于 Nitro 的实例会继续分配单个辅助 IP 地址,但分配给 pods 的 IP 地址数量比 Nitro-based 实例少得多。

  • 将附加组件配置为向网络接口分配前缀后,您将无法在不删除集群所有节点组中的所有节点的情况下将 Amazon VPC CNI 附加组件版本降级到 1.9.0 版(或 1.10.1 版)以下。

  • 您的 VPC 必须具有足够的可用连续 /28 IPv4 地址数据块来支持此功能。

  • 每种实例类型支持最大数量的 pods。如果您的托管节点组由多种实例类型组成,则集群中某个实例的最大 pods 数量的最小值将应用于集群中的所有节点。

  • 如果您有现有的托管节点组,则节点组的下一次 AMI 或启动模板更新会导致新的 Worker 节点出现时带有启用了新的 IP 地址前缀分配 max-pod 值。

先决条件

  • 现有集群。要部署一个角色,请参阅 创建 Amazon EKS 集群

  • 1.9.0 版或更高版本(适用于 1.20 版或更早版本的集群,或 1.21 版或更高版本的集群,配置为使用 IPv4)或者 1.10.1 版或更高版本(适用于 1.21 版或更高版本的集群,配置为使用 IPv6)的 Amazon VPC CNI plugin for Kubernetes 附加组件已部署到您的集群。

提高 Amazon EC2 节点的可用 IP 地址数量的步骤

  1. 确认您当前安装的 Amazon VPC CNI plugin for Kubernetes 版本为 1.9.01.10.1 或更高版本。

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

    输出示例如下。

    amazon-k8s-cni:v1.10.1-eksbuild.1

    如果您的版本早于 1.9.0,则必须予以更新。想要了解更多信息,请参阅 管理 Amazon VPC CNI plugin for Kubernetes 的更新部分。

  2. 启用参数,以便为 Amazon VPC CNI DaemonSet 的网络接口分配前缀。当您部署 1.21 或更高版本的集群时,1.10.1 或更高版本的 Amazon VPC CNI plugin for Kubernetes 附加组件随它一起部署。如果您使用 IPv6 系列创建集群,这个设置将被默认设置为 true。如果您使用 IPv4 系列创建集群,这个设置将被默认设置为 false

    kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
    重要

    即使您的子网有免费的 IP 地址,如果子网没有任何连续 /28 数据块可用,您也将在 Amazon VPC CNI plugin for Kubernetes 日志中看到以下错误:

    "failed to allocate a private IP/Prefix address: InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request"

    发生这种情况的原因可能是分散在子网中的现有辅助 IP 地址的碎片。要解决此错误,请创建一个新子网并在那里启动 pods,或者使用 Amazon EC2 子网 CIDR 预留在子网中预留空间以便与前缀分配一起使用。有关更多信息,请参阅《Amazon VPC 用户指南》中的子网 CIDR 预留

  3. 如果您计划在没有启动模板的情况下部署托管节点组,或者采用尚未在其中指定 AMI ID 的启动模板,并且您使用的是在先决条件中列出的 Amazon VPC CNI plugin for Kubernetes 版本或更高版本,则跳至下一步。托管节点组会自动为您计算最大 pods 数量。

    如果您正在部署自我管理的节点组或带有启动模板的托管节点组,且其启动模板已指定了 AMI ID,则必须确定 Amazon EKS 为节点推荐的最大 pods 数量。按照 Amazon EKS 建议每种 Amazon EC2 实例类型的最大 pods 数量 中的说明进行操作,将 --cni-prefix-delegation-enabled 添加到步骤 3。请记下输出的内容,以便在下一个步骤中使用。

    重要

    托管节点组强制执行 maxPods 的值的最大数量。对于 vCPUs 少于 30 个的实例,最大数量为 110,对于所有其他实例,最大数量为 250。无论是否启用前缀委派,均应用此最大数量。

  4. 如果您使用配置为使用 IPv61.21 或更高版本的集群,请跳至下一步。

    在以下选项中指定参数。要确定哪个选项适合您以及为其提供哪些值,请参阅 GitHub 上的 WARM_PREFIX_TARGETWARM_IP_TARGETMINIMUM_IP_TARGET

    您可以将 example values 替换为大于零的值。

    • WARM_PREFIX_TARGET

      kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
    • WARM_IP_TARGETMINIMUM_IP_TARGET:如果设置了两种值之一,则其会覆盖所设置的 WARM_PREFIX_TARGET 的值。

      kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=5
      kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=2
  5. 使用至少一种 Amazon EC2 Nitro Amazon Linux 2 实例类型创建以下类型之一的节点组。有关 Nitro 实例类型的列表,请参阅适用于 Linux 实例的 Amazon EC2 用户指南中的基于 Nitro 系统构建的实例。Windows 中不支持此功能。对于包含 110 的选项,将其替换为第 3 步中的值(建议)或您自己的值。

    • 自行管理的节点组 – 按照 启动自行管理的 Amazon Linux 节点 中的说明部署节点组。为 BootstrapArguments 参数指定以下文本。

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

      如果使用 eksctl 创建节点组,可以使用下面的命令。

      eksctl create nodegroup --cluster my-cluster --managed=false --max-pods-per-node 110
    • 托管:使用以下选项之一部署您的节点组:

      • 没有启动模板或者没有指定 AMI ID 的启动模板:完成 创建托管节点组 中的过程。托管节点组会自动为您计算 Amazon EKS 建议的 max-pods 值。

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

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

        如果使用 eksctl 创建节点组,可以使用下面的命令。

        eksctl create nodegroup --cluster my-cluster --max-pods-per-node 110

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

      注意

      如果您还想将 IP 地址分配给不同于实例子网的 pods,则需要在此步骤中启用该功能。有关更多信息,请参阅教程:自定义联网

  6. 节点部署完成后,请查看集群中的节点。

    kubectl get nodes

    输出示例如下。

    NAME STATUS ROLES AGE VERSION ip-192-168-22-103.region-code.compute.internal Ready <none> 19m v1.20.4-eks-6b7464 ip-192-168-97-94.region-code.compute.internal Ready <none> 19m v1.20.4-eks-6b7464
  7. 描述其中一个节点以确定节点的 max-pods

    kubectl describe node node-name ip-192-168-22-103.region-code.compute.internal

    输出示例如下。

    ... Allocatable: attachable-volumes-aws-ebs: 25 cpu: 1930m ephemeral-storage: 76224326324 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 7244720Ki pods: 110 ...

    在先前的输出中,110 是 Kubernetes 将部署到节点的最大 pods 数量。