Kubernetes 中的 Windows 容器

Windows 应用程序在许多组织中占据了相当一部分运行的服务和应用程序。Windows 容器提供了一种封装进程和打包依赖项的方式,使得为 Windows 应用程序采用 DevOps 实践和遵循云原生模式变得更加容易。

投资于基于 Windows 和基于 Linux 应用程序的组织无需寻找单独的编排器来管理其工作负载,从而提高跨部署的运营效率,而无论操作系统如何。

Kubernetes 中的 Windows 节点

要在 Kubernetes 中启用 Windows 容器的编排,请将 Windows 节点添加到现有的 Linux 集群中。在 Kubernetes 的 Pods 中调度 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 Containers 提供类似的功能。
  • TerminationGracePeriod: 需要 containerD

并非所有共享命名空间的特性都受到支持。有关更多详细信息,请参阅 API 兼容性

有关 Kubernetes 测试所用的 Windows 版本的详细信息,请参阅 Windows OS 版本兼容性

从 API 和 kubectl 的角度来看,Windows 容器的行为与基于 Linux 的容器基本相同。然而,关键功能存在一些显著差异,本节对此进行了概述。

与 Linux 的比较

核心的 Kubernetes 元素在 Windows 中的工作方式与在 Linux 中相同。本节介绍了几个关键的工作负载抽象以及它们如何映射到 Windows。

  • Pod

    Pod 是 Kubernetes 的基本构建单元——在 Kubernetes 对象模型中创建或部署的最小、最简单的单元。你不能在同一个 Pod 中部署 Windows 和 Linux 容器。Pod 中的所有容器都被调度到单个 Node 上,其中每个 Node 代表一个特定的平台和架构。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。

  • 工作负载资源包括

    • ReplicaSet
    • Deployment
    • StatefulSet
    • DaemonSet
    • Job
    • CronJob
    • ReplicationController
  • Service 有关更多详细信息,请参阅 负载均衡和 Service

Pods、工作负载资源和 Service 是在 Kubernetes 上管理 Windows 工作负载的关键要素。然而,仅凭它们自身不足以在动态的云原生环境中实现 Windows 工作负载的适当生命周期管理。

kubelet 的命令行选项

一些 kubelet 命令行选项在 Windows 上的行为不同,如下所述

  • --windows-priorityclass 允许你设置 kubelet 进程的调度优先级(参见 CPU 资源管理
  • --kube-reserved--system-reserved--eviction-hard 标志会更新 NodeAllocatable
  • 使用 --enforce-node-allocable 进行的驱逐尚未实现
  • 当在 Windows 节点上运行时,kubelet 没有内存或 CPU 限制。--kube-reserved--system-reserved 仅从 NodeAllocatable 中减去,不保证为工作负载提供资源。有关更多信息,请参阅 Windows 节点的资源管理
  • PIDPressure Condition 尚未实现
  • kubelet 不会采取 OOM 驱逐操作

API 兼容性

由于操作系统和容器运行时,Kubernetes API 在 Windows 上的工作方式存在细微差别。一些工作负载属性是为 Linux 设计的,因此无法在 Windows 上运行。

在较高层面,这些操作系统概念有所不同

  • 身份 - Linux 使用以整数类型表示的 userID (UID) 和 groupID (GID)。用户和组名不是规范的,它们只是 /etc/groups/etc/passwd 中 UID+GID 的别名。Windows 使用更大的二进制 安全标识符 (SID),该标识符存储在 Windows Security Access Manager (SAM) 数据库中。此数据库不在主机与容器之间或容器之间共享。
  • 文件权限 - Windows 使用基于 SID 的访问控制列表,而 POSIX 系统(如 Linux)使用基于对象权限和 UID+GID 的位掩码,以及可选的访问控制列表。
  • 文件路径 - Windows 上的约定是使用 \ 而不是 /。Go IO 库通常两者都接受,并且能够正常工作,但是当你设置在容器内部解释的路径或命令行时,可能需要使用 \
  • 信号 - Windows 交互式应用程序处理终止的方式不同,可以实现以下一项或多项
    • UI 线程处理包括 WM_CLOSE 在内的定义良好的消息。
    • 控制台应用程序使用 Control Handler 处理 Ctrl-C 或 Ctrl-break。
    • 服务注册一个 Service Control Handler 函数,该函数可以接受 SERVICE_CONTROL_STOP 控制码。

容器退出码遵循相同的约定:0 表示成功,非零表示失败。具体的错误码在 Windows 和 Linux 上可能有所不同。然而,从 Kubernetes 组件(kubelet、kube-proxy)传递的退出码是保持不变的。

容器规格的字段兼容性

以下列表记录了 Pod 容器规格在 Windows 和 Linux 上的工作方式差异

  • Huge pages 未在 Windows 容器运行时中实现,因此不可用。它们需要声明 用户特权,但这对于容器来说是不可配置的。
  • requests.cpurequests.memory - requests 从节点可用资源中扣除,因此可用于避免节点超量分配。但是,它们不能用于保证在超量分配的节点中的资源。如果操作员希望完全避免超量分配,应将其作为最佳实践应用于所有容器。
  • securityContext.allowPrivilegeEscalation - 在 Windows 上不可能;没有相关的能力挂钩
  • securityContext.capabilities - POSIX 能力未在 Windows 上实现
  • securityContext.privileged - Windows 不支持特权容器,请改用 HostProcess Containers
  • securityContext.procMount - Windows 没有 /proc 文件系统
  • securityContext.readOnlyRootFilesystem - 在 Windows 上不可能;注册表和系统进程需要在容器内运行,需要写入访问权限
  • securityContext.runAsGroup - 在 Windows 上不可能,因为不支持 GID
  • securityContext.runAsNonRoot - 此设置将阻止容器以 ContainerAdministrator 身份运行,ContainerAdministrator 是 Windows 上最接近 root 用户的等效身份。
  • securityContext.runAsUser - 请改用 runAsUserName
  • securityContext.seLinuxOptions - 在 Windows 上不可能,因为 SELinux 是 Linux 特有的
  • terminationMessagePath - 这有一些限制,因为 Windows 不支持映射单个文件。默认值为 /dev/termination-log,它确实有效,因为它在 Windows 上默认不存在。

Pod 规格的字段兼容性

以下列表记录了 Pod 规格在 Windows 和 Linux 上的工作方式差异

  • hostIPChostpid - Windows 不支持主机命名空间共享
  • hostNetwork - Windows 不支持主机网络
  • dnsPolicy - 在 Windows 上不支持将 Pod 的 dnsPolicy 设置为 ClusterFirstWithHostNet,因为没有提供主机网络。Pod 总是使用容器网络运行。
  • podSecurityContext 参见下文
  • shareProcessNamespace - 这是一个 beta 特性,并且依赖于未在 Windows 上实现的 Linux 命名空间。Windows 不能共享进程命名空间或容器的根文件系统。只有网络可以共享。
  • terminationGracePeriodSeconds - 这在 Windows 上的 Docker 中尚未完全实现,参见 GitHub Issue。目前的行为是向 ENTRYPOINT 进程发送 CTRL_SHUTDOWN_EVENT,然后 Windows 默认等待 5 秒,最后使用正常的 Windows 关闭行为关闭所有进程。默认的 5 秒实际上在 容器内的 Windows 注册表中,因此在构建容器时可以覆盖它。
  • volumeDevices - 这是一个 beta 特性,未在 Windows 上实现。Windows 不能将原始块设备附加到 Pod。
  • volumes
    • 如果定义了 emptyDir 卷,则不能将其卷源设置为 memory
  • 不能对卷挂载启用 mountPropagation,因为 Windows 不支持此功能。

主机网络访问

Kubernetes v1.26 到 v1.32 包含了在主机网络命名空间中运行 Windows Pods 的 alpha 支持。

Kubernetes v1.33 包含 WindowsHostNetwork 特性门控,也不支持在主机网络命名空间中运行 Windows Pods。

Pod 安全上下文的字段兼容性

Pod securityContext 字段中只有 securityContext.runAsNonRootsecurityContext.windowsOptions 在 Windows 上起作用。

节点问题检测器

节点问题检测器(参见 监控节点健康)对 Windows 有初步支持。有关更多信息,请访问项目的 GitHub 页面

Pause 容器

在 Kubernetes Pod 中,首先创建一个基础设施容器或“pause”容器来托管容器。在 Linux 中,构成 Pod 的 cgroups 和命名空间需要一个进程来维持其持续存在;pause 进程提供了这一点。属于同一 Pod 的容器,包括基础设施容器和工作容器,共享一个通用的网络端点(相同的 IPv4 和/或 IPv6 地址,相同的网络端口空间)。Kubernetes 使用 pause 容器来允许工作容器崩溃或重启而不会丢失任何网络配置。

Kubernetes 维护一个包含 Windows 支持的多架构镜像。对于 Kubernetes v1.33.0,推荐的 pause 镜像为 registry.k8s.io/pause:3.6源代码可在 GitHub 上获取。

Microsoft 维护一个不同的多架构镜像,支持 Linux 和 Windows amd64,可在 mcr.microsoft.com/oss/kubernetes/pause:3.6 找到。此镜像与 Kubernetes 维护的镜像源相同,但所有 Windows 二进制文件均由 Microsoft 进行 authenticode 签名。如果你要部署到需要签名二进制文件的生产或类似生产环境,Kubernetes 项目建议使用 Microsoft 维护的镜像。

容器运行时

你需要在集群中的每个节点安装容器运行时,以便 Pod 可以在那里运行。

以下容器运行时支持 Windows

ContainerD

特性状态: Kubernetes v1.20 [稳定]

你可以使用 ContainerD 1.4.0+ 作为运行 Windows 的 Kubernetes 节点的容器运行时。

了解如何在 Windows 节点上安装 ContainerD

Mirantis Container Runtime

Mirantis Container Runtime (MCR) 可用作所有 Windows Server 2019 及更高版本的容器运行时。

有关更多信息,请参阅 在 Windows Server 上安装 MCR

Windows OS 版本兼容性

在 Windows 节点上,适用严格的兼容性规则,要求主机操作系统版本必须与容器基础镜像操作系统版本匹配。只有容器操作系统为 Windows Server 2019 的 Windows 容器才完全受支持。

对于 Kubernetes v1.33,Windows 节点(和 Pods)的操作系统兼容性如下

Windows Server LTSC 版本
Windows Server 2019
Windows Server 2022
Windows Server SAC 版本
Windows Server version 20H2

Kubernetes 版本偏差策略 也适用。

硬件建议和注意事项

  • 64 位处理器,4 个或更多 CPU 核,支持虚拟化
  • 8GB 或更多内存
  • 50GB 或更多可用磁盘空间

有关最低硬件要求的最新信息,请参阅 Microsoft 文档中的 Windows Server 硬件要求。有关为生产工作节点确定资源的指导,请参阅 Kubernetes 文档中的 生产工作节点

为了优化系统资源,如果不需要图形用户界面,可能更倾向于使用不包含 Windows Desktop Experience 安装选项的 Windows Server 操作系统安装,因为此配置通常会释放更多系统资源。

评估 Windows 工作节点的磁盘空间时,请注意 Windows 容器镜像通常比 Linux 容器镜像大,单个容器镜像大小从 300MB 到 10GB 以上不等。此外,请注意,Windows 容器中的 C: 驱动器默认表示虚拟可用空间 20GB,这不是实际消耗的空间,而是单个容器在使用主机上的本地存储时可以增长占用的磁盘大小。有关更多详细信息,请参阅 Windows 上的容器 - 容器存储文档

获取帮助和故障排除

解决 Kubernetes 集群故障的主要帮助来源应从 故障排除 页面开始。

本节包含一些额外的、针对 Windows 的故障排除帮助。日志是解决 Kubernetes 问题的重要元素。在寻求其他贡献者帮助解决故障时,请务必包含日志。请按照 SIG Windows 贡献指南中关于收集日志的说明进行操作。

报告问题和特性请求

如果你发现了一个看似 Bug 的问题,或者你想提出特性请求,请按照 SIG Windows 贡献指南 创建一个新问题。你应该首先搜索问题列表,以防之前已有人报告过该问题,并在该问题上评论你的经验并添加额外日志。Kubernetes Slack 上的 SIG Windows 频道也是在创建工单之前获得初步支持和故障排除想法的好途径。

验证 Windows 集群可操作性

Kubernetes 项目提供了一份 Windows 操作就绪规范,并附带了一套结构化的测试套件。该套件分为两组测试,核心和扩展,每组都包含旨在测试特定领域的类别。它可用于全面覆盖验证 Windows 系统和混合系统(与 Linux 节点混合)的所有功能。

要在新创建的集群上设置项目,请参阅 项目指南 中的说明。

部署工具

kubeadm 工具帮助你部署 Kubernetes 集群,提供控制平面来管理集群及其运行工作负载的节点。

Kubernetes cluster API 项目也提供了自动化部署 Windows 节点的方法。

Windows 分发渠道

有关 Windows 分发渠道的详细说明,请参阅 Microsoft 文档

有关不同 Windows Server 服务通道(包括其支持模型)的信息,请参阅 Windows Server 服务通道

此页面上的项目引用了提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南

在提出添加额外第三方链接的变更之前,应阅读 内容指南

最后修改于 2025 年 4 月 8 日下午 11:32 PST:移除 v1.33 的 Windows hostNetwork 支持文档 (#49905) (9e160e87b4)