diff --git a/content/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md b/content/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md
index ce14ee6354..5935f09bb7 100644
--- a/content/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md
+++ b/content/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md
@@ -5,8 +5,10 @@ weight: 65
---
在很多组织中,其服务和应用的很大比例是 Windows 应用。
[Windows 容器](https://aka.ms/windowscontainers)提供了一种对进程和包依赖关系
@@ -32,16 +46,27 @@ Windows 容器调度到 Kubernetes 集群中 Windows 节点上的生产级支持
## kubernetes 中的 Windows 容器 {#windows-containers-in-kubernetes}
-若要在 Kubernetes 中启用对 Windows 容器的编排,只需在现有的 Linux 集群中
+若要在 Kubernetes 中启用对 Windows 容器的编排,可以在现有的 Linux 集群中
包含 Windows 节点。在 Kubernetes 上调度 {{< glossary_tooltip text="Pods" term_id="pod" >}}
-中的 Windows 容器与调用基于 Linux 的容器一样简单、一样容易。
+中的 Windows 容器与调用基于 Linux 的容器类似。
为了运行 Windows 容器,你的 Kubernetes 集群必须包含多个操作系统,控制面
节点运行 Linux,工作节点则可以根据负载需要运行 Windows 或 Linux。
@@ -52,15 +77,22 @@ Windows Server 2019 是唯一被支持的 Windows 操作系统,在 Windows 上
[Microsoft 文档](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19)。
{{< note >}}
-Kubernetes 控制面,包括[主控组件](/zh/docs/concepts/overview/components/),继续
-在 Linux 上运行。目前没有支持完全是 Windows 节点的 Kubernetes 集群的计划。
+Kubernetes 控制面,包括[主控组件](/zh/docs/concepts/overview/components/),
+继续在 Linux 上运行。
+目前没有支持完全是 Windows 节点的 Kubernetes 集群的计划。
{{< /note >}}
{{< note >}}
在本文中,当我们讨论 Windows 容器时,我们所指的是具有进程隔离能力的 Windows
@@ -75,7 +107,10 @@ In this document, when we talk about Windows containers we mean Windows containe
#### Windows OS Version Support
-Refer to the following table for Windows operating system support in Kubernetes. A single heterogeneous Kubernetes cluster can have both Windows and Linux worker nodes. Windows containers have to be scheduled on Windows nodes and Linux containers on Linux nodes.
+Refer to the following table for Windows operating system support in
+Kubernetes. A single heterogeneous Kubernetes cluster can have both Windows
+and Linux worker nodes. Windows containers have to be scheduled on Windows
+nodes and Linux containers on Linux nodes.
-->
## 支持的功能与局限性 {#supported-functionality-and-limitations}
@@ -89,17 +124,14 @@ Windows 容器仅能调度到 Windows 节点,Linux 容器则只能调度到 Li
| Kubernetes 版本 | Windows Server LTSC 版本 | Windows Server SAC 版本 |
| --- | --- | --- | --- |
-| *Kubernetes v1.14* | Windows Server 2019 | Windows Server ver 1809 |
-| *Kubernetes v1.15* | Windows Server 2019 | Windows Server ver 1809 |
-| *Kubernetes v1.16* | Windows Server 2019 | Windows Server ver 1809 |
-| *Kubernetes v1.17* | Windows Server 2019 | Windows Server ver 1809 |
-| *Kubernetes v1.18* | Windows Server 2019 | Windows Server ver 1809, Windows Server ver 1903, Windows Server ver 1909 |
| *Kubernetes v1.19* | Windows Server 2019 | Windows Server ver 1909, Windows Server ver 2004 |
+| *Kubernetes v1.20* | Windows Server 2019 | Windows Server ver 1909, Windows Server ver 2004 |
+| *Kubernetes v1.21* | Windows Server 2019 | Windows Server ver 2004, Windows Server ver 20H2 |
关于不同的 Windows Server 版本的服务渠道,包括其支持模式等相关信息可以在
[Windows Server servicing channels](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19)
@@ -113,8 +145,8 @@ chose to upgrade their operating system for containers running on Kubernetes,
we will offer guidance and step-by-step instructions when we add support for a
new operating system version. This guidance will include recommended upgrade
procedures for upgrading user applications together with cluster nodes.
-Windows nodes adhere to Kubernetes [version-skew
-policy](/docs/setup/release/version-skew-policy/) (node to control plane
+Windows nodes adhere to Kubernetes
+[version-skew policy](/docs/setup/release/version-skew-policy/) (node to control plane
versioning) the same way as Linux nodes do today.
-->
我们并不指望所有 Windows 客户都为其应用频繁地更新操作系统。
@@ -126,20 +158,47 @@ Windows 节点遵从 Kubernetes
[版本偏差策略](/zh/docs/setup/release/version-skew-policy/)(节点到控制面的
版本控制),与 Linux 节点的现行策略相同。
-Windows Server 主机操作系统会受 [Windows Server](https://www.microsoft.com/en-us/cloud-platform/windows-server-pricing)
+
+Windows Server 主机操作系统会受
+[Windows Server](https://www.microsoft.com/en-us/cloud-platform/windows-server-pricing)
授权策略控制。Windows 容器镜像则遵从
[Windows 容器的补充授权条款](https://docs.microsoft.com/en-us/virtualization/windowscontainers/images-eula)
约定。
+
带进程隔离的 Windows 容器受一些严格的兼容性规则约束,
[其中宿主 OS 版本必须与容器基准镜像的 OS 版本相同](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility)。
一旦我们在 Kubernetes 中支持带 Hyper-V 隔离的 Windows 容器,
这一约束和兼容性规则也会发生改变。
+
+#### Pause 镜像 {#pause-image}
+
+Microsoft 在 `mcr.microsoft.com/oss/kubernetes/pause:3.4.1` 处维护
+一个 pause 基础设施容器镜像。
+
#### 计算 {#compute}
@@ -192,7 +251,8 @@ to Windows.
* [控制器(Controllers)](/zh/docs/concepts/workloads/controllers/)
Kubernetes 控制器处理 Pod 的期望状态。Windows 容器支持以下负载控制器:
@@ -207,7 +267,10 @@ to Windows.
* [服务(Services)](/zh/docs/concepts/services-networking/service/)
Kubernetes Service 是一种抽象对象,用来定义 Pod 的一个逻辑集合及用来访问这些
Pod 的策略。Service 有时也称作微服务(Micro-service)。你可以使用服务来实现
@@ -221,7 +284,10 @@ to Windows.
* 无头(Headless)服务
Docker EE-basic 19.03+ 是建议所有 Windows Server 版本采用的容器运行时。
该容器运行时能够与 kubelet 中的 dockershim 代码协同工作。
##### CRI-ContainerD
-{{< feature-state for_k8s_version="v1.19" state="beta" >}}
+{{< feature-state for_k8s_version="v1.20" state="stable" >}}
-{{< caution >}}
-在 ContainerD 上使用 GMSA 访问 Windows 网络共享资源时,有一个
-[已知的局限](/zh/docs/tasks/configure-pod-container/configure-gmsa/#gmsa-limitations),
-需要内核补丁来解决。
-你可以在关注 [Microsoft Windows Containers 问题跟踪](https://github.com/microsoft/Windows-Containers/issues/44)
-来跟进相关的更新。
-{{< /caution >}}
-
-
-{{< glossary_tooltip term_id="containerd" text="ContainerD" >}} 1.4.0-beta.2+
-也可在 Windows Kubernetes 节点上用作容器运行时。
-
-
-在 Windows 对 ContainerD 的最初支持是在 Kubernetes v1.18 加入的。
-Windows 上 ContainerD 的进展可以在
-[enhancements#1001](https://github.com/kubernetes/enhancements/issues/1001)
-跟进。
-
-你可以进一步了解如何[在 Windows 上安装 ContainerD](/zh/docs/setup/production-environment/container-runtimes/#install-containerd).
+{{< glossary_tooltip term_id="containerd" text="ContainerD" >}} 1.4.0+
+也可作为 Windows Kubernetes 节点上的容器运行时。
#### 持久性存储 {#persistent-storage}
@@ -310,7 +363,13 @@ Windows 支持以下大类的 Kubernetes 卷插件:
##### 树内卷插件 {#in-tree-volume-plugins}
@@ -329,11 +388,20 @@ Code associated with in-tree volume plugins ship as part of the core Kubernetes
##### FlexVolume 插件 {#flexvolume-plugins}
-与 [FlexVolume](/docs/concepts/storage/volumes/#flexVolume) 插件相关的代码是作为
+与 [FlexVolume](/zh/docs/concepts/storage/volumes/#flexVolume) 插件相关的代码是作为
树外(Out-of-tree)脚本或可执行文件来发布的,因此需要在宿主系统上直接部署。
FlexVolume 插件处理将卷挂接到 Kubernetes 节点或从其上解挂、将卷挂载到 Pod 中
各个容器上或从其上卸载等操作。对于与 FlexVolume 插件相关联的持久卷的配备和
@@ -350,10 +418,19 @@ FlexVolume 插件处理将卷挂接到 Kubernetes 节点或从其上解挂、将
-->
##### CSI 插件 {#csi-plugins}
-{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
+{{< feature-state for_k8s_version="v1.19" state="beta" >}}
与 {{< glossary_tooltip text="CSI" term_id="csi" >}} 插件相关联的代码作为
树外脚本和可执行文件来发布且通常发布为容器镜像形式,并使用 DaemonSet 和
@@ -364,7 +441,17 @@ CSI 插件处理 Kubernetes 中的很多卷管理操作:对卷的配备、去
CSI 插件通常包含节点插件(以 DaemonSet 形式运行于各节点上)和控制器插件。
CSI 节点插件(尤其是那些通过块设备或者共享文件系统形式来提供持久卷的插件)
需要执行很多特权级操作,例如扫描磁盘设备、挂载文件系统等等。
@@ -378,7 +465,15 @@ Windows 节点之上。请参考你要部署的 CSI 插件的部署指南以进
#### 联网 {#networking}
@@ -412,7 +507,12 @@ The following service spec types are supported:
##### 网络模式 {#network-modes}
@@ -421,26 +521,193 @@ Windows 支持五种不同的网络驱动/模式:二层桥接(L2bridge)、
在一个包含 Windows 和 Linux 工作节点的异构集群中,你需要选择一种对 Windows 和
Linux 兼容的联网方案。下面是 Windows 上支持的一些树外插件及何时使用某种
CNI 插件的建议:
-
-| 网络驱动 | 描述 | 容器报文修改 | 网络插件 | 网络插件特点 |
-| ----------- | ---------- | -------------- | ---------- | ---------------|
-| L2bridge | 容器挂接到外部 vSwitch 上。容器挂接到下层网络之上,但由于容器的 MAC 地址在入站和出站时被重写,物理网络不需要这些地址。 | MAC 地址被重写为宿主系统的 MAC 地址,IP 地址也可能依据 HNS OutboundNAT 策略重写为宿主的 IP 地址。 | [win-bridge](https://github.com/containernetworking/plugins/tree/master/plugins/main/windows/win-bridge)、[Azure-CNI](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md);Flannel 宿主网关(host-gateway)使用 win-bridge | win-bridge 使用二层桥接(L2bridge)网络模式,将容器连接到下层宿主系统上,从而提供最佳性能。需要用户定义的路由(User-Defined Routes,UDR)才能实现节点间的连接。 |
-| L2Tunnel | 这是二层桥接的一种特殊情形,但仅被用于 Azure 上。所有报文都被发送到虚拟化环境中的宿主机上并根据 SDN 策略进行处理。 | MAC 地址被改写,IP 地址在下层网络上可见。 | [Azure-CNI](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md) | Azure-CNI 使得容器能够与 Azure vNET 集成,并允许容器利用 [Azure 虚拟网络](https://azure.microsoft.com/en-us/services/virtual-network/)所提供的功能特性集合。例如,可以安全地连接到 Azure 服务上或者使用 Azure NSG。你可以参考 [azure-cni](https://docs.microsoft.com/en-us/azure/aks/concepts-network#azure-cni-advanced-networking) 所提供的一些示例。 |
-| 覆盖网络(Kubernetes 中为 Windows 提供的覆盖网络支持处于 *alpha* 阶段) | 每个容器会获得一个连接到外部 vSwitch 的虚拟网卡(vNIC)。每个覆盖网络都有自己的、通过定制 IP 前缀来定义的 IP 子网。覆盖网络驱动使用 VXLAN 封装。 | 封装于外层包头内。 | [Win-overlay](https://github.com/containernetworking/plugins/tree/master/plugins/main/windows/win-overlay)、Flannel VXLAN(使用 win-overlay) | 当(比如出于安全原因)期望虚拟容器网络与下层宿主网络隔离时,应该使用 win-overlay。如果你的数据中心可用 IP 地址受限,覆盖网络允许你在不同的网络中复用 IP 地址(每个覆盖网络有不同的 VNID 标签)。这一选项要求在 Windows Server 2009 上安装 [KB4489899](https://support.microsoft.com/help/4489899) 补丁。 |
-| 透明网络([ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes) 的特殊用例) | 需要一个外部 vSwitch。容器挂接到某外部 vSwitch 上,该 vSwitch 通过逻辑网络(逻辑交换机和路由器)允许 Pod 间通信。 | 报文或者通过 [GENEVE](https://datatracker.ietf.org/doc/draft-gross-geneve/) 来封装,或者通过 [STT](https://datatracker.ietf.org/doc/draft-davie-stt/) 隧道来封装,以便能够到达不在同一宿主系统上的每个 Pod。
报文通过 OVN 网络控制器所提供的隧道元数据信息来判定是转发还是丢弃。
北-南向通信通过 NAT 网络地址转译来实现。 | [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes) | [通过 Ansible 来部署](https://github.com/openvswitch/ovn-kubernetes/tree/master/contrib)。所发布的 ACL 可以通过 Kubernetes 策略来应用实施。支持 IPAM 。负载均衡能力不依赖 kube-proxy。网络地址转译(NAT)也不需要 iptables 或 netsh。 |
-| NAT(*未在 Kubernetes 中使用*) | 容器获得一个连接到某内部 vSwitch 的 vNIC 接口。DNS/DHCP 服务通过名为 [WinNAT](https://blogs.technet.microsoft.com/virtualization/2016/05/25/windows-nat-winnat-capabilities-and-limitations/) 的内部组件来提供。 | MAC 地址和 IP 地址都被重写为宿主系统的 MAC 地址和 IP 地址。| [nat](https://github.com/Microsoft/windows-container-networking/tree/master/plugins/nat) | 列在此表中仅出于完整性考虑 |
+
+
+
+ | 网络驱动 |
+ 描述 |
+ 容器报文更改 |
+ 网络插件 |
+ 网络插件特点 |
+
+
+
+
+ | L2bridge |
+
+ 容器挂接到外部 vSwitch 上。容器挂接到下层网络之上,但由于容器的 MAC
+ 地址在入站和出站时被重写,物理网络不需要这些地址。
+ |
+
+
+ MAC 地址被重写为宿主系统的 MAC 地址,IP 地址也可能依据 HNS OutboundNAT
+ 策略重写为宿主的 IP 地址。
+ |
+
+ win-bridge、
+ Azure-CNI、
+
+ Flannel 宿主网关(host-gateway)使用 win-bridge
+ |
+
+
+ win-bridge 使用二层桥接(L2bridge)网络模式,将容器连接到下层宿主系统上,
+ 从而提供最佳性能。需要用户定义的路由(User-Defined Routes,UDR)才能
+ 实现节点间的连接。
+ |
+
+
+ | L2Tunnel |
+
+
+ 这是二层桥接的一种特殊情形,但仅被用于 Azure 上。
+ 所有报文都被发送到虚拟化环境中的宿主机上并根据 SDN 策略进行处理。
+ |
+
+
+ MAC 地址被改写,IP 地址在下层网络上可见。
+ |
+
+ Azure-CNI
+ |
+
+
+ Azure-CNI 使得容器能够与 Azure vNET 集成,并允许容器利用
+ [Azure 虚拟网络](https://azure.microsoft.com/en-us/services/virtual-network/)
+ 所提供的功能特性集合。例如,可以安全地连接到 Azure 服务上或者使用 Azure NSG。
+ 你可以参考
+ [azure-cni](https://docs.microsoft.com/en-us/azure/aks/concepts-network#azure-cni-advanced-networking)
+ 所提供的一些示例。
+ |
+
+
+ | 覆盖网络(Kubernetes 中为 Windows 提供的覆盖网络支持处于 *alpha* 阶段) |
+
+
+ 每个容器会获得一个连接到外部 vSwitch 的虚拟网卡(vNIC)。
+ 每个覆盖网络都有自己的、通过定制 IP 前缀来定义的 IP 子网。
+ 覆盖网络驱动使用 VxLAN 封装。
+ |
+
+
+ 封装于外层包头内。
+ |
+
+ Win-overlay、
+ Flannel VXLAN(使用 win-overlay)
+ |
+
+
+ 当(比如出于安全原因)期望虚拟容器网络与下层宿主网络隔离时,
+ 应该使用 win-overlay。如果你的数据中心可用 IP 地址受限,
+ 覆盖网络允许你在不同的网络中复用 IP 地址(每个覆盖网络有不同的 VNID 标签)。
+ 这一选项要求在 Windows Server 2009 上安装
+ [KB4489899](https://support.microsoft.com/help/4489899) 补丁。
+ |
+
+
+ |
+
+ 透明网络([ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes) 的特殊用例)
+ |
+
+
+ 需要一个外部 vSwitch。容器挂接到某外部 vSwitch 上,该 vSwitch
+ 通过逻辑网络(逻辑交换机和路由器)允许 Pod 间通信。
+ |
+
+
+ 报文或者通过 [GENEVE](https://datatracker.ietf.org/doc/draft-gross-geneve/) 来封装,
+ 或者通过 [STT](https://datatracker.ietf.org/doc/draft-davie-stt/) 隧道来封装,
+ 以便能够到达不在同一宿主系统上的每个 Pod。
+ 报文通过 OVN 网络控制器所提供的隧道元数据信息来判定是转发还是丢弃。
+ 北-南向通信通过 NAT 网络地址转译来实现。
+ |
+
+ ovn-kubernetes
+ |
+
+
+ [通过 Ansible 来部署](https://github.com/openvswitch/ovn-kubernetes/tree/master/contrib)。
+ 所发布的 ACL 可以通过 Kubernetes 策略来应用实施。支持 IPAM 。
+ 负载均衡能力不依赖 kube-proxy。
+ 网络地址转译(NAT)也不需要 iptables 或 netsh。
+ |
+
+
+ | NAT(未在 Kubernetes 中使用) |
+
+
+ 容器获得一个连接到某内部 vSwitch 的 vNIC 接口。
+ DNS/DHCP 服务通过名为
+ [WinNAT](https://blogs.technet.microsoft.com/virtualization/2016/05/25/windows-nat-winnat-capabilities-and-limitations/)
+ 的内部组件来提供。
+ |
+
+
+ MAC 地址和 IP 地址都被重写为宿主系统的 MAC 地址和 IP 地址。
+ |
+
+ nat
+ |
+
+
+ 列在此表中仅出于完整性考虑
+ |
+
+
+
如前所述,[Flannel](https://github.com/coreos/flannel) CNI
[meta 插件](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel)
@@ -458,7 +725,8 @@ As outlined above, the [Flannel](https://github.com/coreos/flannel) CNI [meta pl
并将包含节点所被分配的子网信息的正确配置发送给 IPAM 插件(例如 host-local)。
##### 负载均衡与服务 {#load-balancing-and-services}
在 Windows 系统上,你可以使用以下配置来设定服务和负载均衡行为:
+{{< table caption="Windows 服务设置" >}}
-
-{{< table caption="Windows 服务配置" >}}
-
-| 功能特性 | 描述 | 支持的 Kubernetes 版本 | 支持的 Windows OS 版本 | 如何启用 |
-| -------- | --------| ---------------------- | ---------------------- | ---------- |
-| 会话亲和性 | 确保来自特定客户的连接每次都被交给同一 Pod。 | v1.19+ | [Windows Server vNext Insider Preview Build 19551](https://blogs.windows.com/windowsexperience/2020/01/28/announcing-windows-server-vnext-insider-preview-build-19551/) 或更高版本 | 将 `service.spec.sessionAffinity` 设置为 "ClientIP" |
-| 直接服务器返回 | 这是一种负载均衡模式,IP 地址的修正和负载均衡地址转译(LBNAT)直接在容器的 vSwitch 端口上处理;服务流量到达时,其源端 IP 地址设置为来源 Pod 的 IP。这种方案的延迟很低且可扩缩性好。 | v1.15+ | Windows Server 2004 版 | 为 kube-proxy 设置标志:`--feature-gates="WinDSR=true" --enable-dsr=true` |
-| 保留目标地址 | 对服务流量略过 DNAT 步骤,这样就可以在到达后端 Pod 的报文中保留目标服务的虚拟 IP 地址。这一配置也会确保入站报文的客户端 IP 地址也被保留下来。 | v1.15+ | Windows Server 1903 或更高版本 | 在服务注解中设置 `"preserve-destination": "true"` 并启用 kube-proxy 中的 DSR 标志。 |
-| IPv4/IPv6 双栈网络 | 在集群内外同时支持原生的 IPv4-到-IPv4 和 IPv6-到-IPv6 通信。 | v1.19+ | Windows Server vNext Insider Preview Build 19603 或更高版本 | 参见 [IPv4/IPv6 dual-stack](#ipv4ipv6-dual-stack) |
+
+
+
+ | 功能特性 |
+ 描述 |
+ 所支持的 Kubernetes 版本 |
+ 所支持的 Windows OS 版本 |
+ 如何启用 |
+
+
+
+
+ | 会话亲和性 |
+
+
+ 确保来自特定客户的连接每次都被交给同一 Pod。
+ |
+ v1.20+ |
+
+
+ [Windows Server vNext Insider Preview Build 19551](https://blogs.windows.com/windowsexperience/2020/01/28/announcing-windows-server-vnext-insider-preview-build-19551/)
+ 或更高版本
+ |
+
+
+ 将 service.spec.sessionAffinitys 设置为 "ClientIP"
+ |
+
+
+ | 直接服务器返回(DSR) |
+
+
+ 这是一种负载均衡模式,IP 地址的修正和负载均衡地址转译(LBNAT)
+ 直接在容器的 vSwitch 端口上处理;服务流量到达时,其源端 IP 地址
+ 设置为来源 Pod 的 IP。
+ |
+ v1.20+ |
+
+ Windows Server 2019
+ |
+
+
+ 为 kube-proxy 设置标志:`--feature-gates="WinDSR=true" --enable-dsr=true`
+ |
+
+
+ | 保留目标地址 |
+
+
+ 对服务流量略过 DNAT 步骤,这样就可以在到达后端 Pod 的报文中保留目标服务的
+ 虚拟 IP 地址。还要禁止节点之间的转发。
+ |
+ v1.20+ |
+ Windows Server 1903 或更高版本 |
+
+
+ 在服务注解中设置 `"preserve-destination": "true"` 并启用
+ kube-proxy 中的 DSR 标志。
+ |
+
+
+ | IPv4/IPv6 双栈网络 |
+
+
+ 在集群内外同时支持原生的 IPv4-到-IPv4 和 IPv6-到-IPv6 通信。
+ |
+ v1.19+ |
+ Windows Server 2004 或更高版本 |
+
+
+ 参见 [IPv4/IPv6 双栈网络](#ipv4ipv6-dual-stack)
+ |
+
+
+ | 保留客户端 IP |
+
+
+ 确保入站流量的源 IP 地址被保留。同样要禁止节点之间的转发。
+ |
+ v1.20+ |
+ Windows Server 2019 或更高版本 |
+
+
+ 将 service.spec.externalTrafficPolicy 设置为 "Local",
+ 并在 kube-proxy 上启用 DSR。
+ |
+
+
+
{{< /table >}}
#### IPv4/IPv6 双栈支持 {#ipv4ipv6-dual-stack}
你可以通过使用 `IPv6DualStack`
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
来为 `l2bridge` 网络启用 IPv4/IPv6 双栈联网支持。
-进一步的细节可参见[启用 IPv4/IPv6 双协议栈](/zh/docs/concepts/services-networking/dual-stack#enable-ipv4ipv6-dual-stack)。
+进一步的细节可参见
+[启用 IPv4/IPv6 双协议栈](/zh/docs/concepts/services-networking/dual-stack#enable-ipv4ipv6-dual-stack)。
对 Windows 而言,在 Kubernetes 中使用 IPv6 需要
-Windows Server vNext Insider Preview Build 19603 或更高版本。
+Windows Server 2004 (内核版本 10.0.19041.610)或更高版本。
目前 Windows 上的覆盖网络(VXLAN)还不支持双协议栈联网。
### 局限性 {#limitations}
-#### 控制面 {#control-plane}
-
在 Kubernetes 架构和节点阵列中仅支持将 Windows 作为工作节点使用。
这意味着 Kubernetes 集群必须总是包含 Linux 主控节点,零个或者多个 Linux
工作节点以及零个或者多个 Windows 工作节点。
-#### 计算 {#compute}
-
-##### 资源管理与进程隔离 {#resource-management-and-process-isolation}
+#### 资源处理 {#resource-handling}
Linux 上使用 Linux 控制组(CGroups)作为 Pod 的边界,以实现资源控制。
容器都创建于这一边界之内,从而实现网络、进程和文件系统的隔离。
@@ -587,16 +949,82 @@ Linux 上使用 Linux 控制组(CGroups)作为 Pod 的边界,以实现资
获得宿主系统上的任何身份标识。
-##### 操作系统限制 {#operating-system-restrictions}
+#### 资源预留 {#resource-reservations}
-Windows 有着严格的兼容性规则,宿主 OS 的版本必须与容器基准镜像 OS 的版本匹配。
-目前仅支持容器操作系统为 Windows Server 2019 的 Windows 容器。
-对于容器的 Hyper-V 隔离、允许一定程度上的 Windows 容器镜像版本向后兼容性等等,
-都是将来版本计划的一部分。
+##### 内存预留 {#memory-reservations}
+
+Windows 不像 Linux 一样有一个内存耗尽(Out-of-memory)进程杀手(Process
+Killer)机制。Windows 总是将用户态的内存分配视为虚拟请求,页面文件(Pagefile)
+是必需的。这一差异的直接结果是 Windows 不会像 Linux 那样出现内存耗尽的状况,
+系统会将进程内存页面写入磁盘而不会因内存耗尽而终止进程。
+当内存被过量使用且所有物理内存都被用光时,系统的换页行为会导致性能下降。
+
+
+使用 kubelet 参数 `--kubelet-reserve` 与/或 `-system-reserve` 可以统计
+节点上的内存用量(各容器之外),进而可能将内存用量限制在一个合理的范围,。
+这样做会减少节点可分配内存
+([NodeAllocatable](/zh/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable))。
+
+
+在你部署工作负载时,对容器使用资源限制(必须仅设置 limits 或者让 limits 等于
+requests 值)。这也会从 NodeAllocatable 中耗掉部分内存量,从而避免在节点
+负荷已满时调度器继续向节点添加 Pods。
+
+
+避免过量分配的最佳实践是为 kubelet 配置至少 2 GB 的系统预留内存,以供
+Windows、Docker 和 Kubernetes 进程使用。
+
+
+##### CPU 预留 {#cpu-reservations}
+
+为了统计 Windows、Docker 和其他 Kubernetes 宿主进程的 CPU 用量,建议
+预留一定比例的 CPU,以便对事件作出相应。此值需要根据 Windows 节点上
+CPU 核的个数来调整,要确定此百分比值,用户需要为其所有节点确定 Pod
+密度的上线,并监控系统服务的 CPU 用量,从而选择一个符合其负载需求的值。
+
+
+使用 kubelet 参数 `--kubelet-reserve` 与/或 `-system-reserve` 可以统计
+节点上的 CPU 用量(各容器之外),进而可能将 CPU 用量限制在一个合理的范围,。
+这样做会减少节点可分配 CPU
+([NodeAllocatable](/zh/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable))。
##### 功能特性限制 {#feature-restrictions}
@@ -621,48 +1052,36 @@ Windows 有着严格的兼容性规则,宿主 OS 的版本必须与容器基
* 并非支持共享名字空间的所有功能特性(参见 API 节以了解详细信息)
-##### 内存预留与处理 {#memory-reservations-and-handling}
+The behavior of the following kubelet flags is different on Windows nodes as described below:
-Windows 不像 Linux 一样有一个内存耗尽(Out-of-memory)进程杀手(Process
-Killer)机制。Windows 总是将用户态的内存分配视为虚拟请求,页面文件(Pagefile)
-是必需的。这一差异的直接结果是 Windows 不会像 Linux 那样出现内存耗尽的状况,
-系统会将进程内存页面写入磁盘而不会因内存耗尽而终止进程。
-当内存被过量使用且所有物理内存都被用光时,系统的换页行为会导致性能下降。
-
-
-通过一个两步的过程是有可能将内存用量限制在一个合理的范围的。
-首先,使用 kubelet 参数 `--kubelet-reserve` 与/或 `--system-reserve`
-来划分节点上的内存用量(各容器之外)。
-这样做会减少节点可分配内存
-([NodeAllocatable](/zh/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable))。
-在你部署工作负载时,对容器使用资源限制(必须仅设置 limits 或者让 limits 等于
-requests 值)。这也会从 NodeAllocatable 中耗掉部分内存量,从而避免在节点
-负荷已满时调度器继续向节点添加 Pods。
-
-避免过量分配的最佳实践是为 kubelet 配置至少 2 GB 的系统预留内存,以供
-Windows、Docker 和 Kubernetes 进程使用。
-
-
-参数的不同行为描述如下:
+#### 与 Linux 相比参数行为的差别
-* `--kubelet-reserve`、`--system-reserve` 和 `--eviction-hard` 标志会更新节点可分配内存量
+以下 kubelet 参数的行为在 Windows 节点上有些不同,描述如下:
+
+* `--kubelet-reserve`、`--system-reserve` 和 `--eviction-hard` 标志
+ 会更新节点可分配资源量
* 未实现通过使用 `--enforce-node-allocable` 来完成的 Pod 驱逐
* 未实现通过使用 `--eviction-hard` 和 `--eviction-soft` 来完成的 Pod 驱逐
* `MemoryPressure` 状况未实现
@@ -671,24 +1090,42 @@ The behavior of the flags behave differently as described below:
`--kubelet-reserve` 和 `--system-reserve` 不会为 kubelet 或宿主系统上运行
的进程设限。这意味着 kubelet 或宿主系统上的进程可能导致内存资源紧张,
而这一情况既不受节点可分配量影响,也不会被调度器感知。
+* 在 Windows 节点上存在一个额外的参数用来设置 kubelet 进程的优先级,称作
+ `--windows-priorityclass`。此参数允许 kubelet 进程获得与 Windows 宿主上
+ 其他进程相比更多的 CPU 时间片。
+ 关于可用参数值及其含义的进一步信息可参考
+ [Windows Priority Classes](https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities#priority-class)。
+ 为了让 kubelet 总能够获得足够的 CPU 周期,建议将此参数设置为
+ `ABOVE_NORMAL_PRIORITY_CLASS` 或更高。
#### 存储 {#storage}
Windows 上包含一个分层的文件系统来挂载容器的分层,并会基于 NTFS 来创建一个
拷贝文件系统。容器中的所有文件路径都仅在该容器的上下文内完成解析。
-* 卷挂载仅可针对容器中的目录进行,不可针对独立的文件
-* 卷挂载无法将文件或目录投射回宿主文件系统
+* Docker 卷挂载仅可针对容器中的目录进行,不可针对独立的文件。
+ 这一限制不适用于 CRI-containerD。
+* 卷挂载无法将文件或目录投射回宿主文件系统。
* 不支持只读文件系统,因为 Windows 注册表和 SAM 数据库总是需要写访问权限。
不过,Windows 支持只读的卷。
* 不支持卷的用户掩码和访问许可,因为宿主与容器之间并不共享 SAM,二者之间不存在
@@ -708,25 +1145,27 @@ As a result, the following storage functionality is not supported on Windows nod
* NFS based storage/volume support
* Expanding the mounted volume (resizefs)
-->
-因此,Windows 节点上不支持以下存储功能:
+因此,Windows 节点上不支持以下存储功能特性:
* 卷的子路径挂载;只能在 Windows 容器上挂载整个卷。
-* 为 Secret 执行子路径挂载
-* 宿主挂载投射
-* 默认访问模式(因为该特性依赖 UID/GID)
-* 只读的根文件系统;映射的卷仍然支持 `readOnly`
-* 块设备映射
-* 将内存作为存储介质
-* 类似 UUID/GUID、每用户不同的 Linux 文件系统访问许可等文件系统特性
-* 基于 NFS 的存储和卷支持
-* 扩充已挂载卷(resizefs)
+* 为 Secret 执行子路径挂载;
+* 宿主挂载投射;
+* 默认访问模式 defaultMode(因为该特性依赖 UID/GID);
+* 只读的根文件系统;映射的卷仍然支持 `readOnly`;
+* 块设备映射;
+* 将内存作为存储介质;
+* 类似 UUID/GUID、每用户不同的 Linux 文件系统访问许可等文件系统特性;
+* 基于 NFS 的存储和卷支持;
+* 扩充已挂载卷(resizefs)。
-#### 联网 {#networking}
+#### 联网 {#networking-limitations}
Windows 容器联网与 Linux 联网有着非常重要的差别。
[Microsoft documentation for Windows Container Networking](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture)
@@ -757,35 +1196,67 @@ Windows 为容器提供的注册表与宿主系统的注册表是分离的,因
The following networking functionality is not supported on Windows nodes
* Host networking mode is not available for Windows pods
-* Local NodePort access from the node itself fails (works for other nodes or external clients)
-* Accessing service VIPs from nodes will be available with a future release of Windows Server
-* Overlay networking support in kube-proxy is an alpha release. In addition, it requires [KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887) to be installed on Windows Server 2019
-* Local Traffic Policy and DSR mode
-* Windows containers connected to l2bridge, l2tunnel, or overlay networks do not support communicating over the IPv6 stack. There is outstanding Windows platform work required to enable these network drivers to consume IPv6 addresses and subsequent Kubernetes work in kubelet, kube-proxy, and CNI plugins.
-* Outbound communication using the ICMP protocol via the win-overlay, win-bridge, and Azure-CNI plugin. Specifically, the Windows data plane ([VFP](https://www.microsoft.com/en-us/research/project/azure-virtual-filtering-platform/)) doesn't support ICMP packet transpositions. This means:
- * ICMP packets directed to destinations within the same network (e.g. pod to pod communication via ping) work as expected and without any limitations
- * TCP/UDP packets work as expected and without any limitations
- * ICMP packets directed to pass through a remote network (e.g. pod to external internet communication via ping) cannot be transposed and thus will not be routed back to their source
- * Since TCP/UDP packets can still be transposed, one can substitute `ping ` with `curl ` to be able to debug connectivity to the outside world.
+
+* Local NodePort access from the node itself fails (works for other nodes or
+ external clients)
+
+* Accessing service VIPs from nodes will be available with a future release of
+ Windows Server
+
+* A single service can only support up to 64 backend pods / unique destination IPs
+
+* Overlay networking support in kube-proxy is a beta feature. In addition, it
+ requires
+ [KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887)
+ to be installed on Windows Server 2019
+
+* Local Traffic Policy in non-DSR mode
+* Windows containers connected to overlay networks do not support
+ communicating over the IPv6 stack. There is outstanding Windows platform
+ work required to enable this network driver to consume IPv6 addresses and
+ subsequent Kubernetes work in kubelet, kube-proxy, and CNI plugins.
-->
Windows 节点不支持以下联网功能:
-* Windows Pod 不能使用宿主网络模式
+* Windows Pod 不能使用宿主网络模式;
* 从节点本地访问 NodePort 会失败(但从其他节点或外部客户端可访问)
-* Windows Server 的未来版本中会支持从节点访问服务的 VIPs
-* kube-proxy 的覆盖网络支持是 Alpha 特性。此外,它要求在 Windows Server 2019 上安装
- [KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887) 补丁
-* 本地流量策略和 DSR(保留目标地址)模式
-* 连接到 l2bridge、l2tunnel 或覆盖网络的 Windows 容器不支持使用 IPv6 协议栈通信。
- 要使得这些网络驱动能够支持 IPv6 地址需要在 Windows 平台上开展大量的工作,
+* Windows Server 的未来版本中会支持从节点访问服务的 VIP;
+* 每个服务最多支持 64 个后端 Pod 或独立的目标 IP 地址;
+* kube-proxy 的覆盖网络支持是 Beta 特性。此外,它要求在 Windows Server 2019 上安装
+ [KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887) 补丁;
+* 非 DSR(保留目标地址)模式下的本地流量策略;
+* 连接到覆盖网络的 Windows 容器不支持使用 IPv6 协议栈通信。
+ 要使得这一网络驱动支持 IPv6 地址需要在 Windows 平台上开展大量的工作,
还需要在 Kubernetes 侧修改 kubelet、kube-proxy 以及 CNI 插件。
+
* 通过 win-overlay、win-bridge 和 Azure-CNI 插件使用 ICMP 协议向集群外通信。
- 尤其是,Windows 数据面([VFP](https://www.microsoft.com/en-us/research/project/azure-virtual-filtering-platform/))
+ 尤其是,Windows 数据面
+ ([VFP](https://www.microsoft.com/en-us/research/project/azure-virtual-filtering-platform/))
不支持转换 ICMP 报文。这意味着:
- * 指向同一网络内目标地址的 ICMP 报文(例如 Pod 之间的 ping 通信)是可以工作的,没有局限性
- * TCP/UDP 报文可以正常工作,没有局限性
+
+ * 指向同一网络内目标地址的 ICMP 报文(例如 Pod 之间的 ping 通信)是可以工作的,
+ 没有局限性;
+ * TCP/UDP 报文可以正常工作,没有局限性;
* 指向远程网络的 ICMP 报文(例如,从 Pod 中 ping 外部互联网的通信)无法被转换,
- 因此也无法被路由回到其源点。
+ 因此也无法被路由回到其源点;
* 由于 TCP/UDP 包仍可被转换,用户可以将 `ping <目标>` 操作替换为 `curl <目标>`
以便能够调试与外部世界的网络连接。
@@ -801,17 +1272,25 @@ Kubernetes v1.15 中添加了以下功能特性:
##### CNI 插件 {#cni-plugins}
* Windows 参考网络插件 win-bridge 和 win-overlay 当前未实现
[CNI spec](https://github.com/containernetworking/cni/blob/master/SPEC.md) v0.4.0,
- 原因是缺少检查用(CHECK)的实现。
+ 原因是缺少检查(CHECK)用的实现。
+
* Windows 上的 Flannel VXLAN CNI 有以下局限性:
1. 其设计上不支持从节点到 Pod 的连接。
@@ -824,12 +1303,25 @@ Kubernetes v1.15 中添加了以下功能特性:
##### DNS {#dns-limitations}
* 不支持 DNS 的 ClusterFirstWithHostNet 配置。Windows 将所有包含 “.” 的名字
视为全限定域名(FQDN),因而不会对其执行部分限定域名(PQDN)解析。
+
* 在 Linux 上,你可以有一个 DNS 后缀列表供解析部分限定域名时使用。
在 Windows 上,我们只有一个 DNS 后缀,即与该 Pod 名字空间相关联的 DNS
后缀(例如 `mydns.svc.cluster.local`)。
@@ -838,12 +1330,17 @@ Kubernetes v1.15 中添加了以下功能特性:
`default.svc.cluster.local`。在 Windows Pod 中,你可以解析
`kubernetes.default.svc.cluster.local` 和 `kubernetes`,但无法解析二者
之间的形式,如 `kubernetes.default` 或 `kubernetes.default.svc`。
+
* 在 Windows 上,可以使用的 DNS 解析程序有很多。由于这些解析程序彼此之间
会有轻微的行为差别,建议使用 `Resolve-DNSName` 工具来完成名字查询解析。
##### IPv6
@@ -853,7 +1350,9 @@ Windows 上的 Kubernetes 不支持单协议栈的“只用 IPv6”联网选项
##### 会话亲和性 {#session-affinity}
@@ -863,10 +1362,12 @@ Windows 服务设置最大会话粘滞时间。
##### 安全性 {#security}
@@ -874,19 +1375,25 @@ Secret 以明文形式写入节点的卷中(而不是像 Linux 那样写入内
这意味着客户必须做以下两件事:
1. 使用文件访问控制列表来保护 Secret 文件所在的位置
-2. 使用 [BitLocker](https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server)
+1. 使用 [BitLocker](https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server)
来执行卷层面的加密
-Windows 上目前不支持 [`RunAsUser`](/zh/docs/concepts/policy/pod-security-policy/#users-and-groups)。
-一种替代方案是在为容器打包时创建本地账号。
-将来的版本中可能会添加对 `RunAsUser` 的支持。
+用户可以为 Windows Pods 或 Container 设置
+[`RunAsUserName`](/zh/docs/tasks/configure-pod-container/configure-runasusername)
+以便以非节点默认用户来执行容器中的进程。这大致等价于设置
+[`RunAsUser`](/zh/docs/concepts/policy/pod-security-policy/#users-and-groups)。
不支持特定于 Linux 的 Pod 安全上下文特权,例如 SELinux、AppArmor、Seccomp、
权能字(POSIX 权能字)等等。
@@ -896,7 +1403,11 @@ Windows 上目前不支持 [`RunAsUser`](/zh/docs/concepts/policy/pod-security-p
@@ -910,29 +1421,57 @@ At a high level, these OS concepts are different:
在较高层面,不同的 OS 概念有:
* 身份标识 - Linux 使用证书类型来表示用户 ID(UID)和组 ID(GID)。用户和组名
- 没有特定标准,它们仅是 `/etc/groups` 或 `/etc/passwd` 中的别名表项,会映射回
+ 没有特定标准,它们是 `/etc/groups` 或 `/etc/passwd` 中的别名表项,会映射回
UID+GID。Windows 使用一个更大的二进制安全标识符(SID),保存在 Windows
安全访问管理器(Security Access Manager,SAM)数据库中。此数据库并不在宿主系统
与容器间,或者任意两个容器之间共享。
+
* 文件许可 - Windows 使用基于 SID 的访问控制列表,而不是基于 UID+GID 的访问权限位掩码。
-* 文件路径 - Windows 上的习惯是使用 `\` 而非 `/`。Go 语言的 IO 库通常能够同时接受二者,
- 并做出正确判断。不过当你在指定要在容器内解析的路径或命令行时,可能需要使用 `\`。
-* 信号 - Windows 交互式应用以不同方式来处理终止事件,并可实现以下方式之一或组合:
- * UI 线程处理包含 WM_CLOSE 在内的良定的消息
- * 控制台应用使用控制处理程序来处理 Ctrl-C 或 Ctrl-Break
- * 服务会注册服务控制处理程序,接受 SERVICE_CONTROL_STOP 控制代码
+* 文件路径 - Windows 上的习惯是使用 `\` 而非 `/`。Go 语言的 IO
+ 库同时接受这两种文件路径分隔符。不过,当你在指定要在容器内解析的路径或命令行时,
+ 可能需要使用 `\`。
+
+* 信号(Signal) - Windows 交互式应用以不同方式来处理终止事件,并可实现以下方式之一或组合:
+
+ * UI 线程处理包含 `WM_CLOSE` 在内的良定的消息
+
+ * 控制台应用使用控制处理程序来处理 Ctrl-C 或 Ctrl-Break
+
+ * 服务会注册服务控制处理程序,接受 `SERVICE_CONTROL_STOP` 控制代码
+
+
退出代码遵从相同的习惯,0 表示成功,非 0 值表示失败。
特定的错误代码在 Windows 和 Linux 上可能会不同。不过,从 Kubernetes 组件
@@ -941,23 +1480,21 @@ Exit Codes follow the same convention where 0 is success, nonzero is failure. Th
-##### V1.Container
+* V1.Container.ResourceRequirements.limits.cpu and
+ V1.Container.ResourceRequirements.limits.memory - Windows doesn't use hard
+ limits for CPU allocations. Instead, a share system is used. The existing
+ fields based on millicores are scaled into relative shares that are followed
+ by the Windows scheduler.
+ See [kuberuntime/helpers_windows.go](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kuberuntime/helpers_windows.go),
+ and [resource controls in Microsoft docs](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/resource-controls)
-* `v1.Container.ResourceRequirements.limits.cpu` 和 `v1.Container.ResourceRequirements.limits.memory` - Windows
+ * Huge pages are not implemented in the Windows container runtime, and are
+ not available. They require
+ [asserting a user privilege](https://docs.microsoft.com/en-us/windows/desktop/Memory/large-page-support)
+ that's not configurable for containers.
+-->
+* `v1.Container.ResourceRequirements.limits.cpu` 和
+ `v1.Container.ResourceRequirements.limits.memory` - Windows
不对 CPU 分配设置硬性的限制。与之相反,Windows 使用一个份额(share)系统。
基于毫核(millicores)的现有字段值会被缩放为相对的份额值,供 Windows 调度器使用。
参见 [kuberuntime/helpers_windows.go](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kuberuntime/helpers_windows.go) 和
@@ -967,22 +1504,75 @@ Exit Codes follow the same convention where 0 is success, nonzero is failure. Th
巨页支持需要[判定用户的特权](https://docs.microsoft.com/en-us/windows/desktop/Memory/large-page-support)
而这一特性无法在容器级别配置。
-* `v1.Container.ResourceRequirements.requests.cpu` 和 `v1.Container.ResourceRequirements.requests.memory` - 请求
+
+* `v1.Container.ResourceRequirements.requests.cpu` 和
+ `v1.Container.ResourceRequirements.requests.memory` - 请求
值会从节点可分配资源中扣除,从而可用来避免节点上的资源过量分配。
但是,它们无法用来在一个已经过量分配的节点上提供资源保障。
如果操作员希望彻底避免过量分配,作为最佳实践,他们就需要为所有容器设置资源请求值。
-* `v1.Container.SecurityContext.allowPrivilegeEscalation` - 在 Windows 上无法实现,对应的权能
- 无一可在 Windows 上生效。
+
+* `v1.Container.SecurityContext.allowPrivilegeEscalation` - 在 Windows
+ 上无法实现,对应的权能无一可在 Windows 上生效。
+
+
* `v1.Container.SecurityContext.Capabilities` - Windows 上未实现 POSIX 权能机制
* `v1.Container.SecurityContext.privileged` - Windows 不支持特权容器
* `v1.Container.SecurityContext.procMount` - Windows 不包含 `/proc` 文件系统
* `v1.Container.SecurityContext.readOnlyRootFilesystem` - 在 Windows 上无法实现,
要在容器内使用注册表或运行系统进程就必需写访问权限。
+
+
* `v1.Container.SecurityContext.runAsGroup` - 在 Windows 上无法实现,没有 GID 支持
+
* `v1.Container.SecurityContext.runAsNonRoot` - Windows 上没有 root 用户。
与之最接近的等价用户是 `ContainerAdministrator`,而该身份标识在节点上并不存在。
-* `v1.Container.SecurityContext.runAsUser` - 在 Windows 上无法实现,因为没有作为整数支持的 GID。
-* `v1.Container.SecurityContext.seLinuxOptions` - 在 Windows 上无法实现,因为没有 SELinux
+
+* `v1.Container.SecurityContext.runAsUser` - 在 Windows 上无法实现,
+ 因为没有作为整数支持的 GID。
+
+* `v1.Container.SecurityContext.seLinuxOptions` - 在 Windows 上无法实现,
+ 因为没有 SELinux
+
* `V1.Container.terminationMessagePath` - 因为 Windows 不支持单个文件的映射,这一功能
在 Windows 上也受限。默认值 `/dev/termination-log` 在 Windows 上也无法使用因为
对应路径在 Windows 上不存在。
@@ -991,15 +1581,18 @@ Exit Codes follow the same convention where 0 is success, nonzero is failure. Th
##### V1.Pod
* V1.Pod.hostIPC, v1.pod.hostpid - host namespace sharing is not possible on Windows
+
* V1.Pod.hostNetwork - There is no Windows OS support to share the host network
-* V1.Pod.dnsPolicy - ClusterFirstWithHostNet - is not supported because Host Networking is not supported on Windows.
+
+* V1.Pod.dnsPolicy - ClusterFirstWithHostNet - is not supported because Host
+ Networking is not supported on Windows.
+
* V1.Pod.podSecurityContext - see V1.PodSecurityContext below
-* V1.Pod.shareProcessNamespace - this is a beta feature, and depends on Linux namespaces which are not implemented on Windows. Windows cannot share process namespaces or the container's root filesystem. Only the network can be shared.
-* V1.Pod.terminationGracePeriodSeconds - this is not fully implemented in Docker on Windows, see: [reference](https://github.com/moby/moby/issues/25982). The behavior today is that the ENTRYPOINT process is sent CTRL_SHUTDOWN_EVENT, then Windows waits 5 seconds by default, and finally shuts down all processes using the normal Windows shutdown behavior. The 5 second default is actually in the Windows registry [inside the container](https://github.com/moby/moby/issues/25982#issuecomment-426441183), so it can be overridden when the container is built.
-* V1.Pod.volumeDevices - this is a beta feature, and is not implemented on Windows. Windows cannot attach raw block devices to pods.
-* V1.Pod.volumes - EmptyDir, Secret, ConfigMap, HostPath - all work and have tests in TestGrid
- * V1.emptyDirVolumeSource - the Node default medium is disk on Windows. Memory is not supported, as Windows does not have a built-in RAM disk.
-* V1.VolumeMount.mountPropagation - mount propagation is not supported on Windows.
+
+* V1.Pod.shareProcessNamespace - this is a beta feature, and depends on Linux
+ namespaces which are not implemented on Windows. Windows cannot share
+ process namespaces or the container's root filesystem. Only the network can be
+ shared.
-->
##### V1.Pod
@@ -1007,51 +1600,117 @@ Exit Codes follow the same convention where 0 is success, nonzero is failure. Th
* `v1.Pod.hostNetwork` - Windows 操作系统不支持共享宿主网络
* `v1.Pod.dnsPolicy` - 不支持 `ClusterFirstWithHostNet`,因为 Windows 不支持宿主网络
* `v1.Pod.podSecurityContext` - 参见下面的 `v1.PodSecurityContext`
-* `v1.Pod.shareProcessNamespace` - 此为 Beta 特性且依赖于 Windows 上未实现的 Linux
- 名字空间。Windows 无法共享进程名字空间或者容器的根文件系统。只能共享网络。
+* `v1.Pod.shareProcessNamespace` - 此为 Beta 特性且依赖于 Windows 上未实现
+ 的 Linux 名字空间。
+ Windows 无法共享进程名字空间或者容器的根文件系统。只能共享网络。
+
+
* `v1.Pod.terminationGracePeriodSeconds` - 这一特性未在 Windows 版本的 Docker 中完全实现。
参见[问题报告](https://github.com/moby/moby/issues/25982)。
- 目前实现的行为是向 ENTRYPOINT 进程发送 CTRL_SHUTDOWN_EVENT 时间,之后 Windows 默认
+ 目前实现的行为是向 `ENTRYPOINT` 进程发送 `CTRL_SHUTDOWN_EVENT` 事件,之后 Windows 默认
等待 5 秒钟,并最终使用正常的 Windows 关机行为关闭所有进程。
- 这里的 5 秒钟默认值实际上保存在[容器内](https://github.com/moby/moby/issues/25982#issuecomment-426441183)
+ 这里的 5 秒钟默认值实际上保存在
+ [容器内](https://github.com/moby/moby/issues/25982#issuecomment-426441183)
的 Windows 注册表中,因此可以在构造容器时重载。
+
* `v1.Pod.volumeDevices` - 此为 Beta 特性且未在 Windows 上实现。Windows 无法挂接
原生的块设备到 Pod 中。
-* `v1.Pod.volumes` - `emptyDir`、`secret`、`configMap` 和 `hostPath` 都可正常工作且在
- TestGrid 中测试。
- * `v1.emptyDir.volumeSource` - Windows 上节点的默认介质是磁盘。不支持将内存作为介质,
- 因为 Windows 不支持内置的 RAM 磁盘。
+
+
+* `v1.Pod.volumes` - `emptyDir`、`secret`、`configMap` 和 `hostPath`
+ 都可正常工作且在 TestGrid 中测试。
+
+ * `v1.emptyDir.volumeSource` - Windows 上节点的默认介质是磁盘。
+ 不支持将内存作为介质,因为 Windows 不支持内置的 RAM 磁盘。
+
* `v1.VolumeMount.mountPropagation` - Windows 上不支持挂载传播。
##### V1.PodSecurityContext
PodSecurityContext 的所有选项在 Windows 上都无法工作。这些选项列在下面仅供参考。
* `v1.PodSecurityContext.seLinuxOptions` - Windows 上无 SELinux
+
* `v1.PodSecurityContext.runAsUser` - 提供 UID;Windows 不支持
+
* `v1.PodSecurityContext.runAsGroup` - 提供 GID;Windows 不支持
+
* `v1.PodSecurityContext.runAsNonRoot` - Windows 上没有 root 用户
最接近的等价账号是 `ContainerAdministrator`,而该身份标识在节点上不存在
+
* `v1.PodSecurityContext.supplementalGroups` - 提供 GID;Windows 不支持
+
* `v1.PodSecurityContext.sysctls` - 这些是 Linux sysctl 接口的一部分;Windows 上
没有等价机制。
+
+#### 操作系统版本限制 {#operating-system-version-restrictions}
+
+Windows 有着严格的兼容性规则,宿主 OS 的版本必须与容器基准镜像 OS 的版本匹配。
+目前仅支持容器操作系统为 Windows Server 2019 的 Windows 容器。
+对于容器的 Hyper-V 隔离、允许一定程度上的 Windows 容器镜像版本向后兼容性等等,
+都是将来版本计划的一部分。
+
## 获取帮助和故障排查 {#troubleshooting}
@@ -1059,453 +1718,531 @@ Your main source of help for troubleshooting your Kubernetes cluster should star
[这份文档](/docs/tasks/debug-application-cluster/troubleshooting/)。
该文档中包含了一些额外的、特定于 Windows 系统的故障排查帮助信息。
Kubernetes 中日志是故障排查的一个重要元素。确保你在尝试从其他贡献者那里获得
-故障排查帮助时提供日志信息。
-你可以按照 SIG-Windows [贡献指南和收集日志](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs)
+故障排查帮助时提供日志信息。你可以按照 SIG-Windows
+[贡献指南和收集日志](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs)
所给的指令来操作。
-1. 我怎样知道 `start.ps1` 是否已成功完成?
+* 我怎样知道 `start.ps1` 是否已成功完成?
- 你应该能看到节点上运行的 kubelet、kube-proxy 和(如果你选择 Flannel
- 作为联网方案)flanneld 宿主代理进程,它们的运行日志显示在不同的
- PowerShell 窗口中。此外,你的 Windows 节点应该在你的 Kubernetes 集群
- 列举为 "Ready" 节点。
+ 你应该能看到节点上运行的 kubelet、kube-proxy 和(如果你选择 Flannel
+ 作为联网方案)flanneld 宿主代理进程,它们的运行日志显示在不同的
+ PowerShell 窗口中。此外,你的 Windows 节点应该在你的 Kubernetes 集群
+ 列举为 "Ready" 节点。
-2. 我可以将 Kubernetes 节点进程配置为服务运行在后台么?
+* 我可以将 Kubernetes 节点进程配置为服务运行在后台么?
- kubelet 和 kube-proxy 都已经被配置为以本地 Windows 服务运行,
- 并且在出现失效事件(例如进程意外结束)时通过自动重启服务来提供一定的弹性。
- 你有两种办法将这些节点组件配置为服务。
+ kubelet 和 kube-proxy 都已经被配置为以本地 Windows 服务运行,
+ 并且在出现失效事件(例如进程意外结束)时通过自动重启服务来提供一定的弹性。
+ 你有两种办法将这些节点组件配置为服务。
-
- 1. 以本地 Windows 服务的形式
-
- Kubelet 和 kube-proxy 可以用 `sc.exe` 以本地 Windows 服务的形式运行:
-
- ```powershell
- # 用两个单独的命令为 kubelet 和 kube-proxy 创建服务
- sc.exe create <组件名称> binPath= "<可执行文件路径> -service <其它参数>"
-
- # 请注意如果参数中包含空格,必须使用转义
- sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' <其它参数>"
-
- # 启动服务
- Start-Service kubelet
- Start-Service kube-proxy
-
- # 停止服务
- Stop-Service kubelet (-Force)
- Stop-Service kube-proxy (-Force)
-
- # 查询服务状态
- Get-Service kubelet
- Get-Service kube-proxy
- ```
-
-
- 2. 使用 nssm.exe
-
- 你也总是可以使用替代的服务管理器,例如[nssm.exe](https://nssm.cc/),来为你在后台运行
- 这些进程(`flanneld`、`kubelet` 和 `kube-proxy`)。你可以使用这一
- [示例脚本](https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/register-svc.ps1),
- 利用 `nssm.exe` 将 `kubelet`、`kube-proxy` 和 `flanneld.exe` 注册为要在后台运行的
- Windows 服务。
-
- ```powershell
- register-svc.ps1 -NetworkMode <网络模式> -ManagementIP -ClusterCIDR <集群子网> -KubeDnsServiceIP -LogDir <日志目录>
-
- # NetworkMode = 网络模式 l2bridge(flannel host-gw,也是默认值)或 overlay(flannel vxlan)选做网络方案
- # ManagementIP = 分配给 Windows 节点的 IP 地址。你可以使用 ipconfig 得到此值
- # ClusterCIDR = 集群子网范围(默认值为 10.244.0.0/16)
- # KubeDnsServiceIP = Kubernetes DNS 服务 IP(默认值为 10.96.0.10)
- # LogDir = kubelet 和 kube-proxy 的日志会被重定向到这一目录中的对应输出文件,默认值为 `C:\k`。
- ```
-
- 若以上所引用的脚本不适合,你可以使用下面的例子手动配置 `nssm.exe`。
-
- ```powershell
- # 注册 flanneld.exe
- nssm install flanneld C:\flannel\flanneld.exe
- nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1
- nssm set flanneld AppEnvironmentExtra NODE_NAME=<主机名>
- nssm set flanneld AppDirectory C:\flannel
- nssm start flanneld
-
- # 注册 kubelet.exe
- # Microsoft 在 mcr.microsoft.com/k8s/core/pause:1.2.0 发布其 pause 基础设施容器
- nssm install kubelet C:\k\kubelet.exe
- nssm set kubelet AppParameters --hostname-override= --v=6 --pod-infra-container-image=mcr.microsoft.com/k8s/core/pause:1.2.0 --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns= --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false --log-dir= --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config
- nssm set kubelet AppDirectory C:\k
- nssm start kubelet
-
- # 注册 kube-proxy.exe (l2bridge / host-gw)
- nssm install kube-proxy C:\k\kube-proxy.exe
- nssm set kube-proxy AppDirectory c:\k
- nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=<主机名>--kubeconfig=c:\k\config --enable-dsr=false --log-dir=<日志目录> --logtostderr=false
- nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0
- nssm set kube-proxy DependOnService kubelet
- nssm start kube-proxy
-
- # 注册 kube-proxy.exe (overlay / vxlan)
- nssm install kube-proxy C:\k\kube-proxy.exe
- nssm set kube-proxy AppDirectory c:\k
- nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override=<主机名> --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip=<源端 VIP> --enable-dsr=false --log-dir=<日志目录> --logtostderr=false
- nssm set kube-proxy DependOnService kubelet
- nssm start kube-proxy
- ```
-
-
- 作为初始的故障排查操作,你可以使用在 [nssm.exe](https://nssm.cc/) 中使用下面的标志
- 以便将标准输出和标准错误输出重定向到一个输出文件:
-
- ```powershell
- nssm set <服务名称> AppStdout C:\k\mysvc.log
- nssm set <服务名称> AppStderr C:\k\mysvc.log
- ```
-
- 要了解更多的细节,可参见官方的 [nssm 用法](https://nssm.cc/usage)文档。
-
-
-3. 我的 Windows Pods 无发连接网络
-
- 如果你在使用虚拟机,请确保 VM 网络适配器均已开启 MAC 侦听(Spoofing)。
-
-
-4. 我的 Windows Pods 无法 ping 外部资源
-
- Windows Pods 目前没有为 ICMP 协议提供出站规则。不过 TCP/UDP 是支持的。
- 尝试与集群外资源连接时,可以将 `ping ` 命令替换为对应的 `curl ` 命令。
-
- 如果你还遇到问题,很可能你在
- [cni.conf](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf)
- 中的网络配置值得额外的注意。你总是可以编辑这一静态文件。
- 配置的更新会应用到所有新创建的 Kubernetes 资源上。
-
- Kubernetes 网络的需求之一(参见[Kubernetes 模型](/zh/docs/concepts/cluster-administration/networking/))
- 是集群内部无需网络地址转译(NAT)即可实现通信。为了符合这一要求,对所有我们不希望出站时发生 NAT
- 的通信都存在一个 [ExceptionList](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf#L20)。
- 然而这也意味着你需要将你要查询的外部 IP 从 ExceptionList 中移除。
- 只有这时,从你的 Windows Pod 发起的网络请求才会被正确地通过 SNAT 转换以接收到
- 来自外部世界的响应。
- 就此而言,你在 `cni.conf` 中的 `ExceptionList` 应该看起来像这样:
-
- ```conf
- "ExceptionList": [
- "10.244.0.0/16", # 集群子网
- "10.96.0.0/12", # 服务子网
- "10.127.130.0/24" # 管理(主机)子网
- ]
- ```
-
-
-5. 我的 Windows 节点无法访问 NodePort 服务
-
- 从节点自身发起的本地 NodePort 请求会失败。这是一个已知的局限。
- NodePort 服务的访问从其他节点或者外部客户端都可正常进行。
-
-
-6. 容器的 vNICs 和 HNS 端点被删除了
-
- 这一问题可能因为 `hostname-override` 参数未能传递给
- [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) 而导致。
- 解决这一问题时,用户需要按如下方式将主机名传递给 kube-proxy:
+ Kubelet & kube-proxy can be run as native Windows Services using `sc.exe`.
```powershell
- C:\k\kube-proxy.exe --hostname-override=$(hostname)
+ # Create the services for kubelet and kube-proxy in two separate commands
+ sc.exe create binPath= " -service "
+
+ # Please note that if the arguments contain spaces, they must be escaped.
+ sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' "
+
+ # Start the services
+ Start-Service kubelet
+ Start-Service kube-proxy
+
+ # Stop the service
+ Stop-Service kubelet (-Force)
+ Stop-Service kube-proxy (-Force)
+
+ # Query the service status
+ Get-Service kubelet
+ Get-Service kube-proxy
```
+ -->
+ * 以本地 Windows 服务的形式
-
-7. 使用 Flannel 时,我的节点在重新加入集群时遇到问题
-
- 无论何时,当一个之前被删除的节点被重新添加到集群时,flannelD 都会将为节点分配
- 一个新的 Pod 子网。
- 用户需要将将下面路径中的老的 Pod 子网配置文件删除:
-
- ```powershell
- Remove-Item C:\k\SourceVip.json
- Remove-Item C:\k\SourceVipRequest.json
- ```
-
-
-8. 在启动了 `start.ps1` 之后,flanneld 一直停滞在 "Waiting for the Network to be created" 状态
+ # 用两个单独的命令为 kubelet 和 kube-proxy 创建服务
+ sc.exe create <组件名称> binPath="<可执行文件路径> -service <其它参数>"
- 关于这一[正在被分析的问题](https://github.com/coreos/flannel/issues/1066)有很多的报告;
- 最可能的一种原因是关于何时设置 Flannel 网络的管理 IP 的时间问题。
- 一种解决办法是重新启动 `start.ps1` 或者按如下方式手动重启之:
+ # 请注意如果参数中包含空格,必须使用转义
+ sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' <其它参数>"
- ```powershell
- PS C:> [Environment]::SetEnvironmentVariable("NODE_NAME", "")
- PS C:> C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1
- ```
+ # 启动服务
+ Start-Service kubelet
+ Start-Service kube-proxy
-
-9. 我的 Windows Pods 无法启动,因为缺少 `/run/flannel/subnet.env` 文件
-
- 这表明 Flannel 网络未能正确启动。你可以尝试重启 flanneld.exe 或者将文件手动地
- 从 Kubernetes 主控节点的 `/run/flannel/subnet.env` 路径复制到 Windows 工作
- 节点的 `C:\run\flannel\subnet.env` 路径,并将 `FLANNEL_SUBNET` 行改为一个
- 不同的数值。例如,如果期望节点子网为 `10.244.4.1/24`:
-
- ```env
- FLANNEL_NETWORK=10.244.0.0/16
- FLANNEL_SUBNET=10.244.4.1/24
- FLANNEL_MTU=1500
- FLANNEL_IPMASQ=true
+ # 查询服务状态
+ Get-Service kubelet
+ Get-Service kube-proxy
```
-
-10. 我的 Windows 节点无法使用服务 IP 访问我的服务
+ You can also always use alternative service managers like
+ [nssm.exe](https://nssm.cc/) to run these processes (flanneld, kubelet &
+ kube-proxy) in the background for you. You can use this [sample
+ script](https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/register-svc.ps1),
+ leveraging `nssm.exe` to register kubelet, kube-proxy, and `flanneld.exe` to run
+ as Windows services in the background.
+ -->
+ * 使用 nssm.exe
- 这是 Windows 上当前网络协议栈的一个已知的限制。
- Windows Pods 能够访问服务 IP。
-
-
-11. 启动 kubelet 时找不到网络适配器
-
- Windows 网络堆栈需要一个虚拟的适配器,这样 Kubernetes 网络才能工作。
- 如果下面的命令(在管理员 Shell 中)没有任何返回结果,证明虚拟网络创建
- (kubelet 正常工作的必要前提之一)失败了:
+ 你也总是可以使用替代的服务管理器,例如[nssm.exe](https://nssm.cc/),来为你在后台运行
+ 这些进程(`flanneld`、`kubelet` 和 `kube-proxy`)。你可以使用这一
+ [示例脚本](https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/register-svc.ps1),
+ 利用 `nssm.exe` 将 `kubelet`、`kube-proxy` 和 `flanneld.exe` 注册为要在后台运行的
+ Windows 服务。
+
+ ```powershell
+ register-svc.ps1 -NetworkMode <网络模式> -ManagementIP -ClusterCIDR <集群子网> -KubeDnsServiceIP -LogDir <日志目录>
```
- 当宿主系统的网络适配器名称不是 "Ethernet" 时,通常值得更改 `start.ps1` 脚本中的
- [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7)
- 参数来重试。否则可以查验 `start-kubelet.ps1` 的输出,看看是否在虚拟网络创建
- 过程中报告了其他错误。
+ 这里的参数解释如下:
-
+ - `NetworkMode`:网络模式 l2bridge(flannel host-gw,也是默认值)或
+ overlay(flannel vxlan)选做网络方案
+ - `ManagementIP`:分配给 Windows 节点的 IP 地址。你可以使用 ipconfig 得到此值
+ - `ClusterCIDR`:集群子网范围(默认值为 10.244.0.0/16)
+ - `KubeDnsServiceIP`:Kubernetes DNS 服务 IP(默认值为 10.96.0.10)
+ - `LogDir`:kubelet 和 kube-proxy 的日志会被重定向到这一目录中的对应输出文件,
+ 默认值为 `C:\k`。
- Check that your pause image is compatible with your OS version. The [instructions](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/deploying-resources) assume that both the OS and the containers are version 1803. If you have a later version of Windows, such as an Insider build, you need to adjust the images accordingly. Please refer to the Microsoft's [Docker repository](https://hub.docker.com/u/microsoft/) for images. Regardless, both the pause image Dockerfile and the sample service expect the image to be tagged as :latest.
+
-12. 我的 Pods 停滞在 "Container Creating" 状态或者反复重启
+ Register flanneld.exe:
+ -->
+ 若以上所引用的脚本不适合,你可以使用下面的例子手动配置 `nssm.exe`。
- 检查你的 pause 镜像是与你的 OS 版本兼容的。
- [这里的指令](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/deploying-resources)
- 假定你的 OS 和容器版本都是 1803。如果你安装的是更新版本的 Windows,比如说
- 某个 Insider 构造版本,你需要相应地调整要使用的镜像。
- 请参照 Microsoft 的 [Docker 仓库](https://hub.docker.com/u/microsoft/)
- 了解镜像。不管怎样,pause 镜像的 Dockerfile 和示例服务都期望镜像的标签
- 为 `:latest`。
+ 注册 flanneld.exe:
- 从 Kubernetes v1.14 版本起,Microsoft 开始在 `mcr.microsoft.com/k8s/core/pause:1.2.0`
- 发布其 pause 基础设施容器。
-
-
-13. DNS 解析无法正常工作
-
- 参阅 Windows 上 [DNS 相关的局限](#dns-limitations) 节。
-
-
-14. `kubectl port-forward` 失败,错误信息为 "unable to do port forwarding: wincat not found"
-
- 此功能是在 Kubernetes v1.15 中实现的,pause 基础设施容器为 `mcr.microsoft.com/k8s/core/pause:1.2.0`。
- 请确保你使用的是这些版本或者更新版本。
- 如果你想要自行构造你自己的 pause 基础设施容器,要确保其中包含了
- [wincat](https://github.com/kubernetes-sigs/sig-windows-tools/tree/master/cmd/wincat)
-
-
-15. 我的 Kubernetes 安装失败,因为我的 Windows Server 节点在防火墙后面
-
- 如果你处于防火墙之后,那么必须定义如下 PowerShell 环境变量:
-
- ```PowerShell
- [Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:80/", [EnvironmentVariableTarget]::Machine)
- [Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:443/", [EnvironmentVariableTarget]::Machine)
+ ```powershell
+ nssm install flanneld C:\flannel\flanneld.exe
+ nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1
+ nssm set flanneld AppEnvironmentExtra NODE_NAME=
+ nssm set flanneld AppDirectory C:\flannel
+ nssm start flanneld
```
+
+ 注册 kubelet.exe:
+
+ ```powershell
+ # Microsoft 在 mcr.microsoft.com/oss/kubernetes/pause:3.4.1
+ # 发布其基础设施容器镜像
+ nssm install kubelet C:\k\kubelet.exe
+ nssm set kubelet AppParameters --hostname-override= --v=6 --pod-infra-container-image=mcr.microsoft.com/oss/kubernetes/pause:3.4.1 --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns= --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false --log-dir= --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config
+ nssm set kubelet AppDirectory C:\k
+ nssm start kubelet
+ ```
+
+
+ 注册 kube-proxy.exe(二层网桥模式和主机网关模式)
+
+ ```powershell
+ nssm install kube-proxy C:\k\kube-proxy.exe
+ nssm set kube-proxy AppDirectory c:\k
+ nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=--kubeconfig=c:\k\config --enable-dsr=false --log-dir= --logtostderr=false
+ nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0
+ nssm set kube-proxy DependOnService kubelet
+ nssm start kube-proxy
+ ```
+
+
+ 注册 kube-proxy.exe(覆盖网络模式或 VxLAN 模式)
+
+ ```powershell
+ nssm install kube-proxy C:\k\kube-proxy.exe
+ nssm set kube-proxy AppDirectory c:\k
+ nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override= --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip= --enable-dsr=false --log-dir= --logtostderr=false
+ nssm set kube-proxy DependOnService kubelet
+ nssm start kube-proxy
+ ```
+
+
+ 作为初始的故障排查操作,你可以使用在 [nssm.exe](https://nssm.cc/) 中使用下面的标志
+ 以便将标准输出和标准错误输出重定向到一个输出文件:
+
+ ```powershell
+ nssm set <服务名称> AppStdout C:\k\mysvc.log
+ nssm set <服务名称> AppStderr C:\k\mysvc.log
+ ```
+
+ 要了解更多的细节,可参见官方的 [nssm 用法](https://nssm.cc/usage)文档。
+
-15. `pause` 容器是什么?
+* 我的 Windows Pods 无发连接网络
- 在一个 Kubernetes Pod 中,一个基础设施容器,或称 "pause" 容器,会被首先创建出来,
- 用以托管容器端点。属于同一 Pod 的容器,包括基础设施容器和工作容器,会共享相同的
- 网络名字空间和端点(相同的 IP 和端口空间)。我们需要 pause 容器来工作容器崩溃或
- 重启的状况,以确保不会丢失任何网络配置。
+ 如果你在使用虚拟机,请确保 VM 网络适配器均已开启 MAC 侦听(Spoofing)。
- "pause" (基础设施)镜像托管在 Microsoft Container Registry (MCR) 上。
- 你可以使用 `docker pull mcr.microsoft.com/k8s/core/pause:1.2.0` 来访问它。
- 要了解进一步的细节,可参阅 [DOCKERFILE](https://github.com/kubernetes-sigs/sig-windows-tools/tree/master/cmd/wincat)。
+
+* 我的 Windows Pods 无法 ping 外部资源
+
+ Windows Pods 目前没有为 ICMP 协议提供出站规则。不过 TCP/UDP 是支持的。
+ 尝试与集群外资源连接时,可以将 `ping ` 命令替换为对应的 `curl ` 命令。
+
+
+ 如果你还遇到问题,很可能你在
+ [cni.conf](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf)
+ 中的网络配置值得额外的注意。你总是可以编辑这一静态文件。
+ 配置的更新会应用到所有新创建的 Kubernetes 资源上。
+
+
+ Kubernetes 网络的需求之一(参见
+ [Kubernetes 网络模型](/zh/docs/concepts/cluster-administration/networking/))
+ 是集群内部无需网络地址转译(NAT)即可实现通信。
+ 为了符合这一要求,对所有我们不希望出站时发生 NAT 的通信都存在一个
+ [ExceptionList](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf#L20)。
+ 然而这也意味着你需要将你要查询的外部 IP 从 ExceptionList 中移除。
+ 只有这时,从你的 Windows Pod 发起的网络请求才会被正确地通过 SNAT 转换以接收到
+ 来自外部世界的响应。
+ 就此而言,你在 `cni.conf` 中的 `ExceptionList` 应该看起来像这样:
+
+
+ ```conf
+ "ExceptionList": [
+ "10.244.0.0/16", # 集群子网
+ "10.96.0.0/12", # 服务子网
+ "10.127.130.0/24" # 管理(主机)子网
+ ]
+ ```
+
+
+* 我的 Windows 节点无法访问 NodePort 服务
+
+ 从节点自身发起的本地 NodePort 请求会失败。这是一个已知的局限。
+ NodePort 服务的访问从其他节点或者外部客户端都可正常进行。
+
+
+* 容器的 vNICs 和 HNS 端点被删除了
+
+ 这一问题可能因为 `hostname-override` 参数未能传递给
+ [kube-proxy](/zh/docs/reference/command-line-tools-reference/kube-proxy/)
+ 而导致。解决这一问题时,用户需要按如下方式将主机名传递给 kube-proxy:
+
+ ```powershell
+ C:\k\kube-proxy.exe --hostname-override=$(hostname)
+ ```
+
+
+* 使用 Flannel 时,我的节点在重新加入集群时遇到问题
+
+ 无论何时,当一个之前被删除的节点被重新添加到集群时,flannelD 都会将为节点分配
+ 一个新的 Pod 子网。
+ 用户需要将将下面路径中的老的 Pod 子网配置文件删除:
+
+ ```powershell
+ Remove-Item C:\k\SourceVip.json
+ Remove-Item C:\k\SourceVipRequest.json
+ ```
+
+
+* 在启动了 `start.ps1` 之后,flanneld 一直停滞在 "Waiting for the Network
+ to be created" 状态
+
+ 关于这一[问题](https://github.com/coreos/flannel/issues/1066)有很多的报告;
+ 最可能的一种原因是关于何时设置 Flannel 网络的管理 IP 的时间问题。
+ 一种解决办法是重新启动 `start.ps1` 或者按如下方式手动重启之:
+
+ ```powershell
+ [Environment]::SetEnvironmentVariable("NODE_NAME", "")
+ C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1
+ ```
+
+
+* 我的 Windows Pods 无法启动,因为缺少 `/run/flannel/subnet.env` 文件
+
+ 这表明 Flannel 网络未能正确启动。你可以尝试重启 flanneld.exe 或者将文件手动地
+ 从 Kubernetes 主控节点的 `/run/flannel/subnet.env` 路径复制到 Windows 工作
+ 节点的 `C:\run\flannel\subnet.env` 路径,并将 `FLANNEL_SUBNET` 行改为一个
+ 不同的数值。例如,如果期望节点子网为 `10.244.4.1/24`:
+
+ ```none
+ FLANNEL_NETWORK=10.244.0.0/16
+ FLANNEL_SUBNET=10.244.4.1/24
+ FLANNEL_MTU=1500
+ FLANNEL_IPMASQ=true
+ ```
+
+* 我的 Windows 节点无法使用服务 IP 访问我的服务
+
+ 这是 Windows 上当前网络协议栈的一个已知的限制。
+ Windows Pods 能够访问服务 IP。
+
+
+* 启动 kubelet 时找不到网络适配器
+
+ Windows 网络堆栈需要一个虚拟的适配器,这样 Kubernetes 网络才能工作。
+ 如果下面的命令(在管理员 Shell 中)没有任何返回结果,证明虚拟网络创建
+ (kubelet 正常工作的必要前提之一)失败了:
+
+ ```powershell
+ Get-HnsNetwork | ? Name -ieq "cbr0"
+ Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*"
+ ```
+
+
+ 当宿主系统的网络适配器名称不是 "Ethernet" 时,通常值得更改 `start.ps1` 脚本中的
+ [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7)
+ 参数来重试。否则可以查验 `start-kubelet.ps1` 的输出,看看是否在虚拟网络创建
+ 过程中报告了其他错误。
+
+
+* 我的 Pods 停滞在 "Container Creating" 状态或者反复重启
+
+ 检查你的 pause 镜像是与你的 OS 版本兼容的。
+ [这里的指令](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/deploying-resources)
+ 假定你的 OS 和容器版本都是 1803。如果你安装的是更新版本的 Windows,比如说
+ 某个 Insider 构造版本,你需要相应地调整要使用的镜像。
+ 请参照 Microsoft 的 [Docker 仓库](https://hub.docker.com/u/microsoft/)
+ 了解镜像。不管怎样,pause 镜像的 Dockerfile 和示例服务都期望镜像的标签
+ 为 `:latest`。
+
+
+* DNS 解析无法正常工作
+
+ 参阅 Windows 上 [DNS 相关的局限](#dns-limitations) 节。
+
+
+* `kubectl port-forward` 失败,错误信息为 "unable to do port forwarding: wincat not found"
+
+ 此功能是在 Kubernetes v1.15 中实现的,pause 基础设施容器
+ `mcr.microsoft.com/oss/kubernetes/pause:3.4.1` 中包含了 wincat.exe。
+ 请确保你使用的是这些版本或者更新版本。
+ 如果你想要自行构造你自己的 pause 基础设施容器,要确保其中包含了
+ [wincat](https://github.com/kubernetes-sigs/sig-windows-tools/tree/master/cmd/wincat)
+
+
+* 我的 Kubernetes 安装失败,因为我的 Windows Server 节点在防火墙后面
+
+ 如果你处于防火墙之后,那么必须定义如下 PowerShell 环境变量:
+
+ ```PowerShell
+ [Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:80/", [EnvironmentVariableTarget]::Machine)
+ [Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:443/", [EnvironmentVariableTarget]::Machine)
+ ```
+
+
+* `pause` 容器是什么?
+
+ 在一个 Kubernetes Pod 中,一个基础设施容器,或称 "pause" 容器,会被首先创建出来,
+ 用以托管容器端点。属于同一 Pod 的容器,包括基础设施容器和工作容器,会共享相同的
+ 网络名字空间和端点(相同的 IP 和端口空间)。我们需要 pause 容器来工作容器崩溃或
+ 重启的状况,以确保不会丢失任何网络配置。
+
+ "pause" (基础设施)镜像托管在 Microsoft Container Registry (MCR) 上。
+ 你可以使用 `mcr.microsoft.com/oss/kubernetes/pause:3.4.1` 来访问它。
+ 要了解进一步的细节,可参阅
+ [DOCKERFILE](https://github.com/kubernetes-sigs/sig-windows-tools/tree/master/cmd/wincat)。
### 进一步探究 {#further-investigation}
@@ -1520,7 +2257,15 @@ If these steps don't resolve your problem, you can get help running Windows cont
## 报告问题和功能需求 {#reporting-issues-and-feature-requests}
@@ -1533,13 +2278,16 @@ If you have what looks like a bug, or you would like to make a feature request,
生成新的 Ticket 之前对一些想法进行故障分析。
在登记软件缺陷时,请给出如何重现该问题的详细信息,例如:
@@ -1553,7 +2301,11 @@ If filing a bug, please include detailed information about how to reproduce the
## {{% heading "whatsnext" %}}
在我们的未来蓝图中包含很多功能特性(要实现)。下面是一个浓缩的简要列表,不过我们
鼓励你查看我们的 [roadmap 项目](https://github.com/orgs/kubernetes/projects/8)并
@@ -1563,11 +2315,16 @@ We have a lot of features in our roadmap. An abbreviated high level list is incl
### Hyper-V 隔离 {#hyper-v-isolation}
@@ -1575,52 +2332,20 @@ Hyper-V isolation is requried to enable the following use cases for Windows cont
要满足 Kubernetes 中 Windows 容器的如下用例,需要利用 Hyper-V 隔离:
* 在 Pod 之间实施基于监管程序(Hypervisor)的隔离,以增强安全性
-* 出于向后兼容需要,允许添加运行新 Windows Server 版本的节点时不必重新创建容器
+* 出于向后兼容需要,允许添加运行新 Windows Server 版本的节点时不必
+ 重新创建容器
* 为 Pod 设置特定的 CPU/NUMA 配置
* 实施内存隔离与预留
-
-现有的 Hyper-V 隔离支持是添加自 v1.10 版本的实验性功能特性,会在未来版本中弃用,
-向前文所提到的 CRI-ContainerD 和 RuntimeClass 特性倾斜。
-要使用当前的功能特性并创建 Hyper-V 隔离的容器,需要在启动 kubelet 时设置特性门控
-`HyperVContainer=true`,同时为 Pod 添加注解
-`experimental.windows.kubernetes.io/isolation-type=hyperv`。
-在实验性实现版本中,此功能特性限制每个 Pod 中只能包含一个容器。
-
-```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
-```
-
### 使用 kubeadm 和 Cluster API 来部署 {#deployment-with-kubeadm-and-cluster-api}
@@ -1629,15 +2354,3 @@ kubeadm 对 Windows 节点的支持目前还在开发过程中,不过你可以
[指南](/zh/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes/)。
我们也在投入资源到 Cluster API,以确保 Windows 节点被正确配置。
-
-### 若干其他关键功能 {#a-few-other-key-features}
-
-* 为组管理的服务账号(Group Managed Service Accounts,GMSA)提供 Beta 支持
-* 添加更多的 CNI 支持
-* 实现更多的存储插件
-