

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

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

在 Amazon EKS 中，默认情况下，VP [C 资源控制器](https://github.com/aws/amazon-vpc-resource-controller-k8s)会为在 Windows 主机上运行的每个 Pod 分配一个辅助 IP 地址。此 IP 地址是从主机的子网分配的 VPC 可路由地址。在 Linux 上，连接到实例的每个 ENI 都有多个插槽，可以用辅助 IP 地址或 /28 CIDR（前缀）填充这些插槽。但是，Windows 主机仅支持单个 ENI 及其可用插槽。即使有大量 IP 地址可供分配，也只能使用辅助 IP 地址可以人为地限制你可以在 Windows 主机上运行的 pod 数量。

为了提高 Windows 主机上的容器密度，尤其是在使用较小的实例类型时，您可以为 Windows 节点启用**前缀委**派。启用前缀委派后，将为 ENI 插槽分配 /28 IPv4 前缀，而不是辅助 IP 地址。可以通过将`enable-windows-prefix-delegation: "true"`条目添加到`amazon-vpc-cni`配置映射来启用前缀委托。这与配置映射相同，你需要在其中设置`enable-windows-ipam: "true"`条目才能启用 Windows 支持。

请按照 [EKS 用户指南](https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses.html)中提及的说明为 Windows 节点启用前缀委派模式。

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


图：辅助 IP 模式与前缀委派模式的比较

您可以为网络接口分配的最大 IP 地址数取决于实例类型及其大小。分配给网络接口的每个前缀都会占用一个可用插槽。例如，`c5.large`实例对每个网络接口的`10`插槽数有限制。网络接口上的第一个插槽总是被该接口的主要 IP 地址占用，剩下 9 个插槽用于前缀 and/or 辅助 IP 地址。如果为这些插槽分配了前缀，则节点可以支持 (9 \$1 16) 144 个 IP 地址，而如果为它们分配了辅助 IP 地址，则只能支持 9 个 IP 地址。有关更多信息，请参阅有关[每种实例类型的每个网络接口的 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 资源控制器会为主 ENI 分配一个或多个前缀，通过维护 IP 地址的热池，从而更快地启动 Pod。通过在配置映射中设置以下配置参数，可以控制要在温池中`amazon-vpc-cni`保存的前缀数量。
+  `warm-prefix-target`，即要分配的超出当前需求的前缀数量。
+  `warm-ip-target`，要分配的超出当前需求的 IP 地址数量。
+  `minimum-ip-target`，任何时候可用的 IP 地址的最小数量。
+  `warm-ip-target` and/or `minimum-ip-target`如果设置则会覆盖`warm-prefix-target`。

随着节点上调度更多的 Pod，将为现有 ENI 请求额外的前缀。在节点上调度 Pod 时，VPC 资源控制器将首先尝试从节点上的现有前缀中分配一个 IPv4 地址。如果这不可能，则只要子网具有所需的容量，就会请求新的 IPv4 前缀。

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


图：向 Pod 分配 IPv4 地址期间的工作流程

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

### 在以下情况下使用前缀委托
<a name="_use_prefix_delegation_when"></a>

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

默认情况下，Windows 节点`max-pods`上的设置为`110`。对于绝大多数实例类型来说，这应该足够了。如果您想增加或减少此限制，请在用户数据中的 bootstrap 命令中添加以下内容：

```
-KubeletExtraArgs '--max-pods=example-value'
```

有关 Windows 节点的引导程序配置参数的更多详细信息，请访问[此处](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-windows-ami.html#bootstrap-script-configuration-parameters)的文档。

### 在以下情况下避免前缀委托
<a name="windows-prefix-avoid"></a>

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

### 配置前缀委派参数以节省地址 IPv4
<a name="windows-network-conserve"></a>

 `warm-prefix-target`、`warm-ip-target`、和`minimum-ip-target`可用于微调预缩放和带前缀的动态缩放行为。默认情况下，使用以下值：

```
warm-ip-target: "1"
minimum-ip-target: "3"
```

通过微调这些配置参数，您可以在节省 IP 地址和确保减少因分配 IP 地址而导致的 Pod 延迟之间取得最佳平衡。有关这些配置参数的更多信息，请访问[此处](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/docs/windows/prefix_delegation_config_options.md)的文档。

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

当 EC2 为 ENI 分配 /28 IPv4 前缀时，它必须是您子网中连续的 IP 地址块。如果生成前缀的子网是碎片化的（具有分散的辅助 IP 地址的高度使用子网），则前缀连接可能会失败，您将看到以下节点事件：

```
InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks 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 空间供前缀专用。创建预留后，保留区块中的 IP 地址将不会分配给其他资源。这样，VPC 资源控制器将能够在对节点 ENI 的分配调用期间获得可用的前缀。

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

### 从辅助 IP 模式迁移到前缀委派模式时替换所有节点，反之亦然
<a name="_replace_all_nodes_when_migrating_from_secondary_ip_mode_to_prefix_delegation_mode_or_vice_versa"></a>

强烈建议您创建新的节点组以增加可用 IP 地址的数量，而不是滚动替换现有的工作节点。

使用自管理节点组时，过渡步骤为：
+ 增加集群中的容量，以便新节点能够容纳您的工作负载
+ 启用/禁用 Windows 的前缀委派功能
+ 封锁并耗尽所有现有节点，以安全地驱逐所有现有 Pod。为了防止服务中断，我们建议在生产集群上为关键工作负载实施 [Pod 中断预算](https://kubernetes.io/docs/tasks/run-application/configure-pdb)。
+ 确认 Pod 正在运行后，您可以删除旧的节点和节点组。新节点上的 Pod 将从分配给节点 ENI 的前缀中分配一个 IPv4 地址。

使用托管节点组时，过渡步骤为：
+ 启用/禁用 Windows 的前缀委派功能
+ 使用此[处](https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html)提到的步骤更新节点组。其执行的步骤与上述类似，但由 EKS 管理。

**警告**  
以相同模式运行节点上的所有 Pod

对于 Windows，我们建议你避免同时在辅助 IP 模式和前缀委派模式下运行 Pod。当你在运行 Windows 工作负载时从辅助 IP 模式迁移到前缀委派模式时，可能会出现这种情况，反之亦然。

虽然这不会影响你正在运行的 Pod，但节点的 IP 地址容量可能会不一致。例如，假设一个 t3.xlarge 节点有 14 个用于存放辅助地址的插槽。 IPv4 如果你运行的是 10 个 Pod，那么 ENI 上的 10 个插槽将被辅助 IP 地址占用。启用前缀委派后，向 kube-api 服务器通告的容量为（14 个插槽 \$1 每个前缀 16 个 IP 地址）244，但当时的实际容量为（剩下 4 个插槽 \$1 每个前缀 16 个地址）64。如果您运行的 Pod 多于可供分配的 IP 地址，则通告的容量与实际容量（剩余插槽）之间的这种不一致可能会导致问题。

话虽如此，你可以使用上述迁移策略将你的 Pod 从辅助 IP 地址安全地过渡到从前缀获取的地址。在两种模式之间切换时，Pod 将继续正常运行，并且：
+ 从辅助 IP 模式切换到前缀委派模式时，分配给正在运行的 pod 的辅助 IP 地址不会被释放。前缀将分配给空闲插槽。Pod 终止后，它使用的辅助 IP 和插槽将被释放。
+ 从前缀委托模式切换到辅助 IP 模式时，当其 IPs 范围内的所有前缀都不再分配给 pod 时，将释放前缀。如果将前缀中的任何 IP 分配给 pod，则该前缀将一直保留，直到 pod 终止。

### 前缀委派的调试问题
<a name="_debugging_issues_with_prefix_delegation"></a>

你可以[在这里](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/docs/troubleshooting.md)使用我们的调试指南来深入探讨你在Windows上前缀委托所面临的问题。