本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Windows 网络与 Linux 在 Kubernetes 中达到同等水平

自四个月前我上次撰写关于Kubernetes Windows 网络的博客以来,Windows 核心网络团队在平台和开源 Kubernetes 项目方面都取得了巨大进展。通过这些更新,Windows 在网络方面已与 Linux 媲美。客户现在可以在任何环境中(包括 Azure、本地和第三方云堆栈)部署混合操作系统 Kubernetes 集群,享受与 Linux 上相同的网络原语和拓扑,而无需任何变通方法、“技巧”或第三方交换机扩展。

你可能会问,“那又怎样?”。这些平台改进在希望运行 Kubernetes 的开发人员和运维团队的生活中产生了实质性影响,原因涉及多个应用程序和基础设施方面。继续阅读以了解更多信息!

紧密耦合的通信

这些改进实现了单个“Pod”内多个 Windows Server 容器(没有 Hyper-V 隔离)之间的紧密耦合通信。可以将 Pod 视为 Kubernetes 集群的调度单元,在其中,一个或多个应用程序容器协同部署,并能够共享存储和网络资源。Pod 中的所有容器共享相同的 IP 地址和端口范围,并能够使用 localhost 相互通信。这使得应用程序可以轻松利用“辅助”程序来完成监控、配置更新、日志管理和代理等任务。另一种思考 Pod 的方式是将其视为一个计算主机,其中应用程序容器代表进程。

简化的网络拓扑

我们还通过将每个容器(或更普遍地,每个 Pod)所需的端点数量减少到一个,简化了 Kubernetes 集群中 Windows 节点的网络拓扑。以前,在 Kubernetes 集群中运行的 Windows 容器(Pod)需要两个端点——一个用于外部(互联网)通信,另一个用于集群内其他节点或 Pod 之间的通信。这是因为从连接到具有本地范围(即不可公开路由)的主机网络的容器进行外部通信需要 NAT 操作,而这只能通过主机上的 Windows NAT (WinNAT) 组件提供。集群内通信则要求容器通过第二个端点连接到具有“全局”(集群级别)范围的独立网络。最近的平台改进现在可以直接在容器端点上进行 NAT 操作,该端点通过 Microsoft 虚拟过滤平台 (VFP) Hyper-V 交换机扩展实现。现在,外部和集群内流量都可以通过单个端点进行传输。

使用 Windows 内核中的 VFP 进行负载均衡

Kubernetes 工作节点依赖 kube-proxy 在集群内的 Pod 之间对传入的服务 IP 网络流量进行负载均衡。早期版本的 Windows 通过用户空间代理实现了 Kube-proxy 的负载均衡。我们最近增加了对“代理模式:iptables”的支持,该模式使用 Windows 内核中的 VFP 实现,因此 Windows 操作系统内核可以更有效地对任何 IP 流量进行负载均衡。用户还可以通过在服务定义中指定 externalIP 参数来配置外部负载均衡器。除了上述改进之外,我们还增加了对以下功能平台支持:

  • 支持每个容器/Pod 的 DNS 搜索后缀(Docker 改进 - 消除了 kube-proxy 以前为添加 DNS 后缀所做的额外工作) 
  • [平台支持] 用于创建 ACL 的 5 元组规则(寻求社区帮助以将其与 K8s 网络策略支持集成)

现在 Windows Server 已加入 Windows Insider Program,客户和合作伙伴可以立即利用这些新的平台功能,这些功能将为今年晚些时候备受期待的新功能发布和六个月后的新版本带来价值。最新的 Windows Server Insider 版本现在包含了对所有这些平台改进的支持。

除了 Windows 的平台改进之外,该团队还为 CNI、kubelet 和 kube-proxy 提交了代码(PRs),目标是将 Windows 支持纳入 Kubernetes v1.8 版本。这些 PRs 消除了 Windows 上以前所需的变通方法,例如用于内部负载均衡的用户模式代理、为每个 Kube-DNS 请求附加额外的 DNS 后缀,以及用于外部(互联网)连接的单独容器端点。

这些新的平台功能以及对 kubelet 和 kube-proxy 的工作与 Linux 上 Kubernetes 使用的 CNI 网络模型保持一致,并简化了 K8s 集群的部署,无需额外的配置或自定义(Azure)资源模板。为此,我们完成了 CNI 网络和 IPAM 插件的工作,以创建/删除端点和管理 IP 地址。CNI 插件通过 kubelet 调用 Windows 主机网络服务 (HNS) API 来创建“l2bridge”网络(类似于 Linux 上的 macvlan),该网络由 VFP 交换机扩展强制执行。

“l2bridge”网络驱动程序在入口和出口处重写容器网络流量的 MAC 地址,以使用容器主机的 MAC 地址。这消除了上游网络交换机端口(容器主机连接到该端口)需要“学习”多个 MAC 地址(每个运行在主机上的容器一个)的需求。这节省了物理交换机 TCAM 表中的内存空间,并依赖 Hyper-V 虚拟交换机在主机中进行 MAC 地址转换,以将流量转发到正确的容器。IP 地址由默认的 Windows IPAM 插件管理,该插件要求 POD CIDR IP 取自容器主机的网络 IP 空间。

该团队在 8 月 8 日向 SIG-Windows 小组演示了(视频链接)这些新的平台功能和开源更新。我们正在与社区合作,合并 kubelet 和 kube-proxy PRs,以便及时将这些更改纳入将于今年 9 月发布的 Kubernetes v1.8 版本。这些功能随后可以在当前的 Windows Server Insider 版本和Windows Server 1709 版上使用。

RTM 后不久,我们还将这些改进引入 Azure 容器服务 (ACS),以便 Windows 工作节点和托管的容器成为 Azure VNet 的一等公民。适用于 Windows CNI 的 Azure IPAM 插件将使这些端点能够直接连接到 Azure VNet,其 Windows 容器的网络策略将以与 VM 相同的方式强制执行。

| 功能 | Windows Server 2016 (已上市) | 下一个 Windows Server 功能发布,半年频道 | Linux | | 每个 Pod 多个容器,共享网络命名空间 (Compartment) | 每个 Pod 一个容器 | ✔ | ✔ | | 每个 Pod 单个(共享)端点 | 两个端点:WinNAT(外部)+ 透明(集群内) | ✔ | ✔ | | 用户模式负载均衡 | ✔ | ✔ | ✔ | | 内核模式负载均衡 | 不支持 | ✔ | ✔ | | 支持每个 Pod 的 DNS 搜索后缀(Docker 更新) | Kube-Proxy 为每个请求添加了多个 DNS 后缀 | ✔ | ✔ | | CNI 插件支持 | 不支持 | ✔ | ✔ |

Kubernetes SIG Windows 小组每两周开会一次,时间为周二上午 12:30 ET。要加入或查看以前会议的记录,请查阅此文档