--- title: Kubernetes 中 Windows 容器的调度指南 content_type: concept weight: 75 --- Windows 应用程序构成了许多组织中运行的服务和应用程序的很大一部分。 本指南将引导您完成在 Kubernetes 中配置和部署 Windows 容器的步骤。 ## 目标 * 配置一个示例 deployment 以在 Windows 节点上运行 Windows 容器 * (可选)使用组托管服务帐户(GMSA)为您的 Pod 配置 Active Directory 身份 ## 在你开始之前 * 创建一个 Kubernetes 集群,其中包括一个控制平面和 [运行 Windows 服务器的工作节点](/zh/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes/) * 重要的是要注意,对于 Linux 和 Windows 容器,在 Kubernetes 上创建和部署服务和工作负载的行为几乎相同。 与集群接口的 [kubectl 命令](/zh/docs/reference/kubectl/overview/)相同。 提供以下部分中的示例只是为了快速启动 Windows 容器的使用体验。 ## 入门:部署 Windows 容器 要在 Kubernetes 上部署 Windows 容器,您必须首先创建一个示例应用程序。 下面的示例 YAML 文件创建了一个简单的 Web 服务器应用程序。 创建一个名为 `win-webserver.yaml` 的服务规约,其内容如下: ```yaml apiVersion: v1 kind: Service metadata: name: win-webserver labels: app: win-webserver spec: ports: # the port that this service should serve on - port: 80 targetPort: 80 selector: app: win-webserver type: NodePort --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: win-webserver name: win-webserver spec: replicas: 2 selector: matchLabels: app: win-webserver template: metadata: labels: app: win-webserver name: win-webserver spec: containers: - name: windowswebserver image: mcr.microsoft.com/windows/servercore:ltsc2019 command: - powershell.exe - -command - "<#code used from https://gist.github.com/19WAS85/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='
IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; "
nodeSelector:
kubernetes.io/os: windows
```
{{< note >}}
端口映射也是支持的,但为简单起见,在此示例中容器端口 80 直接暴露给服务。
{{< /note >}}
1. 检查所有节点是否健康:
```bash
kubectl get nodes
```
1. 部署服务并观察 pod 更新:
```bash
kubectl apply -f win-webserver.yaml
kubectl get pods -o wide -w
```
正确部署服务后,两个 Pod 都标记为“Ready”。要退出 watch 命令,请按 Ctrl + C。
1. 检查部署是否成功。验证:
* Windows 节点上每个 Pod 有两个容器,使用 `docker ps`
* Linux 控制平面节点列出两个 Pod,使用 `kubectl get pods`
* 跨网络的节点到 Pod 通信,从 Linux 控制平面节点 `curl` 您的 pod IPs 的端口80,以检查 Web 服务器响应
* Pod 到 Pod 的通信,使用 docker exec 或 kubectl exec 在 Pod 之间
(以及跨主机,如果你有多个 Windows 节点)进行 ping 操作
* 服务到 Pod 的通信,从 Linux 控制平面节点和各个 Pod 中 `curl` 虚拟服务 IP
(在 `kubectl get services` 下可见)
* 服务发现,使用 Kubernetes `curl` 服务名称
[默认 DNS 后缀](/zh/docs/concepts/services-networking/dns-pod-service/#services)
* 入站连接,从 Linux 控制平面节点或集群外部的计算机 `curl` NodePort
* 出站连接,使用 kubectl exec 从 Pod 内部 curl 外部 IP
{{< note >}}
由于当前平台对 Windows 网络堆栈的限制,Windows 容器主机无法访问在其上调度的服务的 IP。只有 Windows pods 才能访问服务 IP。
{{< /note >}}
## 可观测性 {#observability}
### 抓取来自工作负载的日志
日志是可观测性的重要一环;使用日志用户可以获得对负载运行状况的洞察,
因而日志是故障排查的一个重要手法。
因为 Windows 容器中的 Windows 容器和负载与 Linux 容器的行为不同,
用户很难收集日志,因此运行状态的可见性很受限。
例如,Windows 工作负载通常被配置为将日志输出到 Windows 事件跟踪
(Event Tracing for Windows,ETW),或者将日志条目推送到应用的事件日志中。
[LogMonitor](https://github.com/microsoft/windows-container-tools/tree/master/LogMonitor)
是 Microsoft 提供的一个开源工具,是监视 Windows 容器中所配置的日志源
的推荐方式。
LogMonitor 支持监视时间日志、ETW 提供者模块以及自定义的应用日志,
并使用管道的方式将其输出到标准输出(stdout),以便 `kubectl logs