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 关联。有关更多信息,请参阅 中的将辅助 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> (包括 <>(对于 name、 和 subnet),securityGroups具有您自己的值。在此示例中,我们遵循最佳实践,并将 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>
      • 如果您没有为 VPC 指定有效的安全组,则 VPC 的默认安全组将分配给辅助 ENI 的 。

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

      kubectl apply -f <us-west-2a>.yaml
    3. (可选,但建议用于多可用区节点组)默认情况下,Kubernetes 将节点可用区的 应用于 failure-domain.beta.kubernetes.io/zone 标签。如果按照步骤 6a 中的建议以 VPC ENIConfig 中的每个 命名您的可用区自定义资源,则可以使用以下命令让 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 实例类型对每个接口支持三个网络接口和十个 IPv4 地址。将值插入到公式中后,实例最多可以支持 20 个 Pod,如以下计算所示。

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

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

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

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

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

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

    spec 节应如下所示:

    spec: securityGroups: - <sg-0dff222a2d22c2c22> subnet: <subnet-022b222c2f22fdf22>
  9. 如果在切换到自定义 CNI 联网功能之前,集群中有任何节点具有正在运行的 Pod,则应封锁和耗尽节点以正常关闭 Pod,然后终止节点。只有向 k8s.amazonaws.com/eniConfig 标签注册的新节点才使用自定义联网功能。