Kubernetes 中的 Windows 容器

Windows 应用程序在许多组织中运行的服务和应用程序中占很大一部分。 Windows 容器提供了一种封装进程和打包依赖项的方法,使其更容易使用 DevOps 实践并遵循 Windows 应用程序的云原生模式。

在 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

    Pod 是 Kubernetes 的基本构建块——你在 Kubernetes 对象模型中创建或部署的最小和最简单的单元。你可能不会在同一个 Pod 中部署 Windows 和 Linux 容器。Pod 中的所有容器都调度到单个节点上,其中每个节点代表一个特定的平台和体系结构。Windows 容器支持以下 Pod 功能、属性和事件

    • 每个 Pod 单个或多个容器,具有进程隔离和卷共享

    • Pod status 字段

    • 就绪、存活和启动探针

    • postStart & preStop 容器生命周期钩子

    • ConfigMap、Secrets:作为环境变量或卷

    • emptyDir

    • 命名管道主机挂载

    • 资源限制

    • 操作系统字段

      应将 .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
  • 服务有关更多详细信息,请参阅负载均衡和服务

Pod、工作负载资源和服务是管理 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 状况
  • kubelet 不会采取 OOM 驱逐操作

API 兼容性

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

在高层面上,这些操作系统概念是不同的

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

容器退出代码遵循相同的约定,其中 0 表示成功,非零表示失败。Windows 和 Linux 之间的特定错误代码可能有所不同。但是,从 Kubernetes 组件(kubelet、kube-proxy)传递的退出代码保持不变。

容器规范的字段兼容性

以下列表记录了 Windows 和 Linux 之间 Pod 容器规范的工作方式的差异

  • Huge Pages 未在 Windows 容器运行时中实现,并且不可用。它们需要断言用户权限,这对于容器来说是不可配置的。
  • requests.cpurequests.memory - 请求从节点可用资源中减去,因此它们可用于避免过度配置节点。但是,它们不能用于保证过度配置节点中的资源。如果操作员想要完全避免过度配置,则应将它们作为最佳实践应用于所有容器。
  • securityContext.allowPrivilegeEscalation - 在 Windows 上不可能;没有连接任何功能
  • securityContext.capabilities - Windows 上未实现 POSIX 功能
  • 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 之间 Pod 规范的工作方式的差异

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

hostNetwork 的字段兼容性

功能状态: Kubernetes v1.26 [alpha]

kubelet 现在可以请求在 Windows 节点上运行的 Pod 使用主机的网络命名空间,而不是创建新的 Pod 网络命名空间。要启用此功能,请将 --feature-gates=WindowsHostNetwork=true 传递给 kubelet。

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

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

节点问题检测器

节点问题检测器(请参阅监控节点运行状况)对 Windows 有初步支持。有关更多信息,请访问该项目的 GitHub 页面

暂停容器

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

Kubernetes 维护一个多架构镜像,其中包括对 Windows 的支持。对于 Kubernetes v1.32.0,推荐的暂停镜像是 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 [stable]

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

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

Mirantis 容器运行时

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

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

Windows 操作系统版本兼容性

在 Windows 节点上,应用严格的兼容性规则,其中主机操作系统版本必须与容器基础镜像操作系统版本匹配。仅完全支持容器操作系统为 Windows Server 2019 的 Windows 容器。

对于 Kubernetes v1.32,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 网站指南

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

上次修改时间:2024 年 9 月 13 日上午 9:33 PST:修复 Markdown 文件中的一些超链接 (e6855623c7)