

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

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

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

Windows 容器与 Linux 容器有根本的不同。Linux 容器使用 Linux 结构，例如命名空间、联合文件系统和 cgroups。在 Windows 上，这些结构由[主机计算服务 (HCS) 从容器中抽象出来。](https://github.com/microsoft/hcsshim)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>

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

Windows 工作节点可以支持的 pod 数量由节点的大小和可用 IPv4 地址的数量决定。您可以按如下方式计算节点上可用的 IPv4 地址：
+ 默认情况下，仅将辅助 IPv4 地址分配给 ENI。在这种情况下：

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

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

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

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

使用上面的公式，我们可以计算基于 m5.large 实例的 Windows 工作节点的最大容量，如下所示：
+ 默认情况下，在辅助 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 个以上服务的节点存在端口耗尽的风险。出现这种情况时，节点将开始抛出错误，并显示以下消息：

 **“策略创建失败：HCN 在 Win32 中CreateLoadBalancer 失败：指定的端口已经存在。”** 

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

在 Windows Server SAC EKS 优化的 AMI 中，DSR 默认处于启用状态。对于 Windows Server 2019 LTSC EKS Optimized AMI，你需要在实例配置期间使用以下脚本并在节点组中使用 Windows Server 2019 完整版或核心版作为 AMI 系列来启用它。`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，你需要在实例启动期间指定以下 [** kube-proxy **](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 容器实验室中的说明来验证 DSR 的启用。](https://catalog.us-east-1.prod.workshops.aws/workshops/1de8014a-d598-4cb5-a119-801576492564/en-US/module1-eks/lab3-handling-mixed-clusters)

![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 地址，以维护热 IP 以缩短 Pod 启动时间。如果你想最大限度地减少未使用的热 IP 地址的 IP 浪费，你可以考虑在给定的 Windows 节点上安排更多 pod，这样你就可以尽可能多地使用 ENI 的 IP 地址容量。更明确地说，如果节点和运行中的 Pod 已经使用了 ENI 上的所有 IP 地址，则可以避免使用预热的未使用 IP。帮助你解决子网中 IP 地址可用性限制的另一种解决方法是探索[增加子网大小](https://docs.aws.amazon.com/vpc/latest/userguide/modify-subnets.html)或将 Windows 节点分成自己的专用子网。

此外，值得注意的是，目前 Windows 节点不支持 IPv6。

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

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

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

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

有关在亚马逊 EKS 上安装 Calico 的说明，请参阅 Tigera 网站上的 “在亚马逊 EKS [ 上](https://docs.tigera.io/calico/latest/getting-started/kubernetes/managed-public-cloud/eks)安装 Calico”。

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