本文发布已超过一年。较早的文章可能包含过时的内容。请确认页面信息自发布以来没有变得不准确。
Kubernetes 中 Windows 网络与 Linux 持平
自从我四个月前发表关于适用于 Windows 的 Kubernetes 网络的博客以来,Windows Core Networking 团队在平台和开源 Kubernetes 项目方面都取得了巨大进展。通过这些更新,Windows 现在在网络方面与 Linux 不相上下。客户现在可以在任何环境,包括 Azure、本地环境和第三方云堆栈上部署混合操作系统的 Kubernetes 集群,并且使用与 Linux 上支持的相同的网络原语和拓扑,无需任何变通方法、“hack”或第三方交换机扩展。
你可能会问,“那又怎样?”。这些平台改进在希望运行 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 Virtual Filtering Platform (VFP) Hyper-V 交换机扩展实现。现在,外部和集群内流量都可以通过单个端点流动。
在 Windows 内核中使用 VFP 进行负载均衡
Kubernetes 工作节点依赖于 kube-proxy 来在集群中的 Pod 之间对进入 Service IP 的网络流量进行负载均衡。以前的 Windows 版本通过用户空间代理实现 Kube-proxy 的负载均衡。我们最近增加了对“Proxy mode: iptables”的支持,它使用 Windows 内核中的 VFP 实现,因此 Windows OS 内核可以更高效地对任何 IP 流量进行负载均衡。用户还可以通过在服务定义中指定 externalIP 参数来配置外部负载均衡器。除了上述改进之外,我们还增加了对以下平台功能的 ondersteuning
- 支持每个容器/Pod 的 DNS 搜索后缀(Docker 改进 - 消除了之前 kube-proxy 为附加 DNS 后缀所做的额外工作)
- [平台支持] 用于创建 ACL 的 5-tuple 规则(正在寻求社区帮助,以便将其与 K8s Network Policy 支持集成)
现在 Windows Server 已经加入了 Windows Insider Program,客户和合作伙伴今天就可以利用这些新的平台功能,这些功能将为今年晚些时候备受期待的新功能版本和六个月后的新构建积累价值。最新的 Windows Server insider 构建现在包含了对所有这些平台改进的支持。
除了 Windows 平台的改进之外,团队还为 CNI、kubelet 和 kube-proxy 提交了代码 (PR),目标是将 Windows 支持主线合并到 Kubernetes v1.8 版本中。这些 PR 移除了之前在 Windows 上所需的变通方法,例如用于内部负载均衡的用户模式代理、为每个 Kube-DNS 请求附加额外的 DNS 后缀,以及用于外部(互联网)连接的单独容器端点。
- https://github.com/kubernetes/kubernetes/pull/51063
- https://github.com/kubernetes/kubernetes/pull/51064
这些新的平台功能以及在 kubelet 和 kube-proxy 上的工作与 Kubernetes 在 Linux 上使用的 CNI 网络模型对齐,并简化了 K8s 集群的部署,无需额外的配置或自定义 (Azure) 资源模板。为此,我们完成了 CNI 网络和 IPAM 插件的工作,用于创建/删除端点和管理 IP 地址。CNI 插件通过 kubelet 工作,目标是 Windows Host Networking Service (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 的 PR,将这些更改主线合并到定于今年 9 月发布的 Kubernetes v1.8 版本中。这些功能随后可以在当前的 Windows Server insider 构建版本和Windows Server 版本 1709 上使用。
在 RTM 发布后不久,我们还将把这些改进引入 Azure Container Service (ACS),以便 Windows 工作节点和托管的容器成为一流的 Azure VNet 公民。适用于 Windows CNI 的 Azure IPAM 插件将使这些端点能够直接连接到 Azure VNet,并以与 VM 相同的方式强制执行 Windows 容器的网络策略。
| 功能 | Windows Server 2016 (当前版本) | 下一个 Windows Server 功能版本,半年频道 | Linux | | 每个 Pod 中的多个容器,共享网络命名空间 (Compartment) | 每个 Pod 一个容器 | ✔ | ✔ | | 每个 Pod 的单个(共享)端点 | 两个端点:WinNAT (外部) + Transparent (集群内) | ✔ | ✔ | | 用户模式负载均衡 | ✔ | ✔ | ✔ | | 内核模式负载均衡 | 不支持 | ✔ | ✔ | | 支持每个 Pod 的 DNS 搜索后缀 (Docker 更新) | Kube-Proxy 为每个请求附加多个 DNS 后缀 | ✔ | ✔ | | CNI 插件支持 | 不支持 | ✔ | ✔ |
Kubernetes SIG Windows 小组每两周在东部时间周二下午 12:30 举行会议。要加入或查看之前会议的纪要,请查阅此文档。