

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

# 适用于 Linux 的前缀模式
<a name="prefix-mode-linux"></a>

**提示**  
 通过 Amazon EKS 研讨会@@ [探索](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)最佳实践。

Amazon VPC CNI 为 [Amazon EC2 网络接口分配网络](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-prefix-eni.html)前缀，以增加节点可用的 IP 地址数量并增加每个节点的容器密度。您可以将版本 1.9.0 或更高版本的 Amazon VPC CNI 插件配置为分配 IPv4 和 IPv6 CIDR，而不是为网络接口分配单独的辅助 IP 地址。

IPv6 群集上默认启用前缀模式，并且是唯一支持的选项。VPC CNI 为弹性网卡上的插槽分配一个 /80 IPv6 前缀。有关更多信息，请参阅[本指南的 IPv6 部分](ipv6.md)。

在前缀分配模式下，每种实例类型的最大弹性网络接口数量保持不变，但您现在可以将 Amazon VPC CNI 配置为分配 /28（16 个 IP 地址）IPv4 地址前缀，而不是为网络接口上的插槽分配单独的 IPv4 地址。当设置`ENABLE_PREFIX_DELEGATION`为 true 时，VPC CNI 会从分配给 ENI 的前缀中为 Pod 分配一个 IP 地址。请按照 [EKS 用户指南](https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses.html)中提及的说明启用前缀 IP 模式。

![两个工作子网的插图](http://docs.aws.amazon.com/zh_cn/eks/latest/best-practices/images/networking/pm_image.png)


您可以分配给网络接口的 IP 地址的最大数量取决于实例类型。您分配给网络接口的每个前缀都算作一个 IP 地址。例如，`c5.large` 实例具有每个网络接口 `10` 个 IPv4 地址的限制。此实例的每个网络接口都有一个主 IPv4 地址。如果网络接口没有辅助 IPv4 地址，则您最多可以为网络接口分配 9 个前缀。您每为网络接口多分配一个 IPv4 地址，则您就可以为网络接口少分配一个前缀。查看 AWS EC2 文档，了解[每种实例类型的每个网络接口的 IP 地址](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)以及[为网络接口分配前缀](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-prefix-eni.html)。

在工作节点初始化期间，VPC CNI 会为主 ENI 分配一个或多个前缀。CNI 预先分配了一个前缀，通过维护温池，可以更快地启动 pod。可以通过设置环境变量来控制要在温池中保存的前缀数量。
+  `WARM_PREFIX_TARGET`，即要分配的超出当前需求的前缀数量。
+  `WARM_IP_TARGET`，要分配的超出当前需求的 IP 地址数量。
+  `MINIMUM_IP_TARGET`，任何时候可用的 IP 地址的最小数量。
+  `WARM_IP_TARGET``MINIMUM_IP_TARGET`如果设置则会覆盖`WARM_PREFIX_TARGET`。

随着计划的 Pod 越多，将为现有 ENI 请求额外的前缀。首先，VPC CNI 尝试为现有 ENI 分配新的前缀。如果 ENI 已满负荷，VPC CNI 会尝试向该节点分配新的弹性网卡。在达到最大 ENI 上限（由实例类型定义）之前，将附加新 ENI。附加新的 ENI 时，ipamd 将分配维护`WARM_PREFIX_TARGET``WARM_IP_TARGET`、和`MINIMUM_IP_TARGET`设置所需的一个或多个前缀。

![为 pod 分配 IP 的过程流程图](http://docs.aws.amazon.com/zh_cn/eks/latest/best-practices/images/networking/pm_image-2.jpeg)


## 建议
<a name="_recommendations"></a>

### 在以下情况下使用前缀模式
<a name="_use_prefix_mode_when"></a>

如果您在工作节点上遇到 Pod 密度问题，请使用前缀模式。为避免 VPC CNI 错误，我们建议在迁移到前缀模式之前，检查子网中是否有 /28 前缀的连续地址块。有关[子网预留的详细信息，请参阅 “使用子网预留避免子网碎片 (IPv4)](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html)” 部分。

为了向后兼容，[最大容量限制](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/misc/eni-max-pods.txt)设置为支持辅助 IP 模式。要增加 pod 密度，请将 Kubelet 的`max-pods``--use-max-pods=false`值指定为节点的用户数据。有关更多信息，请参阅 [Amazon EKS 用户指南中的如何确定 MaxPods](https://docs.aws.amazon.com/eks/latest/userguide/choosing-instance-type.html#max-pods-precedence)。有关示例[用户数据，请参阅 EKS 用户指南](https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses.html)。

```
./max-pods-calculator.sh --instance-type m5.large --cni-version ``1.9``.0 --cni-prefix-delegation-enabled
```

前缀分配模式对于 [CNI 自定义网络的用户尤其重要，在这种网络](https://docs.aws.amazon.com/eks/latest/userguide/cni-custom-network.html)中，主网卡不用于 pod。通过前缀分配，您仍然可以在几乎每种 Nitro 实例类型上附加更多 IP，即使没有将主 ENI 用于 pod 也是如此。

### 在以下情况下避免使用前缀模式
<a name="_avoid_prefix_mode_when"></a>

如果您的子网非常分散，且可用的 IP 地址不足，无法创建 /28 前缀，请避免使用前缀模式。如果生成前缀的子网碎片化（一个经常使用的子网，次要 IP 地址分散），则前缀连接可能会失败。可以通过创建新子网并保留前缀来避免此问题。

在前缀模式下，分配给工作节点的安全组由 Pod 共享。如果您有通过在共享计算资源上运行具有不同网络安全要求的应用程序来实现合规性的安全要求，可以考虑为 [Pod 使用安全组](sgpp.md)。

### 在同一个节点组中使用相似的实例类型
<a name="_use_similar_instance_types_in_the_same_node_group"></a>

您的节点组可能包含多种类型的实例。如果实例的最大 Pod 数量较低，则该值将应用于节点组中的所有节点。考虑在节点组中使用相似的实例类型，以最大限度地提高节点使用率。我们建议配置 [node.kubernetes。 io/instance-如果您使用 Karp](https://karpenter.sh/docs/concepts/nodepools/) enter 进行自动节点扩展，请在配置器 API 的要求部分中键入。

**警告**  
特定节点组中所有节点的最大 Pod 数量由该节点组中任何单个实例类型的最*低*最大容器数量定义。

### 配置`WARM_PREFIX_TARGET`以保存 IPv4 地址
<a name="_configure_warm_prefix_target_to_conserve_ipv4_addresses"></a>

[安装清单的](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/config/v1.9/aws-k8s-cni.yaml#L158)默认值`WARM_PREFIX_TARGET`为 1。在大多数情况下，建议的值 1 可以很好地兼顾快速的 pod 启动时间，同时最大限度地减少分配给实例的未使用的 IP 地址。`WARM_PREFIX_TARGET`

如果您需要进一步节省每个节点的 IPv4 地址，请使用`WARM_IP_TARGET`和`MINIMUM_IP_TARGET`设置（配置`WARM_PREFIX_TARGET`后会覆盖这些地址）。通过将值设置`WARM_IP_TARGET`为小于 16，可以防止 CNI 保留全部多余的前缀。

### 与附加新 ENI 相比，更喜欢分配新的前缀
<a name="_prefer_allocating_new_prefixes_over_attaching_a_new_eni"></a>

与创建新的 ENI 并将其附加到实例相比，为现有 ENI 分配额外前缀更快的 EC2 API 操作。使用前缀可以提高性能，同时节俭 IPv4 地址分配。附加前缀通常在不到一秒钟的时间内完成，而连接新的 ENI 可能需要长达 10 秒的时间。对于大多数用例，CNI 在前缀模式下运行时，每个工作节点只需要一个 ENI。如果您负担得起（在最坏的情况下）每个节点多达 15 个未使用的 IP，我们强烈建议您使用更新的前缀分配网络模式，并实现随之而来的性能和效率提升。

### 使用子网预留避免子网碎片 (IPv4)
<a name="_use_subnet_reservations_to_avoid_subnet_fragmentation_ipv4"></a>

当 EC2 为 ENI 分配 /28 IPv4 前缀时，它必须是您子网中连续的 IP 地址块。如果生成前缀的子网是碎片化的（一个高度使用的子网，具有分散的辅助 IP 地址），则前缀连接可能会失败，并且您将在 VPC CNI 日志中看到以下错误消息：

```
failed to allocate a private IP/Prefix address: InsufficientCidrBlocks: There are not enough free cidr blocks in the specified subnet to satisfy the request.
```

为了避免分段并有足够的连续空间来创建前缀，您可以使用 VP [C 子网 CIDR 预留在子网内保留](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html#work-with-subnet-cidr-reservations) IP 空间供前缀专用。创建预留后，VPC CNI 插件将调用 EC2 API 来分配从预留空间自动分配的前缀。

建议创建一个新子网，为前缀预留空间，并使用 VPC CNI 为在该子网中运行的工作节点启用前缀分配。如果新子网仅专用于在启用了 VPC CNI 前缀分配的 EKS 集群中运行的 Pod，则可以跳过前缀预留步骤。

### 避免降级 VPC CNI
<a name="_avoid_downgrading_vpc_cni"></a>

前缀模式适用于 VPC CNI 版本 1.9.0 及更高版本。启用前缀模式并为 ENI 分配前缀后，必须避免将 Amazon VPC CNI 附加组件降级到低于 1.9.0 的版本。如果您决定降级 VPC CNI，则必须删除并重新创建节点。

### 在过渡到前缀委派期间替换所有节点
<a name="_replace_all_nodes_during_the_transition_to_prefix_delegation"></a>

强烈建议您创建新的节点组以增加可用 IP 地址的数量，而不是滚动替换现有的工作节点。封锁并耗尽所有现有节点，以安全地驱逐所有现有 Pod。为了防止服务中断，我们建议在生产集群上为关键工作负载实施 [Pod 中断预算](https://kubernetes.io/docs/tasks/run-application/configure-pdb)。新节点上的 Pod 将从分配给 ENI 的前缀中分配一个 IP。确认 Pod 正在运行后，您可以删除旧的节点和节点组。如果您使用的是托管节点组，请按照此处提到的步骤安全地[删除节点组](https://docs.aws.amazon.com/eks/latest/userguide/delete-managed-node-group.html)。