Kubernetes v1.13 版本的文档已不再维护。您现在看到的版本来自于一份静态的快照。如需查阅最新文档,请点击 最新版本。

Edit This Page

在 Kubernetes 中使用 Windows Server 容器

Note: Note: 这些说明最近基于 Windows Server 平台增强和 Kubernetes v1.9 版本进行了更新

Kubernetes 1.5 版本基于 Windows Server 2016 操作系统引入了对 Windows Server 容器 的 Alpha 支持。随着 Windows Server 版本 1709 的发布和使用 Kubernetes v1.9,用户可以使用许多不同的 网络拓扑和 CNI 插件在本地或私有/公共云中部署 Kubernetes 集群。Kubernetes 上的 Windows Server 容器的一些 关键功能改进包括:

Kubernetes 控制平面(API服务器,调度程序,控制器管理器等)继续在 Linux 上运行,而 kubelet 和 kube-proxy 可以在 Windows Server 2016 或更高版本上运行

Note: Note: Kubernetes 上的 Windows Server 容器是 Kubernetes v1.9 中的一个 Beta 特性

获取 Windows 二进制文件

我们建议使用可以在 https://github.com/kubernetes/kubernetes/releases/latest 上找到的发布的二进制文件。在更新日志下您可以找到 Windows-amd64 的节点二进制文件链接,其中包括 kubeadm,kubectl,kubelet 和 kube-proxy。

如果您希望自己构建代码,请参阅此处的详细构建说明。

环境准备

在 Kubernetes 1.9 或更高版本中,使用以下内容支持 Kubernetes 的 Windows Server 容器:

  1. Kubernetes 控制平面在现有的 Linux 基础架构(1.9版本或更高版本)上运行。 <!–
  2. Kubernetes control plane running on existing Linux infrastructure (version 1.9 or later). –>
  3. Linux 的节点上的 Kubenet 网络插件设置。 <!–
  4. Kubenet network plugin setup on the Linux nodes. –>
  5. Windows Server 2016 RTM 或更高版本,Windows Server 版本 1709 或更高版本是首选; 它解锁了共享网络命名空间等关键功能。 <!–
  6. Windows Server 2016 RTM or later. Windows Server version 1709 or later is preferred; it unlocks key capabilities like shared network namespace. –>
  7. 适用于 Windows Server 节点的 Docker 版本 17.06.1-ee-2 或更高版本(Linux 节点和 Kubernetes 控制平面可以运行任何 Kubernetes 支持的 Docker 版本)。 <!–
  8. Docker Version 17.06.1-ee-2 or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). –>

网络

Windows 上有几种支持 Kubernetes v1.9 的网络配置,包括使用第三方网络插件的第三层路由和覆盖拓扑。

  1. 上游 L3 路由 - 在上游 ToR 中配置的 IP 路由 <!–
  2. Upstream L3 Routing - IP routes configured in upstream ToR –>
  3. 主机网关 - 在每台主机上配置的 IP 路由 <!–
  4. Host-Gateway - IP routes configured on each host –>
  5. 使用覆盖式 Open vSwitch(OVS) 和开放虚拟网络(OVN) - 覆盖网络(支持STT和Geneve隧道类型) <!–
  6. Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay - overlay networks (supports STT and Geneve tunneling types) –>
  7. [未来 - 评审中] 覆盖 - 使用 Flannel 的 VXLAN 或者 IP-in-IP 封装 <!–
  8. [Future - In Review] Overlay - VXLAN or IP-in-IP encapsulation using Flannel –>
  9. [未来] 使用 BGP(Calico) 的第三层路由 <!–
  10. [Future] Layer-3 Routing with BGP (Calico) –>

选择要部署的网络配置和拓扑取决于物理网络拓扑和用户配置路由的能力,封装的性能问题以及与第三方网络插件集成的要求。

未来的 CNI 插件

另外两个 CNI 插件 [win-l2bridge(主机网关)和 win-overlay(vxlan)] 正在进行 PR 审核。这两个 CNI 插件准备好后,既可以直接使用,也可以与 Flannel 一起使用。

Linux

Linux 上已经使用桥接接口支持上述网络方法,桥接接口基本上创建了节点本地的专用网络。与 Windows 端类似,必须创建到所有其他 pod CIDR 的路由才能通过”公共” NIC 发送数据包。

Windows

Windows 支持 CNI 网络模型,并使用插件与 Windows 主机网络服务(HNS)连接以配置主机网络和策略。在撰写本文时,Microsoft 唯一公开提供的 CNI 插件是从私人存储库构建的,可在此处获得wincni.exe。它使用由管理员在每个节点上使用 HNS PowerShell 命令通过 Windows 主机网络服务(HNS)创建的 l2bridge 网络,如下面的 Windows 主机设置部分所述。未来CNI插件的源代码将公开发布

上游 L3 路由拓扑

在这种拓扑结构中,通过在机架 (ToR)交换机/路由器的上游顶部配置静态 IP 路由,使用L3路由实现网络连接。每个群集节点都通过主机 IP 连接到管理网络。此外,每个节点使用本地’l2bridge’网络,并分配了一个 pod CIDR。给定工作节点上的所有 pod 将连接到 pod CIDR 子网(‘l2bridge’网络)。为了在不同节点上运行的 pod 之间实现网络通信,上游路由器配置了静态路由 pod CIDR 前缀 => 主机 IP。

以下示例图说明了使用上游 L3 路由设置的 Kubernetes 的 Windows Server 网络设置:

K8s 集群使用 ToR 的 L3 路由

主机网关拓扑

这种拓扑与上游 L3 路由拓扑相似,惟一的区别是静态 IP 路由是直接在每个集群节点上配置的,而不是在上游 ToR 中配置的。每个节点使用本地的 ‘l2bridge’ 网络,并像以前一样分配 pod CIDR,并为分配给远程集群节点的所有其他 pod CIDR 子网提供路由表条目。

OVN 和 OVS 一起使用

下图概述了组件之间的体系结构和交互:

覆盖式使用 OVN 控制器和 OVS 开关扩展

(上图来自 https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram)

由于它的体系结构,OVN 有一个中央组件,它将您的网络意图存储在数据库中。其他组件如 kube-apiserver、kube-controller-manager、kube-scheduler 等也可以部署在该中心节点上。

在 Kubernetes 上设置 Windows Server 容器

要在 Kubernetes 上运行 Windows Server 容器,您需要为 Windows 设置主机和 Kubernetes 节点组件。根据您的网络拓扑,可能需要为不同节点上的 pod 通信设置路由。

主机设置

1. 上游 L3 路由拓扑和 2. 主机网关拓扑

Linux 主机设置
  1. Linux 主机应该根据它们各自的发行版文档和您将使用的 Kubernetes 版本的要求进行设置。 <!–
  2. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. –>
  3. 使用步骤此处配置Linux主节点 <!–
  4. Configure Linux Master node using steps here –>
  5. [可选]安装CNI网络插件。 <!–
  6. [Optional] CNI network plugin installed. –>
Windows 主机设置
  1. 运行所需 Windows Server 和 Docker 版本的 Windows Server 容器主机。请按照此帮助主题概述的安装说明进行操作:https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server。 <!–
  2. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. –>
  3. 2. 获取 Windows 二进制文件 kubelet.exe, kube-proxy.exe, and kubectl.exe 使用说明 <!–
  4. Get Windows Binaries kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions –>
  5. 使用 X.509 密钥从 Linux 主节点复制节点规范文件(kube config) <!–
  6. Copy Node spec file (kube config) from Linux master node with X.509 keys –>
  7. 创建 HNS 网络,确保正确的 CNI 网络配置,并使用此脚本 start-kubelet.ps1 启动 kubelet.exe <!–
  8. Create the HNS Network, ensure the correct CNI network config, and start kubelet.exe using this script start-kubelet.ps1 –>
  9. 使用此脚本启动 start-kubeproxy.ps1 启动 kube-proxy
  10. [仅限 #2 主机网关模式]使用此脚本 AddRoutes.ps1 在Windows主机上添加静态路由 <!–
  11. [Only required for #2 Host-Gateway mode] Add static routes on Windows host using this script AddRoutes.ps1 –> 更详细的说明可以在这里找到。

Windows CNI 配置示例

Windows CNI 插件基于 wincni.exe 的,配置文件,是基于上面显示的 ToR 示例图,指定了应用于 Windows node-1 的配置。特别有趣的是 Windows node-1 pod CIDR(10.10.187.64/26) 和 cbr0(10.10.187.66)的关联网关。异常列表指定服务 CIDR(11.0.0.0/8),集群 CIDR(10.10.0.0/16) 和管理(或主机) CIDR(10.127.132.128/25)。

注意:此文件假设用户以前使用 -HNSNetworkcmdlet 在每个 Windows 节点上创建了’l2bridge’ 主机网络,如上面链接的 start-kubelet.ps1 和 start-kubeproxy.ps1 脚本中所示

{
	"cniVersion": "0.2.0",
	"name": "l2bridge",
	"type": "wincni.exe",
	"master": "Ethernet",
	"ipam": {
		"environment": "azure",
		"subnet": "10.10.187.64/26",
		"routes": [{
			"GW": "10.10.187.66"
		}]
	},
	"dns": {
		"Nameservers": [
			"11.0.0.10"
		]
	},
	"AdditionalArgs": [{
			"Name": "EndpointPolicy",
			"Value": {
				"Type": "OutBoundNAT",
				"ExceptionList": [
					"11.0.0.0/8",
					"10.10.0.0/16",
					"10.127.132.128/25"
				]
			}
		},
		{
			"Name": "EndpointPolicy",
			"Value": {
				"Type": "ROUTE",
				"DestinationPrefix": "11.0.0.0/8",
				"NeedEncap": true
			}
		},
		{
			"Name": "EndpointPolicy",
			"Value": {
				"Type": "ROUTE",
				"DestinationPrefix": "10.127.132.213/32",
				"NeedEncap": true
			}
		}
	]
}

3.使用覆盖方式打开 vSwitch(OVS) 和开放虚拟网络(OVN)

Note: Note: 通过 Ansible 剧本的全自动设置是可用的

对于手动设置,请继续以下步骤。

Linux 主机设置

设置中心节点和所需组件超出了本文档的范围。您可以阅读这些说明

添加 Linux minion 也超出了范围,你可以在这里阅读:Linux minion

windows 主机设置

添加 Windows minion 需要您安装 OVS 和 OVN 二进制文件。运行所需 Windows Server 和 Docker 版本的 Windows Server 容器主机。请按照此帮助主题概述的设置说明进行操作。从 Windows Server 2016 RTM 开始支持此类部署。

编译 OVS 并生成安装程序不在本文中讨论。请访问此链接。对于预构建的认证安装程序,请访问此链接并下载最新版本

以下指南使用预构建的认证安装程序。

安装 OVS 既可以通过 GUI 对话框完成,也可以在无人看管的情况下完成。将 Windows 主机添加到您的设置需要您拥有OVN主机和默认安装特性。下面是需要安装的对话框图像:

Windows 安装 OVN OVS

对于无人看管情况下的安装,请使用以下命令:

cmd /c 'msiexec /i openvswitch.msi ADDLOCAL="OpenvSwitchCLI,OpenvSwitchDriver,OVNHost" /qn'

安装程序设置新的环境变量。请使用命令打开一个新的 shell 或注销/登录,以确保刷新了环境变量。

对于叠加,Windows 上的 OVS 需要透明的 docker 网络才能正常运行。请使用以下命令创建一个透明的 docker 网络,OVS 将使用该网络。powershell:

docker network create -d transparent --gateway $GATEWAY_IP --subnet $SUBNET `
    -o com.docker.network.windowsshim.interface="$INTERFACE_ALIAS" external

$SUBNET 是用于产生 pods 的 minion 子网(将由 kubernetes 使用的子网),$GATEWAY_IP 是 $SUBNET 的第一个 IP,$INTERFACE_ALIAS 是用于创建覆盖隧道的接口(必须与 OVN 主机的 rests 连接)。 例:

docker network create -d transparent --gateway 10.0.1.1 --subnet 10.0.1.0/24 `
    -o com.docker.network.windowsshim.interface="Ethernet0" external

创建 docker 网络后,请从 powershell 运行下面的命令。(创建OVS桥接器,在桥接器下添加接口,并启用OVS转发交换机扩展名)

$a = Get-NetAdapter | where Name -Match HNSTransparent
Rename-NetAdapter $a[0].Name -NewName HNSTransparent
Stop-Service ovs-vswitchd -force; Disable-VMSwitchExtension "Cloudbase Open vSwitch Extension";
ovs-vsctl --no-wait del-br br-ex
ovs-vsctl --no-wait --may-exist add-br br-ex
ovs-vsctl --no-wait add-port br-ex HNSTransparent -- set interface HNSTransparent type=internal
ovs-vsctl --no-wait add-port br-ex $INTERFACE_ALIAS
Enable-VMSwitchExtension "Cloudbase Open vSwitch Extension"; sleep 2; Restart-Service ovs-vswitchd

除此之外,Windows主机的设置与Linux主机相同。从这里开始执行以下步骤。

Windows CNI 设置

现在,Windows OVN&OVS CNI 插件是基于 ovn_cni.exe 可以从此处下载。CNI 配置文件示例如下:

{
    "name": "net",
    "type": "ovn_cni.exe",
    "bridge": "br-int",
    "isGateway": "true",
    "ipMasq": "false",
    "ipam": {
         "type": "host-local",
         "subnet": "$SUBNET"
         }
}

$SUBNET 是上一个 docker network create 命令中使用的子网。

有关谷歌云平台(GCP),即谷歌计算引擎(GCE)的完整指南,请访问这里

有关亚马逊网络服务(AWS),请访问这里

启动群集

要启动集群,您需要启动基于 Linux 的 Kubernetes 控制平面和基于 Windows Server 的 Kubernetes 节点组件(kubelet 和 kube-proxy)。对于 OVS 和 OVN,仅需要 kubelet。

启动基于 Linux-based 的控制平面

使用您喜欢的方法在 Linux 上启动 Kubernetes 集群。请注意,集群 CIDR 可能需要更新。

支持kubeadm加入

如果您的群集是由kubeadm,创建的 使用上面列出的方法之一正确地设置网络(网络是在 kubeadm 之外设置的),您可以使用 kubeadm 向集群添加 Windows 节点。在较高的级别上,首先必须使用 kubeadm(Linux) 初始化主节点,然后设置基于 CNI 的网络(在 kubeadm 之外),最后开始将 Windows 或 Linux 工作节点连接到集群。如需其他文件和参考资料,请访问上文的 kubeadm 链接。

kubeadm 二进制文件可以在 Kubernetes 版本的节点二进制文件归档中找到。添加 Windows 节点与添加 Linux 节点没有任何不同:

kubeadm.exe join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>

有关更多详细信息请参阅加入您的节点

支持的功能

下面列出的示例假设在 Windows Server 1709 上运行 Windows 节点。如果您正在运行 Windows Server 2016,示例将需要更新镜像以指定 image: microsoft/windowsservercore:ltsc2016。这是因为在使用进程隔离时,需要容器镜像匹配主机操作系统版本。不指定标记将隐式地使用 :latest 标记,这可能导致令人惊讶的行为。有关 Windows Service Core 镜像标记的更多信息,请与https://hub.docker.com/r/microsoft/windowsservercore/联系。

在 Windows 上调度 Pod

由于您的群集同时具有 Linux 和 Windows 节点,因此必须明确设置 nodeSelector 约束以便能够将 pod 安排到 Windows 节点。必须将 nodeSelector 的标签 beta.kubernetes.io/os 设置为值 windows; 请参阅以下示例:

windows/simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: iis
  labels:
    name: iis
spec:
  containers:
    - name: iis
      image: microsoft/iis:windowsservercore-1709
      ports:
        - containerPort: 80
  nodeSelector:
    "beta.kubernetes.io/os": windows
Note: Note: 本例假设您在 Windows Server 1709 上运行,因此使用镜像标记来支持它。如果使用不同的版本,则需要更新标记。例如,如果在 Windows Server 2016 上,更新为使用 "image": "microsoft/iis",默认为该操作系统版本。

Secrets 和 ConfigMaps

secret和configmap可以在Windows Service 容器中使用,但是必须作为环境变量使用。有关更多细节,请参见下面的限制部分。

例子:

Windows pod 与 secrets 映射到环境变量

windows/secret-pod.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

---

apiVersion: v1
kind: Pod
metadata:
  name: my-secret-pod
spec:
  containers:
  - name: my-secret-pod
    image: microsoft/windowsservercore:1709
    env:
      - name: USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
  nodeSelector:
    beta.kubernetes.io/os: windows

具有 configMap 值的 Windows Pod 映射到环境变量

windows/configmap-pod.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  name: example-config
data:
  example.property.1: hello
  example.property.2: world

---

apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
  - name: configmap-redis
    image: redis:3.0-nanoserver
    env:
      - name: EXAMPLE_PROPERTY_1
        valueFrom:
          configMapKeyRef:
            name: example-config
            key: example.property.1
      - name: EXAMPLE_PROPERTY_2
        valueFrom:
          configMapKeyRef:
            name: example-config
            key: example.property.2
  nodeSelector:
    beta.kubernetes.io/os: windows

一些受支持的卷挂载可以是本地卷,emptyDir 卷和主机路径卷。需要记住的一点是,路径必须转义,或者使用前斜杠,例如:mountPath: "C:\\etc\\foo" or mountPath: "C:/etc/foo"

对于受支持的卷类型,支持持久卷的声明。

例子:

带有主机路径卷的 Windows pod

windows/hostpath-volume-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-volume-pod
spec:
  containers:
  - name: my-hostpath-volume-pod
    image: microsoft/windowsservercore:1709
    volumeMounts:
    - name: foo
      mountPath: "C:\\etc\\foo"
      readOnly: true
  nodeSelector:
    beta.kubernetes.io/os: windows
  volumes:
  - name: foo
    hostPath:
     path: "C:\\etc\\foo"

具有多个 emptyDir 卷的 Windows pod

windows/emptydir-pod.yaml
 apiVersion: v1
 kind: Pod
 metadata:
   name: my-empty-dir-pod
 spec:
   containers:
   - image: microsoft/windowsservercore:1709
     name: my-empty-dir-pod
     volumeMounts:
     - mountPath: /cache
       name: cache-volume
     - mountPath: C:/scratch
       name: scratch-volume
   volumes:
   - name: cache-volume
     emptyDir: {}
   - name: scratch-volume
     emptyDir: {}
   nodeSelector:
     beta.kubernetes.io/os: windows

守护线程集

支持守护线程集

windows/daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
  labels:
    app: foo
spec:
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      containers:
      - name: foo
        image: microsoft/windowsservercore:1709
      nodeSelector:
        beta.kubernetes.io/os: windows

指标

Windows Stats 使用混合模型:pod 和容器级别的统计数据来自 CRI(通过 dockershim),而节点级别的统计数据来自“winstats”包,该包使用特定于 Windows 的 perf 计数器导出 cadvisor 之类的数据结构。

容器资源

现在可以为 v1.10 中的 windows 容器设置容器资源(CPU和内存)。

windows/deploy-resource.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis
spec:
  replicas: 3
  selector:
    matchLabels:
      app: iis
  template:
    metadata:
      labels:
        app: iis
    spec:
      containers:
      - name: iis
        image: microsoft/iis
        resources:
          limits:
            memory: "128Mi"
            cpu: 2
        ports:
        - containerPort: 80

Hyper-V 容器

Hyper-V 容器在 v1.10 中作为实验支持。要创建 Hyper-V 容器,kubelet 应该从特性 gates HyperVContainer=true 开始,Pod 应该包含注释 experimental.windows.kubernetes.io/isolation-type=hyperv

windows/deploy-hyperv.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis
spec:
  selector:
    matchLabels:
      app: iis
  replicas: 3
  template:
    metadata:
      labels:
        app: iis
      annotations:
        experimental.windows.kubernetes.io/isolation-type: hyperv
    spec:
      containers:
      - name: iis
        image: microsoft/iis
        ports:
        - containerPort: 80

Kubelet 和 kube-proxy 现在可以作为 Windows 服务运行

从 kubernetes v1.11 开始,kubelet 和 kube-proxy 可以作为 Windows 服务运行。

这意味着您现在可以通过 sc 命令将它们注册为 Windows 服务。有关如何使用 sc 创建 Windows 服务的更多细节,请参阅此处

例子:

创建服务

PS > sc.exe create <component_name> binPath= "<path_to_binary> --service <other_args>"
CMD > sc create <component_name> binPath= "<path_to_binary> --service <other_args>"

请注意,如果参数包含空格,则必须对其进行转义。例:

PS > sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' <other_args>"
CMD > sc create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' <other_args>"

启动服务:

PS > Start-Service kubelet; Start-Service kube-proxy
CMD > net start kubelet && net start kube-proxy

停止服务

PS > Stop-Service kubelet (-Force); Stop-Service kube-proxy (-Force)
CMD > net stop kubelet && net stop kube-proxy

查询服务

PS > Get-Service kubelet; Get-Service kube-proxy;
CMD > sc.exe queryex kubelet && sc qc kubelet && sc.exe queryex kube-proxy && sc.exe qc kube-proxy

Windows Server 容器与 v1.9 的已知限制

在未来的Kubernetes版本中,社区将解决其中一些限制:

后续步骤和资源

反馈