CNI 自定义网络 - Amazon EKS

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

CNI 自定义网络

默认情况下,在为 Pod 分配新的网络接口时,ipamD 将使用节点的主网络接口的安全组和子网。您可能希望 Pod 在与您的控制层面安全组相同的 VPC 中使用不同的安全组或子网。例如:

  • 子网中可用 IP 地址的数量是有限的。这可能会限制可在集群中创建的 Pod 的数量。对 Pod 使用不同的子网将允许您增加可用 IP 地址的数量。

  • 出于安全原因,您必须使用与节点的主网络接口不同的安全组或子网。

  • 这些节点在公有子网中配置,您希望使用 NAT 网关将 Pod 放在私有子网中。有关更多信息,请参阅 外部源网络地址转换 (SNAT).

注意
  • 您可以为自行管理的节点组或通过使用使用自定义 AMI 的启动模板创建的托管节点组配置自定义网络。本主题中的过程需要适用于 Kubernetes 的 Amazon VPC CNI 插件版本 1.4.0 或更高版本。要检查您的 CNI 版本,并在必要时进行升级,请参阅Amazon VPC适用于 Kubernetes 的 CNI 插件升级.

  • 启用自定义网络将从使用它的每个节点中有效地删除可用网络接口(及其针对 Pod 的所有可用 IP 地址)。启用自定义网络时,节点的主网络接口不用于 Pod 放置。

  • 本主题中的过程指示 CNI 插件将与辅助网络接口关联的安全组与实例中的主网络接口关联的不同。使用辅助网络接口的所有 Pod 仍将共享辅助网络接口的使用情况,并将使用相同的安全组。如果您要将不同的安全组分配给各个 Pod,则可以使用 Pod 的安全组。Pod 的安全组创建额外的网络接口,每个接口都可以分配一个唯一的安全组。适用于 Pod 的安全组可在有或没有自定义网络的情况下使用。

配置 CNI 自定义网络

  1. 将辅助 CIDR 块与您集群的 VPC 关联。有关更多信息,请参阅 https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#add-ipv4-cidr 中的将辅助 IPv4 CIDR 块与您的 VPC 关联Amazon VPC 用户指南。

  2. 使用您的辅助 CIDR 块在您的 VPC 中为每个 可用区 创建一个子网。您的自定义子网必须来自与启动节点的子网不同的 VPC CIDR 块。有关更多信息,请参阅 中的在 VPC 中创建子网Amazon VPC 用户指南。

  3. AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG 环境变量设置为 true DaemonSet 中的 aws-node

    kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
  4. 查看当前安装的 CNI 版本。

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

    输出:

    amazon-k8s-cni:1.7.5
  5. 如果您安装了版本 1.3 或更高版本的 CNI,则可以跳到步骤 6。为集群定义新的 ENIConfig 自定义资源。

    1. 创建一个名为 ENIConfig.yaml 的文件,并将以下内容粘贴到该文件中:

      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
    2. 使用以下命令将该文件应用于集群:

      kubectl apply -f ENIConfig.yaml
  6. 为您希望在其中安排 Pod 的每个子网创建 ENIConfig 自定义资源。

    1. 为每个网络接口配置创建一个唯一的文件。每个文件必须包含具有 name 的唯一值的以下内容。我们强烈建议为 name 使用与子网的 可用区 匹配的值,因为这可以简化多可用区 Auto Scaling 组的部署(请参阅下面的步骤 6c)。

      在此示例中,将创建一个名为 us-west-2a.yaml 的文件。将 <example values>、namesubnetsecurityGroups 替换为您自己的值。在此示例中,我们遵循最佳实践,并将 name 的值设置为子网所在的可用区 如果您没有要为 Pod 附加的特定安全组,您可以暂时将该值留空。稍后,您将在 ENIConfig 中指定节点安全组。

      apiVersion: crd.k8s.amazonaws.com/v1alpha1 kind: ENIConfig metadata: name: <us-west-2a> spec: securityGroups: - <sg-0dff111a1d11c1c11> subnet: <subnet-011b111c1f11fdf11>
      注意

      子网和安全组的每个组合均需要有自己的自定义资源。如果您在同一个 可用区 中有多个子网,请使用以下命令使用匹配的配置名称注释每个子网中的节点。

      kubectl annotate node <node-name>.<region>.compute.internal k8s.amazonaws.com/eniConfig=<subnet1ConfigName>
    2. 使用以下命令将您创建的每个自定义资源文件应用于您的集群:

      kubectl apply -f <us-west-2a>.yaml
    3. (可选,但建议用于多 可用区 节点组)默认情况下,Kubernetes 将节点的 可用区 应用于 failure-domain.beta.kubernetes.io/zone 标签。如果您以 VPC 中的每个 可用区 命名您的 ENIConfig 自定义资源,如步骤 6a 中所推荐,则可以使用以下命令,让 Kubernetes 自动为节点的 可用区 应用对应的 ENIConfig。

      kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone
      注意

      确保对于 k8s.amazonaws.com/eniConfig 环境变量具有键 ENI_CONFIG_ANNOTATION_DEF 的注释不存在于 aws-node 守护进程集的容器规范中。如果存在,它会覆盖 ENI_CONFIG_LABEL_DEF 值,而应被删除。您可以检查是否使用 kubectl describe daemonset aws-node -n kube-system | grep ENI_CONFIG_ANNOTATION_DEF 命令设置了此变量。如果没有返回输出,则未设置此变量。

  7. 创建新的自行管理节点组。对于托管节点组,请使用具有启动模板的自定义 AMI。

    1. 使用以下公式确定每个节点上可以计划的最大 Pod 数。

      maxPods = (number of interfaces - 1) * (max IPv4 addresses per interface - 1) + 2

      例如,m5.large 实例类型支持三个网络接口,每个接口有 10 个 IPv4 地址。将值插入到公式中时,实例最多可支持 20 个 Pod,如以下计算所示。

      maxPods = (3 - 1) * (10 - 1) + 2 = 20

      有关每个实例类型的最大网络接口数的更多信息,请参阅 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI 中的每个实例类型的每个网络接口的 IP 地址Amazon EC2 用户指南(适用于 Linux 实例)。

    2. 按照自行管理节点启动自管理 Amazon Linux 节点的步骤创建新的自行管理节点组。打开 AWS CloudFormation 模板后,按照说明中所述输入值。指定您在部署的 ENIConfig 资源中指定的子网。对于 BootstrapArguments 字段,输入以下值。

      --use-max-pods false --kubelet-extra-args '--max-pods=<20>'
  8. 创建节点组后,记录为子网创建的安全组并将安全组应用于关联的 ENIConfig。使用以下命令编辑每个 ENIConfig,将 <eniconfig-name> 替换为您的值:

    kubectl edit eniconfig.crd.k8s.amazonaws.com/<eniconfig-name>

    如果您遵循了步骤 6a 和 6c 中的最佳实践,则 eniconfig-name 对应于 可用区 名称。

    spec 节应如下所示:

    spec: securityGroups: - <sg-0dff222a2d22c2c22> subnet: <subnet-022b222c2f22fdf22>
  9. 如果在您集群中有任何节点上放置 Pod,则完成此过程之前,您应终止这些节点。只有向 k8s.amazonaws.com/eniConfig 标签注册的新节点使用新的自定义联网功能。