Kubernetes 中的 Windows 容器
Windows 应用程序构成了许多组织中运行的大部分服务和应用程序。 Windows 容器 提供了一种封装进程和打包依赖项的方法,使得对 Windows 应用程序使用 DevOps 实践和遵循云原生模式变得更加容易。
在基于 Windows 的应用程序和基于 Linux 的应用程序方面都有投入的组织不必寻找单独的编排器来管理其工作负载,从而提高了其部署的运营效率,而无论操作系统如何。
Kubernetes 中的 Windows 节点
要在 Kubernetes 中启用 Windows 容器的编排,请在现有的 Linux 集群中包含 Windows 节点。在 Kubernetes 上的 Pod 中调度 Windows 容器类似于调度基于 Linux 的容器。
为了运行 Windows 容器,您的 Kubernetes 集群必须包含多个操作系统。虽然您只能在 Linux 上运行 控制平面,但您可以部署运行 Windows 或 Linux 的工作节点。
只要操作系统是 Windows Server 2019 或 Windows Server 2022,就 支持 Windows 节点。
本文档使用术语“Windows 容器”来表示具有进程隔离的 Windows 容器。Kubernetes 不支持运行具有 Hyper-V 隔离 的 Windows 容器。
兼容性和限制
某些节点功能只有在您使用特定的 容器运行时 时才可用;其他功能在 Windows 节点上不可用,包括
- HugePages:Windows 容器不支持
- 特权容器:Windows 容器不支持。HostProcess 容器 提供了类似的功能。
- TerminationGracePeriod:需要 containerD
并非所有共享命名空间的功能都受支持。有关更多详细信息,请参阅 API 兼容性。
有关 Kubernetes 测试过的 Windows 版本的详细信息,请参阅 Windows 操作系统版本兼容性。
从 API 和 kubectl 的角度来看,Windows 容器的行为方式与基于 Linux 的容器非常相似。但是,关键功能存在一些显著差异,本节将对此进行概述。
与 Linux 的比较
关键的 Kubernetes 元素在 Windows 中的工作方式与在 Linux 中的工作方式相同。本节介绍了几个关键的工作负载抽象概念以及它们如何映射到 Windows。
Pod 是 Kubernetes 的基本构建块,是您创建或部署的 Kubernetes 对象模型中最小的、最简单的单元。您不得在同一个 Pod 中部署 Windows 和 Linux 容器。Pod 中的所有容器都被调度到单个节点上,其中每个节点代表特定的平台和架构。Windows 容器支持以下 Pod 功能、属性和事件
每个 Pod 一个或多个容器,具有进程隔离和卷共享
Pod
status
字段就绪性、活跃性和启动探针
postStart 和 preStop 容器生命周期钩子
ConfigMap、Secrets:作为环境变量或卷
emptyDir
卷命名管道主机挂载
资源限制
OS 字段
.spec.os.name
字段应设置为windows
,以指示当前 Pod 使用 Windows 容器。如果将
.spec.os.name
字段设置为windows
,则不得在该 Pod 的.spec
中设置以下字段spec.hostPID
spec.hostIPC
spec.securityContext.seLinuxOptions
spec.securityContext.seccompProfile
spec.securityContext.fsGroup
spec.securityContext.fsGroupChangePolicy
spec.securityContext.sysctls
spec.shareProcessNamespace
spec.securityContext.runAsUser
spec.securityContext.runAsGroup
spec.securityContext.supplementalGroups
spec.containers[*].securityContext.seLinuxOptions
spec.containers[*].securityContext.seccompProfile
spec.containers[*].securityContext.capabilities
spec.containers[*].securityContext.readOnlyRootFilesystem
spec.containers[*].securityContext.privileged
spec.containers[*].securityContext.allowPrivilegeEscalation
spec.containers[*].securityContext.procMount
spec.containers[*].securityContext.runAsUser
spec.containers[*].securityContext.runAsGroup
在上面的列表中,通配符 (
*
) 表示列表中的所有元素。例如,spec.containers[*].securityContext
指的是所有容器的 SecurityContext 对象。如果指定了这些字段中的任何一个,则 API 服务器将不接受该 Pod。
工作负载资源,包括
- 副本集
- Deployment
- StatefulSet
- 守护进程集
- Job
- 定时任务
- 复制控制器
Pod、工作负载资源和服务是在 Kubernetes 上管理 Windows 工作负载的关键要素。但是,仅凭它们本身不足以在动态云原生环境中实现 Windows 工作负载的正确生命周期管理。
kubectl exec
- Pod 和容器指标
- 水平 Pod 自动扩展
- 资源配额
- 调度器抢占
kubelet 的命令行选项
某些 kubelet 命令行选项在 Windows 上的行为有所不同,如下所述
--windows-priorityclass
允许您设置 kubelet 进程的调度优先级(请参阅 CPU 资源管理)--kube-reserved
、--system-reserved
和--eviction-hard
标志更新 NodeAllocatable- 未实现使用
--enforce-node-allocable
进行的驱逐 - 未实现使用
--eviction-hard
和--eviction-soft
进行的驱逐 - 在 Windows 节点上运行时,kubelet 没有内存或 CPU 限制。
--kube-reserved
和--system-reserved
仅从NodeAllocatable
中减去,不保证为工作负载提供资源。有关更多信息,请参阅 Windows 节点的资源管理。 - 未实现
MemoryPressure
条件 - kubelet 不执行 OOM 驱逐操作
API 兼容性
由于操作系统和容器运行时的原因,Kubernetes API 在 Windows 上的工作方式存在细微差异。某些工作负载属性是为 Linux 设计的,无法在 Windows 上运行。
在较高层次上,这些操作系统概念是不同的
- 身份 - Linux 使用表示为整数类型的用户 ID (UID) 和组 ID (GID)。用户名和组名不是规范的 - 它们只是
/etc/groups
或/etc/passwd
中返回到 UID+GID 的别名。Windows 使用存储在 Windows 安全访问管理器 (SAM) 数据库中的更大的二进制 安全标识符 (SID)。此数据库不在主机和容器之间或容器之间共享。 - 文件权限 - Windows 使用基于 (SID) 的访问控制列表,而 POSIX 系统(如 Linux)使用基于对象权限和 UID+GID 的位掩码,以及“可选”访问控制列表。
- 文件路径 - Windows 上的约定是使用
\
而不是/
。Go IO 库通常同时接受两者并使其正常工作,但是当您设置在容器内解释的路径或命令行时,可能需要使用\
。 - 信号 - Windows 交互式应用程序以不同的方式处理终止,并且可以实现以下一项或多项
- UI 线程处理定义良好的消息,包括
WM_CLOSE
。 - 控制台应用程序使用控制处理程序处理 Ctrl-C 或 Ctrl-break。
- 服务注册一个服务控制处理程序函数,该函数可以接受
SERVICE_CONTROL_STOP
控制代码。
- UI 线程处理定义良好的消息,包括
容器退出代码遵循相同的约定,其中 0 表示成功,非零表示失败。特定的错误代码在 Windows 和 Linux 之间可能有所不同。但是,从 Kubernetes 组件(kubelet、kube-proxy)传递的退出代码保持不变。
容器规范的字段兼容性
以下列表记录了 Pod 容器规范在 Windows 和 Linux 之间工作方式的差异
- Windows 容器运行时未实现大页面,因此不可用。它们需要声明用户权限,而该权限无法为容器配置。
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 上不可能,因为不支持 GIDsecurityContext.runAsNonRoot
- 此设置将阻止容器以ContainerAdministrator
身份运行,该身份是 Windows 上最接近 root 用户的等效身份。securityContext.runAsUser
- 改用runAsUserName
securityContext.seLinuxOptions
- 在 Windows 上不可能,因为 SELinux 是特定于 Linux 的terminationMessagePath
- 这有一些限制,因为 Windows 不支持映射单个文件。默认值为/dev/termination-log
,它确实有效,因为它默认情况下在 Windows 上不存在。
Pod 规范的字段兼容性
以下列表记录了 Pod 规范在 Windows 和 Linux 之间工作方式的差异
hostIPC
和hostpid
- 在 Windows 上不可能共享主机命名空间hostNetwork
- 见下文dnsPolicy
- 在 Windows 上不支持将 PoddnsPolicy
设置为ClusterFirstWithHostNet
,因为未提供主机网络。Pod 始终使用容器网络运行。podSecurityContext
见下文shareProcessNamespace
- 这是一项测试功能,并且依赖于 Windows 上未实现的 Linux 命名空间。Windows 无法共享进程命名空间或容器的根文件系统。只有网络可以共享。terminationGracePeriodSeconds
- 这在 Windows 上的 Docker 中未完全实现,请参阅GitHub 问题。现在的行为是向 ENTRYPOINT 进程发送 CTRL_SHUTDOWN_EVENT,然后 Windows 默认等待 5 秒,最后使用正常的 Windows 关闭行为关闭所有进程。5 秒的默认值实际上在容器内的 Windows 注册表中,因此可以在构建容器时覆盖它。volumeDevices
- 这是一项测试功能,并且未在 Windows 上实现。Windows 无法将原始块设备附加到 Pod。卷
- 如果定义
emptyDir
卷,则无法将其卷源设置为memory
。
- 如果定义
- 您无法为卷挂载启用
mountPropagation
,因为 Windows 上不支持此功能。
hostNetwork 的字段兼容性
Kubernetes v1.26 [alpha]
kubelet 现在可以请求在 Windows 节点上运行的 Pod 使用主机的网络命名空间,而不是创建新的 Pod 网络命名空间。要启用此功能,请将 --feature-gates=WindowsHostNetwork=true
传递给 kubelet。
注意
此功能需要支持此功能的容器运行时。Pod 安全上下文的字段兼容性
只有 Pod securityContext
字段中的 securityContext.runAsNonRoot
和 securityContext.windowsOptions
在 Windows 上有效。
节点问题检测器
节点问题检测器(请参阅监控节点运行状况)初步支持 Windows。有关更多信息,请访问该项目的GitHub 页面。
暂停容器
在 Kubernetes Pod 中,首先会创建一个基础架构或“暂停”容器来托管该容器。在 Linux 中,构成 Pod 的 cgroup 和命名空间需要一个进程来维持其持续存在;暂停进程提供了这一点。属于同一个 Pod 的容器(包括基础架构和工作容器)共享一个公共网络端点(相同的 IPv4 和/或 IPv6 地址,相同的网络端口空间)。Kubernetes 使用暂停容器来允许工作容器崩溃或重新启动,而不会丢失任何网络配置。
Kubernetes 维护着一个多架构镜像,其中包括对 Windows 的支持。对于 Kubernetes v1.30.0,推荐的暂停镜像为 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
ContainerD
Kubernetes v1.20 [稳定]
您可以使用ContainerD 1.4.0+ 作为运行 Windows 的 Kubernetes 节点的容器运行时。
了解如何在Windows 节点上安装 ContainerD。
注意
将 GMSA 与 containerd 一起使用以访问 Windows 网络共享时存在已知限制,这需要内核补丁。Mirantis 容器运行时
Mirantis 容器运行时 (MCR) 可作为所有 Windows Server 2019 及更高版本的容器运行时。
有关更多信息,请参阅在 Windows Server 上安装 MCR。
Windows 操作系统版本兼容性
在 Windows 节点上,适用严格的兼容性规则,其中主机操作系统版本必须与容器基础镜像操作系统版本匹配。仅完全支持容器操作系统为 Windows Server 2019 的 Windows 容器。
对于 Kubernetes v1.30,Windows 节点(和 Pod)的操作系统兼容性如下
- Windows Server LTSC 版本
- Windows Server 2019
- Windows Server 2022
- Windows Server SAC 版本
- Windows Server 版本 20H2
Kubernetes 版本偏差策略也适用。
硬件建议和注意事项
注意
此处概述的以下硬件规范应被视为合理的默认值。它们并非旨在代表生产环境的最低要求或具体建议。根据您的工作负载要求,可能需要调整这些值。- 64 位处理器,4 个或更多 CPU 内核,能够支持虚拟化
- 8GB 或更多 RAM
- 50GB 或更多可用磁盘空间
有关最低硬件要求的最新信息,请参阅Windows Server Microsoft 文档的硬件要求。有关确定生产工作节点资源的指南,请参阅生产工作节点 Kubernetes 文档。
为了优化系统资源,如果不需要图形用户界面,则最好使用排除Windows 桌面体验安装选项的 Windows Server 操作系统安装,因为此配置通常会释放更多系统资源。
在评估 Windows 工作节点的磁盘空间时,请注意 Windows 容器镜像通常比 Linux 容器镜像大,单个镜像的容器镜像大小范围从300MB 到超过 10GB。此外,请注意 Windows 容器中的 C:
驱动器表示默认情况下虚拟可用大小为 20GB,这不是实际消耗的空间,而是单个容器在主机上使用本地存储时可以增长到的磁盘大小。有关更多详细信息,请参阅Windows 上的容器 - 容器存储文档。
获取帮助和故障排除
您解决 Kubernetes 集群故障的主要帮助来源应从故障排除页面开始。
本节中包含一些特定于 Windows 的其他故障排除帮助。日志是解决 Kubernetes 中问题的重要因素。每当您向其他贡献者寻求故障排除帮助时,请务必包含它们。请按照 SIG Windows 收集日志的贡献指南中的说明进行操作。
报告问题和功能请求
如果您遇到了看似错误的问题,或者您想提出功能请求,请按照SIG Windows 贡献指南创建新问题。您应该首先搜索问题列表,以防之前报告过该问题,并对该问题发表您的经验并添加其他日志。Kubernetes Slack 上的 SIG Windows 频道也是在创建故障单之前获得一些初始支持和故障排除思路的绝佳途径。
验证 Windows 集群可操作性
Kubernetes 项目提供了一个*Windows 操作就绪*规范,并附带了一个结构化的测试套件。该套件分为两组测试,核心测试和扩展测试,每组测试都包含旨在测试特定领域的类别。它可用于验证 Windows 和混合系统(与 Linux 节点混合)的所有功能,并提供全面覆盖。
要在新创建的集群上设置项目,请参阅项目指南中的说明。
部署工具
kubeadm 工具可帮助您部署 Kubernetes 集群,提供控制平面来管理集群,以及运行工作负载的节点。
Kubernetes 集群 API项目还提供了自动部署 Windows 节点的方法。
Windows 分发渠道
有关 Windows 分发渠道的详细说明,请参阅Microsoft 文档。
有关不同 Windows Server 服务渠道(包括其支持模型)的信息,请访问Windows Server 服务渠道。
此页面上的项目指的是提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅CNCF 网站指南。
在提议添加额外第三方链接的更改之前,您应该阅读内容指南。