在许多组织中,所运行的很大一部分服务和应用是 Windows 应用。Windows 容器提供了一种封装进程和包依赖项的方式,从而简化了 DevOps 实践,令 Windows 应用同样遵从云原生模式。
对于同时投入基于 Windows 应用和 Linux 应用的组织而言,他们不必寻找不同的编排系统来管理其工作负载,使其跨部署的运营效率得以大幅提升,而不必关心所用的操作系统。
若要在 Kubernetes 中启用对 Windows 容器的编排,可以在现有的 Linux 集群中包含 Windows 节点。在 Kubernetes 上调度 Pod 中的 Windows 容器与调度基于 Linux 的容器类似。
为了运行 Windows 容器,你的 Kubernetes 集群必须包含多个操作系统。尽管你只能在 Linux 上运行控制平面,你可以部署运行 Windows 或 Linux 的工作节点。
支持 Windows 节点的前提是操作系统为Windows Server 2022 或 Windows Server 2025。
本文使用术语 Windows 容器表示具有进程隔离能力的 Windows 容器。Kubernetes 不支持使用Hyper-V 隔离能力来运行Windows 容器。
某些节点层面的功能特性仅在使用特定容器运行时时才可用;另外一些特性则在 Windows 节点上不可用,包括:
Windows 节点并不支持共享命名空间的所有功能特性。有关更多详细信息,请参考 API 兼容性。
有关 Kubernetes 测试时所使用的 Windows 版本的详细信息,请参考Windows 操作系统版本兼容性。
从 API 和 kubectl 的角度来看,Windows 容器的行为与基于 Linux 的容器非常相似。然而,在本节所概述的一些关键功能上,二者存在一些显著差异。
Kubernetes 关键组件在 Windows 上的工作方式与在 Linux 上相同。本节介绍几个关键的工作负载抽象及其如何映射到 Windows。
Pod 是 Kubernetes 的基本构建块,是可以创建或部署的最小和最简单的单元。你不可以在同一个 Pod 中部署 Windows 和 Linux 容器。Pod 中的所有容器都调度到同一 Node 上,每个 Node 代表一个特定的平台和体系结构。Windows 容器支持以下 Pod 能力、属性和事件:
每个 Pod 有一个或多个容器,具有进程隔离和卷共享能力
Pod status 字段
就绪、存活和启动探针
postStart 和 preStop 容器生命周期回调
ConfigMap 和 Secret:作为环境变量或卷
emptyDir 卷
命名管道形式的主机挂载
资源限制
操作系统字段:
.spec.os.name 字段应设置为 windows 以表明当前 Pod 使用 Windows 容器。
如果你将 .spec.os.name 字段设置为 windows,则你必须不能在对应 Pod 的 .spec 中设置以下字段:
spec.hostPIDspec.hostIPCspec.securityContext.seLinuxOptionsspec.securityContext.seccompProfilespec.securityContext.fsGroupspec.securityContext.fsGroupChangePolicyspec.securityContext.sysctlsspec.shareProcessNamespacespec.securityContext.runAsUserspec.securityContext.runAsGroupspec.securityContext.supplementalGroupsspec.containers[*].securityContext.seLinuxOptionsspec.containers[*].securityContext.seccompProfilespec.containers[*].securityContext.capabilitiesspec.containers[*].securityContext.readOnlyRootFilesystemspec.containers[*].securityContext.privilegedspec.containers[*].securityContext.allowPrivilegeEscalationspec.containers[*].securityContext.procMountspec.containers[*].securityContext.runAsUserspec.containers[*].securityContext.runAsGroup在上述列表中,通配符(*)表示列表中的所有项。例如,spec.containers[*].securityContext 指代所有容器的 SecurityContext 对象。如果指定了这些字段中的任意一个,则 API 服务器不会接受此 Pod。
工作负载资源包括:
有关更多详细信息,请参考负载均衡和 Service。
Pod、工作负载资源和 Service 是在 Kubernetes 上管理 Windows 工作负载的关键元素。然而,它们本身还不足以在动态的云原生环境中对 Windows 工作负载进行恰当的生命周期管理。
kubectl exec某些 kubelet 命令行选项在 Windows 上的行为不同,如下所述:
--windows-priorityclass 允许你设置 kubelet 进程的调度优先级(参考 CPU 资源管理)。--kube-reserved、--system-reserved 和 --eviction-hard 标志更新NodeAllocatable。--enforce-node-allocable 驱逐。--kube-reserved 和 --system-reserved 仅从 NodeAllocatable 中减去,并且不保证为工作负载提供的资源。有关更多信息,请参考 Windows 节点的资源管理。PIDPressure 条件。由于操作系统和容器运行时的缘故,Kubernetes API 在 Windows 上的工作方式存在细微差异。某些工作负载属性是为 Linux 设计的,无法在 Windows 上运行。
从较高的层面来看,以下操作系统概念是不同的:
/etc/groups 或 /etc/passwd 中的别名,作为 UID+GID 的后备标识。Windows 使用更大的二进制安全标识符(SID),存放在 Windows 安全访问管理器(Security Access Manager,SAM)数据库中。此数据库在主机和容器之间或容器之间不共享。\ 而不是 /。Go IO 库通常接受两者,能让其正常工作,但当你设置要在容器内解读的路径或命令行时,可能需要用 \。WM_CLOSE 在内准确定义的消息。SERVICE_CONTROL_STOP 控制码的服务控制处理程序(Service Control Handler)函数。容器退出码遵循相同的约定,其中 0 表示成功,非零表示失败。具体的错误码在 Windows 和 Linux 中可能不同。但是,从 Kubernetes 组件(kubelet、kube-proxy)传递的退出码保持不变。
以下列表记录了 Pod 容器规约在 Windows 和 Linux 之间的工作方式差异:
requests.cpu 和 requests.memory -从节点可用资源中减去请求,因此请求可用于避免一个节点过量供应。但是,请求不能用于保证已过量供应的节点中的资源。如果运营商想要完全避免过量供应,则应将设置请求作为最佳实践应用到所有容器。securityContext.allowPrivilegeEscalation -不能在 Windows 上使用;所有权能字都无法生效。securityContext.capabilities - POSIX 权能未在 Windows 上实现。securityContext.privileged - Windows 不支持特权容器,可使用 HostProcess 容器代替。securityContext.procMount - Windows 没有 /proc 文件系统。securityContext.readOnlyRootFilesystem -不能在 Windows 上使用;对于容器内运行的注册表和系统进程,写入权限是必需的。securityContext.runAsGroup - 不能在 Windows 上使用,因为不支持 GID。securityContext.runAsNonRoot -此设置将阻止以 ContainerAdministrator 身份运行容器,这是 Windows 上与 root 用户最接近的身份。securityContext.runAsUser - 改用 runAsUserName。securityContext.seLinuxOptions - 不能在 Windows 上使用,因为 SELinux 特定于 Linux。terminationMessagePath - 这个字段有一些限制,因为 Windows 不支持映射单个文件。默认值为 /dev/termination-log,因为默认情况下它在 Windows 上不存在,所以能生效。以下列表记录了 Pod 规约在 Windows 和 Linux 之间的工作方式差异:
hostIPC 和 hostpid - 不能在 Windows 上共享主机命名空间。hostNetwork - 在 Windows 上不支持主机网络模式。dnsPolicy - Windows 不支持将 Pod dnsPolicy 设为 ClusterFirstWithHostNet,因为未提供主机网络。Pod 始终用容器网络运行。podSecurityContext 参见下文shareProcessNamespace - 这是一个 Beta 版功能特性,依赖于 Windows 上未实现的 Linux 命名空间。Windows 无法共享进程命名空间或容器的根文件系统(root filesystem)。只能共享网络。terminationGracePeriodSeconds - 这在 Windows 上的 Docker 中没有完全实现,请参考 GitHub issue。目前的行为是通过 CTRL_SHUTDOWN_EVENT 发送 ENTRYPOINT 进程,然后 Windows 默认等待 5 秒,最后使用正常的 Windows 关机行为终止所有进程。5 秒默认值实际上位于容器内的Windows 注册表中,因此在构建容器时可以覆盖这个值。volumeDevices - 这是一个 Beta 版功能特性,未在 Windows 上实现。Windows 无法将原始块设备挂接到 Pod。volumes
emptyDir 卷,则你无法将卷源设为 memory。mountPropagation,因为这在 Windows 上不支持。Kubernetes 从 v1.26 到 v1.32 提供了在主机网络命名空间中运行 Windows Pod 的 Alpha 版本支持。
Kubernetes v1.35 不包含 WindowsHostNetwork 特性门控,也不支持在主机网络命名空间中运行 Windows Pod。
Pod 的 securityContext
中只有 securityContext.runAsNonRoot 和 securityContext.windowsOptions 字段在 Windows 上生效。
节点问题检测器(参考节点健康监测)初步支持 Windows。有关更多信息,请访问该项目的 GitHub 页面。
在 Kubernetes Pod 中,首先创建一个基础容器或 “pause” 容器来承载容器。在 Linux 中,构成 Pod 的 cgroup 和命名空间维持持续存在需要一个进程;而 pause 进程就提供了这个功能。属于同一 Pod 的容器(包括基础容器和工作容器)共享一个公共网络端点(相同的 IPv4 和/或 IPv6 地址,相同的网络端口空间)。Kubernetes 使用 pause 容器以允许工作容器崩溃或重启,而不会丢失任何网络配置。
Kubernetes 维护一个多体系结构的镜像,包括对 Windows 的支持。对于 Kubernetes v1.35.0,推荐的 pause 镜像为 registry.k8s.io/pause:3.6。可在 GitHub 上获得源代码。
Microsoft 维护一个不同的多体系结构镜像,支持 Linux 和 Windows amd64,你可以找到的镜像类似 mcr.microsoft.com/oss/kubernetes/pause:3.6。此镜像的构建与 Kubernetes 维护的镜像同源,但所有 Windows 可执行文件均由Microsoft 进行了验证码签名。如果你正部署到一个需要签名可执行文件的生产或类生产环境,Kubernetes 项目建议使用 Microsoft 维护的镜像。
你需要将容器运行时安装到集群中的每个节点,这样 Pod 才能在这些节点上运行。
以下容器运行时适用于 Windows:
Kubernetes v1.20 [stable]
对于运行 Windows 的 Kubernetes 节点,你可以使用ContainerD 1.4.0+ 作为容器运行时。
将 GMSA 和 containerd 一起用于访问 Windows网络共享时存在已知限制,这需要一个内核补丁。
Mirantis 容器运行时(MCR)可作为所有 Windows Server 2019 和更高版本的容器运行时。
有关更多信息,请参考在 Windows Server 上安装 MCR。
在 Windows 节点上,如果主机操作系统版本必须与容器基础镜像操作系统版本匹配,则会应用严格的兼容性规则。仅 Windows Server 2019 作为容器操作系统时,才能完全支持 Windows 容器。
对于 Kubernetes v1.35,Windows 节点(和 Pod)的操作系统兼容性如下:
也适用 Kubernetes 版本偏差策略。
这里列出的硬件规格应被视为合理的默认值。它们并不代表生产环境的最低要求或具体推荐。根据你的工作负载要求,这些值可能需要进行调整。
有关最新的最低硬件要求信息,请参考微软文档:Windows Server 的硬件要求。有关决定生产工作节点资源的指导信息,请参考 Kubernetes 文档:生产用工作节点。
为了优化系统资源,如果图形用户界面不是必需的,最好选择一个不包含Windows 桌面体验安装选项的Windows Server 操作系统安装包,因为这种配置通常会释放更多的系统资源。
在估算 Windows 工作节点的磁盘空间时,需要注意 Windows 容器镜像通常比 Linux 容器镜像更大,单个镜像的容器大小范围从 300MB 到超过 10GB。此外,需要注意 Windows 容器中的 C: 驱动器默认呈现的虚拟剩余空间为 20GB,这不是实际的占用空间,而是使用主机上的本地存储时单个容器可以最多占用的磁盘大小。有关更多详细信息,请参见在 Windows 上运行容器 - 容器存储文档。
对 Kubernetes 集群进行故障排查的主要帮助来源应始于故障排查页面。
本节包括了一些其他特定于 Windows 的故障排查帮助。日志是解决 Kubernetes 中问题的重要元素。确保在任何时候向其他贡献者寻求故障排查协助时随附了日志信息。遵照 SIG Windows日志收集贡献指南中的指示说明。
如果你发现疑似 bug,或者你想提出功能请求,请按照SIG Windows 贡献指南 新建一个 Issue。你应该先搜索 Issue 列表,以防之前报告过这个问题,凭你对该问题的经验添加评论,并随附日志信息。Kubernetes Slack 上的 SIG Windows 频道也是一个很好的途径,可以在创建工单之前获得一些初始支持和故障排查思路。
Kubernetes 项目提供了 Windows 操作准备规范,配备了结构化的测试套件。这个套件分为两组测试:核心和扩展。每组测试都包含了针对特定场景的分类测试。它可以用来验证 Windows 和混合系统(混合了 Linux 节点)的所有功能,实现全面覆盖。
要在新创建的集群上搭建此项目,请参考项目指南中的说明。
kubeadm 工具帮助你部署 Kubernetes 集群,提供管理集群的控制平面以及运行工作负载的节点。
Kubernetes 集群 API 项目也提供了自动部署Windows 节点的方式。
有关 Windows 分发渠道的详细阐述,请参考Microsoft 文档。
有关支持模型在内的不同 Windows Server 服务渠道的信息,请参考Windows Server 服务渠道。