

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

# Windows 联网
<a name="windows-networking"></a>

## Windows 容器网络概述
<a name="_windows_container_networking_overview"></a>

Windows 容器与 Linux 容器有根本的不同。Linux 容器使用 Linux 结构，例如命名空间、联合文件系统和 cgroups。在 Windows 上，这些结构是由[主机计算服务](https://github.com/microsoft/hcsshim) (HCS) 从 containerd 中抽象出来的。HCS 充当一个 API 层，位于 Windows 上的容器实现之上。Windows 容器还利用主机网络服务 (HNS) 来定义节点上的网络拓扑。

![\[Windows 联网\]](http://docs.aws.amazon.com/zh_cn/eks/latest/best-practices/images/windows/windows-networking.png)


从网络的角度来看，HCS 和 HNS 使 Windows 容器的功能类似于虚拟机。例如，每个容器都有一个虚拟网络适配器 (vNIC)，该适配器连接到 Hyper-V 虚拟交换机 (vSwitch)，如上图所示。

## IP 地址管理
<a name="_ip_address_management"></a>

Amazon EKS 中的一个节点使用其弹性网络接口 (ENI) 连接到 AWS VPC 网络。目前，**每个 Windows 工作节点仅支持一个 ENI**。Windows 节点的 IP 地址管理由在控制平面中运行的 [VPC 资源控制器](https://github.com/aws/amazon-vpc-resource-controller-k8s)执行。有关 Windows 节点 IP 地址管理工作流程的更多详细信息，可[在此处](https://github.com/aws/amazon-vpc-resource-controller-k8s#windows-ipv4-address-management)找到。

Windows 工作节点可以支持的 pod 数量取决于节点的大小和可用 IPv4 地址的数量。您可以计算节点上的可用 IPv4 地址，如下所示：
+ 默认情况下，仅向 ENI 分配辅助 IPv4 地址。在这种情况下：

  ```
  Total IPv4 addresses available for Pods = Number of supported IPv4 addresses in the primary interface - 1
  ```

  我们从总数中减去一个，因为一个 IPv4 地址将用作 ENI 的主地址，因此无法分配给 Pod。
+ 如果已通过启用[前缀委派功能](prefix-mode-win.md)将集群配置为高 pod 密度，那么-

  ```
  Total IPv4 addresses available for Pods = (Number of supported IPv4 addresses in the primary interface - 1) * 16
  ```

  在这里，VPC 资源控制器不会分配`/28 prefixes`辅助 IPv4 地址，而是分配，因此，可用 IPv4 地址的总数将增加 16 倍。

使用上面的公式，我们可以计算基于 m5.large 实例的 Windows 工作节点的最大 pod 数，如下所示：
+ 默认情况下，在辅助 IP 模式下运行时-

  ```
  10 secondary IPv4 addresses per ENI - 1 = 9 available IPv4 addresses
  ```
+ 使用时 `prefix delegation`-

  ```
  (10 secondary IPv4 addresses per ENI - 1) * 16 = 144 available IPv4 addresses
  ```

有关实例类型可以支持多少 IP 地址的更多信息，请参阅[每种实例类型的每个网络接口的 IP 地址](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)。



另一个关键考虑因素是网络流量。使用 Windows 时，在拥有超过 100 个服务的节点上存在端口耗尽的风险。出现这种情况时，节点将开始抛出错误，并显示以下消息：

 **“策略创建失败：Win32 中的 hcnCreateLoad平衡器失败：指定的端口已经存在。”** 

为了解决这个问题，我们利用服务器直接返回 (DSR)。DSR 是一种非对称网络负载分配的实现。换句话说，请求和响应流量使用不同的网络路径。此功能可加快 Pod 之间的通信速度并降低端口耗尽的风险。因此，我们建议在 Windows 节点上启用 DSR。

在 Windows Server SAC EKS 优化版中，DSR 默认处于启用状态。 AMIs对于 Windows Server 2019 LTSC EKS Optimized AMIs，你需要使用下面的脚本在实例配置期间启用它，并在 NodeGroup 中使用 Windows Server 2019 Full 或 Core 作为 amiFamily。`eksctl`有关更多信息，请参阅 [eksctl 自定义 AMI](https://eksctl.io/usage/custom-ami-support/)。

```
nodeGroups:
- name: windows-ng
  instanceType: c5.xlarge
  minSize: 1
  volumeSize: 50
  amiFamily: WindowsServer2019CoreContainer
  ssh:
    allow: false
```

要在 Windows Server 2019 及更高版本中使用 DSR，你需要在实例启动期间指定以下 [https://kubernetes.io/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#load-balancing-and-services](https://kubernetes.io/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#load-balancing-and-services) 标志。您可以通过调整与[自管理节点组启动](https://docs.aws.amazon.com/eks/latest/userguide/launch-windows-workers.html)模板关联的用户数据脚本来做到这一点。

```
<powershell>
[string]$EKSBinDir = "$env:ProgramFiles\Amazon\EKS"
[string]$EKSBootstrapScriptName = 'Start-EKSBootstrap.ps1'
[string]$EKSBootstrapScriptFile = "$EKSBinDir\$EKSBootstrapScriptName"
(Get-Content $EKSBootstrapScriptFile).replace('"--proxy-mode=kernelspace",', '"--proxy-mode=kernelspace", "--feature-gates WinDSR=true", "--enable-dsr",') | Set-Content $EKSBootstrapScriptFile
& $EKSBootstrapScriptFile -EKSClusterName "eks-windows" -APIServerEndpoint "https://<REPLACE-EKS-CLUSTER-CONFIG-API-SERVER>" -Base64ClusterCA "<REPLACE-EKSCLUSTER-CONFIG-DETAILS-CA>" -DNSClusterIP "172.20.0.10" -KubeletExtraArgs "--node-labels=alpha.eksctl.io/cluster-name=eks-windows,alpha.eksctl.io/nodegroup-name=windows-ng-ltsc2019 --register-with-taints=" 3>&1 4>&1 5>&1 6>&1
</powershell>
```

可以按照微[软网络博客](https://techcommunity.microsoft.com/t5/networking-blog/direct-server-return-dsr-in-a-nutshell/ba-p/693710)和 [AWS 实验室上的 Windows 容器](https://catalog.us-east-1.prod.workshops.aws/workshops/1de8014a-d598-4cb5-a119-801576492564/en-US/module1-eks/lab3-handling-mixed-clusters)中的说明验证 DSR 的启用。

![\[dsr\]](http://docs.aws.amazon.com/zh_cn/eks/latest/best-practices/images/windows/dsr.png)


如果保留可用 IPv4 地址和最大限度地减少浪费对子网至关重要，那么通常建议避免使用 [Windows 前缀模式-何时避免使用前缀委派模式](prefix-mode-win.md#windows-prefix-avoid)。如果仍需要使用前缀委派，则可以采取措施优化子网中的 IPv4 地址利用率。[有关如何微调 IPv4 地址请求和分配过程的详细说明，请参阅配置前缀委派参数](prefix-mode-win.md#windows-network-conserve)。调整这些配置可以帮助您在节省 IPv4 地址和前缀委派的 pod 密度优势之间取得平衡。

当使用分配辅助 IPv4 地址的默认设置时，目前不支持用于操作 VPC 资源控制器请求和分配 IPv4 地址的配置。更具体地说`minimum-ip-target`，`warm-ip-target`只有前缀委托模式才支持和。另请注意，在辅助 IP 模式下，根据接口上的可用 IP 地址，VPC 资源控制器通常会代表您在节点上分配 3 个未使用 IPv4 的地址，以保持温暖 IPs ，从而缩短 Pod 启动时间。如果您想最大限度地减少未使用的热 IP 地址的 IP 浪费，则可以设法在给定的 Windows 节点上安排更多 pod，以便尽可能多地使用 ENI 的 IP 地址容量。更明确地说， IPs 如果节点和正在运行的 pod 都已使用 ENI 上的所有 IP 地址，则可以避免未使用预热。帮助您解决子网中 IP 地址可用性限制的另一种解决方法是探索[增加子网大小](https://docs.aws.amazon.com/vpc/latest/userguide/modify-subnets.html)或将 Windows 节点分成自己的专用子网。

此外，需要注意 IPv6 的是，目前 Windows 节点不支持这一点。

## 容器网络接口 (CNI) 选项
<a name="_container_network_interface_cni_options"></a>

 AWSVPC CNI 实际上是适用于 Windows 和 Linux 工作节点的 CNI 插件。尽管 AWSVPC CNI可以满足许多客户的需求，但有时您仍需要考虑诸如覆盖网络之类的替代方案，以避免IP耗尽。在这些情况下，可以使用 Calico CNI 代替 CNI。 AWSVPC P@@ [roject Calico](https://www.projectcalico.org/) 是由 [Tig](https://www.tigera.io/) era 开发的开源软件。该软件包括可与EKS配合使用的CNI。在 EKS 中安装 Calico CNI 的说明可以在 P [roject Calico EKS](https://docs.projectcalico.org/getting-started/kubernetes/managed-public-cloud/eks) 安装页面上找到。

## 网络策略
<a name="_network_polices"></a>

从 Kubernetes 集群上的 Pod 之间的默认开放通信模式更改为基于网络策略限制访问的默认模式，这被认为是一种最佳实践。开源 P [roject Calico](https://www.tigera.io/tigera-products/calico/) 为同时适用于 Linux 和 Windows 节点的网络策略提供了强有力的支持。此功能是独立的，不依赖于使用 Calico CNI。因此，我们建议安装 Calico 并将其用于网络策略管理。

在 EKS 中安装 Calico 的说明可以在[亚马逊 EKS 上安装 Calico 页面上找到。](https://docs.aws.amazon.com/eks/latest/userguide/calico.html)

此外，《[Amazon EKS 安全最佳实践指南-网络》部分](https://docs.aws.amazon.com/eks/latest/best-practices/network-security.html)中提供的建议同样适用于带有 Windows 工作节点的 EKS 集群，但是，Windows 目前不支持某些功能，例如 “Pod 的安全组”。