Kubernetes 中的 Windows 容器调度指南
- 配置 Deployment 样例以在 Windows 节点上运行 Windows 容器
- 在 Kubernetes 中突出 Windows 特定的功能
在你开始之前
- 创建一个 Kubernetes 集群,其中包含一个控制平面和一个
- 务必请注意,在 Kubernetes 上创建和部署服务和工作负载的行为方式与 Linux 和 Windows 容器的行为方式大致相同。 与集群交互的 kubectl 命令是一致的。 下一小节的示例旨在帮助你快速开始使用 Windows 容器。
以下示例 YAML 文件部署了一个在 Windows 容器内运行的简单 Web 服务器的应用程序。
创建一个名为 的 Service 规约,其内容如下:
说明:
端口映射也是支持的,但为简单起见,此示例将容器的端口 80 直接暴露给服务。
检查所有节点是否健康
kubectl get nodes
部署 Service 并监视 Pod 更新:
当 Service 被正确部署时,两个 Pod 都被标记为就绪(Ready)。要退出 watch 命令,请按 Ctrl+C。
检查部署是否成功。请验证:
- 使用
kubectl get pods
从 Linux 控制平面节点能够列出两个 Pod - 跨网络的节点到 Pod 通信,从 Linux 控制平面节点上执行
curl
访问 Pod IP 的 80 端口以检查 Web 服务器响应 - Pod 间通信,使用 docker exec 或 kubectl exec 在 Pod 之间(以及跨主机,如果你有多个 Windows 节点)互 ping
- Service 到 Pod 的通信,在 Linux 控制平面节点以及独立的 Pod 中执行
curl
访问虚拟的服务 IP(在kubectl get services
下查看) - 服务发现,使用 Kubernetes 的服务名称, 用
curl
访问服务名称 - 入站连接,在 Linux 控制平面节点或集群外的机器上执行
curl
来访问 NodePort 服务
- 使用
说明:
可观察性
日志是可观察性的重要元素;它们使用户能够深入了解工作负载的运行情况,并且是解决问题的关键因素。 由于 Windows 容器和 Windows 容器中的工作负载与 Linux 容器的行为不同,因此用户很难收集日志,从而限制了操作可见性。 例如,Windows 工作负载通常配置为记录到 ETW(Windows 事件跟踪)或向应用程序事件日志推送条目。 是一个微软开源的工具,是监视 Windows 容器内所配置的日志源的推荐方法。 LogMonitor 支持监视事件日志、ETW 提供程序和自定义应用程序日志,将它们传送到 STDOUT 以供 kubectl logs <pod>
使用。
按照 LogMonitor GitHub 页面中的说明,将其二进制文件和配置文件复制到所有容器, 并为 LogMonitor 添加必要的入口点以将日志推送到标准输出(STDOUT)。
使用可配置的容器用户名
Windows 容器可以配置为使用不同于镜像默认值的用户名来运行其入口点和进程。 了解更多信息。
Windows 容器工作负载可以配置为使用组托管服务帐户(Group Managed Service Accounts,GMSA)。 组托管服务帐户是一种特定类型的活动目录(Active Directory)帐户,可提供自动密码管理、 简化的服务主体名称(Service Principal Name,SPN)管理,以及将管理委派给多个服务器上的其他管理员的能力。 配置了 GMSA 的容器可以携带使用 GMSA 配置的身份访问外部活动目录域资源。 在此处了解有关为 Windows 容器配置和使用 GMSA 的更多信息。
污点和容忍度
用户需要使用某种污点(Taint)和节点选择器的组合,以便将 Linux 和 Windows 工作负载各自调度到特定操作系统的节点。 下面概述了推荐的方法,其主要目标之一是该方法不应破坏现有 Linux 工作负载的兼容性。
如果启用了 IdentifyPodOS
特性门控, 你可以(并且应该)将 Pod 的 .spec.os.name
设置为该 Pod 中的容器设计所用于的操作系统。 对于运行 Linux 容器的 Pod,将 .spec.os.name
设置为 linux
。 对于运行 Windows 容器的 Pod,将 .spec.os.name
设置为 Windows
。
说明:
从 1.24 开始,IdentifyPodOS
特性处于 Beta 阶段,默认启用。
调度器在将 Pod 分配到节点时并不使用 .spec.os.name
的值。 你应该使用正常的 Kubernetes 机制, 以确保集群的控制平面将 Pod 放置到运行适当操作系统的节点上。
确保特定于操作系统的工作负载落到合适的容器主机上
用户可以使用污点(Taint)和容忍度(Toleration)确保将 Windows 容器调度至合适的主机上。 现在,所有的 Kubernetes 节点都有以下默认标签:
- kubernetes.io/os = [windows|linux]
- kubernetes.io/arch = [amd64|arm64|…]
如果 Pod 规约没有指定像 "kubernetes.io/os": windows
这样的 nodeSelector, 则 Pod 可以被调度到任何主机上,Windows 或 Linux。 这可能会有问题,因为 Windows 容器只能在 Windows 上运行,而 Linux 容器只能在 Linux 上运行。 最佳实践是使用 nodeSelector。
但是,我们了解到,在许多情况下,用户已经预先存在大量 Linux 容器部署, 以及现成配置的生态系统,例如社区中的 Helm Chart 包和程序化的 Pod 生成案例,例如 Operator。 在这些情况下,你可能不愿更改配置来添加节点选择器。 另一种方法是使用污点。因为 kubelet 可以在注册过程中设置污点, 所以可以很容易地修改为,当只能在 Windows 上运行时,自动添加污点。
例如:--register-with-taints='os=windows:NoSchedule'
通过向所有 Windows 节点添加污点,任何负载都不会被调度到这些节点上(包括现有的 Linux Pod)。 为了在 Windows 节点上调度 Windows Pod,它需要 nodeSelector 和匹配合适的容忍度来选择 Windows。
nodeSelector:
kubernetes.io/os: windows
node.kubernetes.io/windows-build: '10.0.17763'
tolerations:
operator: "Equal"
value: "windows"
effect: "NoSchedule"
每个 Pod 使用的 Windows Server 版本必须与节点的版本匹配。 如果要在同一个集群中使用多个 Windows Server 版本,则应设置额外的节点标签和节点选择器。
Kubernetes 1.17 自动添加了一个新标签 node.kubernetes.io/windows-build
来简化这一点。 如果你运行的是旧版本,则建议手动将此标签添加到 Windows 节点。
此标签反映了需要匹配以实现兼容性的 Windows 主要、次要和内部版本号。 以下是目前用于每个 Windows Server 版本的值。
使用 RuntimeClass 进行简化
RuntimeClass 可用于简化使用污点和容忍度的流程。 集群管理员可以创建一个用于封装这些污点和容忍度的 RuntimeClass
对象。
- 将此文件保存到
runtimeClasses.yml
。它包括针对 Windows 操作系统、架构和版本的nodeSelector
。
- 以集群管理员身份运行
kubectl create -f runtimeClasses.yml
- 根据情况,向 Pod 规约中添加
runtimeClassName: windows-2019
apiVersion: apps/v1
kind: Deployment
metadata:
name: iis-2019
labels:
app: iis-2019
spec:
replicas: 1
template:
metadata:
name: iis-2019
labels:
app: iis-2019
runtimeClassName: windows-2019
- name: iis
image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
resources:
limits:
cpu: 1
memory: 800Mi
requests:
cpu: .1
memory: 300Mi
ports:
- containerPort: 80
selector:
matchLabels:
app: iis-2019
---
apiVersion: v1
kind: Service
metadata:
name: iis
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 80
app: iis-2019