使用 Windows Server 节点池创建集群

在本页面中,您将了解如何使用运行 Microsoft Windows Server 的节点池创建 Google Kubernetes Engine (GKE) 集群。在此集群中,您可以使用 Windows Server 容器。目前不支持 Microsoft Hyper-V 容器。 与 Linux 容器类似,Windows Server 容器提供进程和命名空间隔离机制。

Windows Server 节点需要的资源比典型 Linux 节点更多。Windows Server 节点需要使用额外资源来运行 Windows 操作系统和无法在容器中运行的 Windows Server 组件。由于 Windows Server 节点需要更多资源,因此与 Linux 节点相比,可分配的资源会更少。

使用 Windows Server 节点池创建集群

在本部分中,您将创建一个使用 Windows Server 容器的集群。

为创建此集群,您需要完成以下任务:

  1. 更新并配置 gcloud
  2. 选择您的节点映像。
  3. 创建集群和节点池。
  4. 获取 kubectl 凭据。
  5. 等待集群初始化。

更新并配置 gcloud

在开始之前,请确保您已执行以下任务:

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 选择默认的 Compute Engine 区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project project-id
  • 如果您使用的是区域级集群,请设置默认计算区域
    gcloud config set compute/zone compute-zone
  • 如果您使用的是地区级集群,请设置默认计算地区
    gcloud config set compute/region compute-region
  • gcloud 更新到最新版本:
    gcloud components update

选择您的 Windows Server 节点映像

如需在 GKE 上运行,您需要基于 Windows Server 版本 2019 (LTSC) 或 Windows Server 版本 1909 (SAC) 构建 Windows Server 容器节点映像。一个集群可以具有多个使用不同 Windows Server 版本的 Windows Server 节点池,但每个单独的节点池只能使用一个 Windows Server 版本。

在选择映像类型时,请考虑以下事项:

  • Microsoft 仅在 SAC 版本首次发布后的 18 个月内对其提供支持。如果您为节点池映像类型选择 SAC,但不将节点池升级到面向较新 SAC 版本的较新 GKE 版本,在 SAC 版本的支持生命周期结束后,您就无法在节点池中创建新节点。

  • 只有在您可以升级节点池以及在其中定期运行的容器时,才选择 SAC。GKE 会定期在新的 GKE 版本中更新 Windows 节点池所用的 SAC 版本,因此为您的节点池映像类型选择 SAC 需要您更加频繁地重新构建容器。

  • 新的 Windows Server 功能通常会先引入 SAC 版本。因此,新的 GKE Windows 功能可能会先引入 SAC 节点池。

如果您不确定要使用哪种 Windows Server 映像类型,我们建议选择 Windows Server LTSC,以避免在升级节点池时出现版本不兼容问题。如需了解详情,请参阅 Microsoft 文档中的 Windows Server 服务渠道:LTSC 和 SAC

版本兼容性

Windows Server CoreNano Server 均可用作容器的基础映像。

Windows Server 容器具有重要的版本兼容性要求:

  • 针对 LTSC 构建的 Windows Server 容器不会在 SAC 节点上运行,反之亦然。
  • 如果没有面向其他 LTSC 或 SAC 版本来重新构建,那么针对特定 LTSC 或 SAC 版本构建的 Windows Server 容器便不会在其他这些版本上运行。

若将 Windows Server 容器映像构建为可面向多个 Windows Server 版本的多架构映像,便可帮助您管理这种版本控制复杂性。

版本映射

Microsoft 大约每 6 个月发布一次新的 SAC 版本,每 2 至 3 年发布一次新的 LTSC 版本。这些新版本通常会在新的 GKE 次要版本中提供。在 GKE 次要版本中,LTSC 和 SAC 版本通常保持不变。

下表显示了 GKE 版本与 Windows Server Core 版本之间的对应关系:

GKE 版本 SAC 版本 LTSC 版本
1.14.x(仅限抢先体验版) 10.0.17763(Windows Server Core 1809 版本)
1.15.x(仅限抢先体验版) 10.0.17763(Windows Server Core 1809 版本)
1.16.4-gke.25 - 1.16.7.x(仅限 Beta 版) 10.0.18363.592(Windows Server Core 1909 版本) 10.0.17763.973 (Windows Server 2019 Core)
1.16.8-gke.8+ 10.0.18363.720(Windows Server Core 1909 版本) 10.0.17763.1098 (Windows Server 2019 Core)
1.17.x 10.0.18363.720(Windows Server Core 1909 版本) 10.0.17763.1098 (Windows Server 2019 Core)

创建集群和节点池

如需运行 Windows Server 容器,您的集群必须至少具有一个 Windows 节点池和一个 Linux 节点池。不能仅使用 Windows Server 节点池创建集群。如需运行关键集群插件,您需要使用 Linux 节点池。

鉴于 Linux 节点池的重要性,请不要将其大小调为零,并确保其具有足够的容量来运行集群插件。

gcloud

使用以下字段创建集群:

  gcloud container clusters create cluster-name \
    --enable-ip-alias \
    --num-nodes=number-of-nodes \
    --cluster-version=version-number

其中:

  • cluster-name 是您为集群选择的名称。
  • --enable-ip-alias 表示启用别名 IP 地址。别名 IP 是 Windows Server 节点的必需设置。如需详细了解使用别名 IP 的优势,请参阅了解使用别名 IP 的原生容器路由
  • number-of-nodes 指定您所创建的 Linux 节点数量。 您应该提供足够的计算资源以用于运行集群插件。这是一个可选字段,如果省略,则使用默认值 3。
  • version-number 必须为 1.16.8-gke.9 或更高版本。您还可以使用 --release-channel 标志来选择默认版本为 1.16.8-gke.9 或更高版本的发布渠道。

使用以下字段创建 Windows Server 节点池。

  gcloud container node-pools create node-pool-name \
    --cluster=cluster-name \
    --image-type=image-name \
    --no-enable-autoupgrade \
    --machine-type=machine-type-name

其中:

  • node-pool-name 是您为 Windows Server 节点池选择的名称。
  • cluster-name 是您在上面创建的集群的名称。
  • image-nameWINDOWS_SACWINDOWS_LTSC。如需详细了解这些节点映像,请参阅选择 Windows 节点映像部分。
  • --no-enable-autoupgrade 表示停用节点自动升级功能。 启用前,请先查看升级 Windows Server 节点池
  • machine-type-name 定义机器类型。n1-standard-2 是建议机器类型的最低要求,因为 Windows Server 节点需要更多资源。不支持 f1-microg1-small 机器类型。每种机器类型的计费方式都各不相同。如需了解详情,请参阅机器类型价格表

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 点击创建集群按钮。

  3. 集群基本信息部分,完成以下操作:

    1. 为集群输入名称
    2. 对于位置类型,请为集群选择所需的区域或地区
    3. 主版本下,选择 1.16.8-gke.9 或更高版本的静态版本
      或者,
      主版本下,选择默认版本为 1.16.8-gke.9 或更高版本的发布版本
  4. 在导航窗格的节点池下,点击 default-pool 以创建 Linux 节点池。配置此节点池时,您应该提供足够的计算资源以用于运行集群插件。您还必须具有节点及其资源(例如防火墙路由)的可用资源配额

  5. 在页面顶部,点击添加节点池以创建 Windows Server 节点池。

  6. 节点池详情部分,完成以下操作:

    1. 输入节点池名称
    2. 为您的节点选择节点版本
    3. 输入要在节点池中创建的节点数
  7. 在导航窗格的节点池下,点击节点

    1. 映像类型下拉列表中,选择 Windows Server 半年渠道Windows Server 长期服务渠道。如需详细了解这些节点映像,请参阅选择 Windows 节点映像部分。
    2. 选择要用于实例的默认机器配置n1-standard-2 是建议的最小大小,因为 Windows Server 节点需要更多资源。不支持 f1-microg1-small 机器类型。每种机器类型的计费方式都各不相同。如需了解详情,请参阅机器类型价格表
  8. 从导航窗格中,选择 Windows Server 节点池的名称。您会返回到节点池详情页面。

    1. 自动化下,取消选择启用节点自动升级。启用前,请先查看升级 Windows Server 节点池部分。
  9. 从导航窗格中,选择网络

    1. 高级网络选项下,确保选中启用 VPC 原生流量路由(使用别名 IP)。别名 IP 是 Windows Server 节点的必需设置。如需详细了解使用别名 IP 的优势,请参阅了解使用别名 IP 的原生容器路由
  10. 点击创建

Terraform

您可以使用 Google Terraform 提供程序创建具有 Windows Server 节点池的 GKE 集群。

将此代码块添加到您的 Terraform 配置:

resource "google_container_cluster" "cluster" {
  project  = "project-id"
  name     = "cluster-name"
  location = "location"

  min_master_version = "version-number"

  # Enable Alias IPs to allow Windows Server networking.
  ip_allocation_policy {
    cluster_ipv4_cidr_block  = "/14"
    services_ipv4_cidr_block = "/20"
  }

  # Removes the implicit default node pool, recommended when using
  # google_container_node_pool.
  remove_default_node_pool = true
  initial_node_count       = 1
}

# Small Linux node pool to run some Linux-only Kubernetes Pods.
resource "google_container_node_pool" "linux_pool" {
  name     = "linux-pool"
  project  = google_container_cluster.cluster.project
  cluster  = google_container_cluster.cluster.name
  location = google_container_cluster.cluster.location

  node_config {
    image_type = "COS_CONTAINERD"
  }
}

# Node pool of Windows Server machines.
resource "google_container_node_pool" "windows_pool" {
  name     = "node-pool-name"
  project  = google_container_cluster.cluster.project
  cluster  = google_container_cluster.cluster.name
  location = google_container_cluster.cluster.location

  node_config {
    image_type   = "image-name"
    machine_type = "machine-type-name"
  }

  # The Linux node pool must be created before the Windows Server node pool.
  depends_on = [google_container_node_pool.linux_pool]
}

替换以下内容:

  • project-id 是创建集群的项目 ID。
  • cluster-name 是 GKE 集群的名称。
  • location 是创建集群的位置(地区或区域)。
  • version-number 必须为 1.16.8-gke.9 或更高版本。
  • node-pool-name 是您为 Windows Server 节点池选择的名称。
  • image-nameWINDOWS_SACWINDOWS_LTSC。如需详细了解这些节点映像,请参阅选择 Windows 节点映像部分。
  • machine-type-name 定义机器类型。n1-standard-2 是建议机器类型的最低要求,因为 Windows Server 节点需要更多资源。不支持 f1-microg1-small 机器类型。每种机器类型的计费方式都各不相同。如需了解详情,请参阅机器类型价格表

创建 Windows Server 节点池后,随着控制层面(主服务器)的更新,集群会进入 RECONCILE 状态几分钟。

获取 kubectl 凭据

使用 get-credentials 命令启用 kubectl,以处理您创建的集群。

gcloud container clusters get-credentials 

如需详细了解 get-credentials 命令,请参阅 SDK get-credentials 文档。

等待集群初始化

在使用集群之前,请等待几秒钟,直到 windows.config.common-webhooks.networking.gke.io 创建完毕。该网络钩子会为使用 kubernetes.io/os: windows 节点选择器创建的 Pod 添加调度容忍机制,以确保这些 Pod 可以在 Windows Server 节点上运行。此外,它还会验证 Pod,以确保其仅使用 Windows 上支持的功能。

如需确保该网络钩子成功创建,请运行以下命令:

kubectl get mutatingwebhookconfigurations

输出应显示该网络钩子正在运行:

NAME                                              CREATED AT
windows.config.common-webhooks.networking.gke.io  2019-12-12T16:55:47Z

现在,您的集群已包含两个节点池(一个 Linux 节点池和一个 Windows 节点池),接下来您就可以部署 Windows 应用了。

升级 Windows Server 节点池

Windows Server 容器版本兼容性要求意味着在升级节点池之前,您的容器映像可能需要进行重新构建以匹配新 GKE 版本的 Windows Server 版本。

为确保您的容器映像与节点保持兼容,我们建议您检查版本映射表,并将 Windows Server 容器映像构建为可面向多个 Windows Server 版本的多架构映像。然后,您可以更新容器部署,以面向适用于当前和下一个 GKE 版本的多架构映像,然后再手动调用 GKE 节点池升级。 必须定期进行手动节点池升级,因为节点版本不能低于控制层面版本后的两个次要版本。

我们建议,只有在您持续构建面向最新 Windows Server 版本的多架构 Windows Server 容器映像时(尤其是在您将 Windows Server SAC 用作节点映像类型时),才启用节点自动升级。节点自动升级不太可能导致 Windows Server LTSC 节点映像类型的相关问题,但仍有遇到版本不兼容问题的风险。

Windows 更新

Windows Server 节点的 Windows 更新已停用。自动更新可能会导致节点在不可预测的时间点重启,而在 GKE 重新创建节点后,在该节点启动后安装的任何 Windows 更新都将丢失。GKE 对新 GKE 版本中使用的 Windows Server 节点映像定期更新,从而提供 Windows 更新。 Microsoft 发布 Windows 更新与 GKE 中提供 Windows 更新之间可能存在延迟。关键安全更新发布后,GKE 会尽快更新 Windows Server 节点映像。

查看和查询日志

GKE 集群会自动启用日志记录功能。您可以使用 Kubernetes Engine Monitoring 查看容器的日志和 Windows 服务器节点上其他服务的日志。

以下是用于获取容器日志的过滤条件示例:

resource.type="k8s_container"
resource.labels.cluster_name="your_cluster_name"
resource.labels.namespace_name="your_namespace_id"
resource.labels.container_name="your_container_name"
resource.labels.Pod_name="your_Pod_name"

使用远程桌面协议 (RDP) 访问 Windows Server 节点

您可以使用 RDP 连接到集群中的 Windows Server 节点。如需了解如何进行连接,请参阅 Compute Engine 文档中的连接到 Windows 实例

构建多架构映像

Docker 支持多架构(或多平台)映像。使用多架构映像时,节点上的容器运行时可以拉取平台的兼容映像。 如需构建多架构映像清单,您需要先为每个平台构建映像,然后再为每个平台构建引用这些映像的清单。

如需构建多架构映像清单,请执行以下操作:

  1. 创建 LTSC 2019 Docker 映像,例如 gcr.io/my-project/foo:1.0-2019
  2. 创建 SAC 1909 Docker 映像,例如 gcr.io/my-project/foo:1.0-1909
  3. 创建 Windows Server 1909 虚拟机。
  4. 使用 RDP 连接到该虚拟机。
  5. 运行 PowerShell。
  6. 启用 docker manifest 实验性功能。
    PS C:> $env:DOCKER_CLI_EXPERIMENTAL = 'enabled'
    
  7. 创建多架构清单。
    docker manifest create gcr.io/my-project/foo:1.0 gcr.io/my-project/foo:1.0-2019 gcr.io/my-project/foo:1.0-1909
    
  8. 推送新创建的清单。
    docker manifest push gcr.io/my-project/foo:1.0 gcr.io/my-project/foo:1.0-2019 gcr.io/my-project/foo:1.0-1909
    

删除 Windows Server 节点池

使用 gcloud 或 Google Cloud Console 删除 Windows Server 节点池。

gcloud

gcloud container node-pools delete --cluster=cluster-name node-pool-name

控制台

若要使用 Cloud Console 删除 Windows Server 节点池,请执行以下步骤:

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 点击包含要删除的节点池的集群旁边的修改图标(形似铅笔)。

  3. 节点池部分下,点击要删除的节点池旁边的删除图标(形似垃圾箱形)。

  4. 当系统提示您确认时,再次点击删除

限制

某些 Kubernetes 功能尚不受 Windows Server 容器支持。此外,某些功能是专门针对 Linux,而不适用于 Windows。如需查看受支持和不受支持的 Kubernetes 功能的完整列表,请参阅 Kubernetes 文档

此外,某些 GKE 功能也不受支持。

对于集群,Windows Server 节点池不支持以下功能:

对于 Windows Server 节点池,以下功能不受支持:

问题排查

如需了解有关调试 PodService 的一般指导信息,请参阅 Kubernetes 文档。

Windows Pod 无法启动

若 Windows Server 容器与尝试运行该容器的 Windows 节点之间的版本不匹配,则可能会导致 Windows Pod 无法启动。

如果您的 Windows 节点池版本为 1.16.8-gke.8 或更高版本,请查看关于 2020 年 2 月 Windows Server 容器不兼容问题的 Microsoft 文档并使用基础 Windows 映像(包含 2020 年 3 月之后的 Windows 更新)构建容器映像。基于较早的基础 Windows 映像构建的容器映像可能无法在这些 Windows 节点上运行,并且还可能会导致节点出现状态为 NotReady 的故障。

映像拉取错误

Windows Server 容器映像及其所含的各个层可能非常大。它们的大小可能会导致 Kubelet 在下载和提取容器层时发生超时和失败。

如果您的 Pod 出现“Failed to pull image”或“Image pull context cancelled”错误消息,或者出现 ErrImagePull 状态,则可能是遇到了此问题。

尝试使用以下选项成功拉取 Windows Server 容器:

  • 将 Windows Server 容器映像的应用层拆分为多个更便于拉取和提取的较小层。这样可以提高 Docker 层缓存的效率,以及映像拉取的重试成功概率。如需详细了解各映像层,请参阅 Docker 文章关于映像、容器和存储驱动程序

  • 在创建 Pod 之前,连接到 Windows Server 节点并在容器映像上手动使用 docker pull 命令。

  • kubelet 服务设置 image-pull-progress-deadline 标志,以增加容器映像的拉取超时时间。

    通过连接到 Windows 节点并运行以下 PowerShell 命令来设置此标志。

    1. 从 Windows 注册表获取 Kubelet 服务的现有命令行。

      PS C:\> $regkey = "HKLM\SYSTEM\CurrentControlSet\Services\kubelet"
      
      PS C:\> $name = "ImagePath"
      
      PS C:\> $(reg query ${regkey} /v ${name} | Out-String) -match `
      "${name}.*(C:.*kubelet\.exe.*)\r"
      
      PS C:\> $kubelet_cmd = $Matches[1]
      
    2. 为 Kubelet 服务设置新的命令行,并添加一个额外标志来增加超时时间。

      PS C:\> reg add ${regkey} /f /v ${name} /t REG_EXPAND_SZ /d "${kubelet_cmd} `
      --image-pull-progress-deadline=15m
      
    3. 确认更改成功。

      PS C:\> reg query ${regkey} /v ${name}
      
    4. 重启 kubelet 服务,以使新标志生效。

      PS C:\> Restart-Service kubelet
      
    5. 确认 kubelet 服务已成功重启。

      PS C:\> Get-Service kubelet # ensure state is Running
      

创建节点池期间超时

如果您要创建大量节点(例如 500 个),并且节点池是集群中使用 Windows Server 映像的第一个节点池,则其创建可能会超时。

如需解决此问题,请减少要创建的节点数。您可以稍后增加节点数。

使用 gMSA

如果您在使用组托管式服务帐号 (gMSA) 时遇到问题,这可能是因为 Active Directory 中的计算机名称限制。Active Directory 将计算机名称限制为 15 个字符。如果您使用的是 GKE,此名称会派生自 GKE 节点名称。 节点名称来自于节点池名称,并后接唯一字符串。 如果节点的名称超过 15 个字符,系统会将其截断至 15 个字符。

例如,如果某一节点的名称为 gke-cluster-windows--node-pool-window-3d3afc34- wnnn,则该名称将被截断为 GKE-CLUSTER-WIN

如果另一节点的名称为 gke-cluster-windows--node-pool-window-123gtj12-aabb,则该名称也会被截断为 GKE-CLUSTER-WIN

在 Active Directory 中,计算机和名称之间存在一对一的关系,因此,如果两台计算机共用一个名称,则会出现错误。

为避免此问题,请在加入 Active Directory 时重命名计算机。为计算机重命名后,您还需要更新节点的 kubelet 和 kube-proxy 配置,以防止出现问题,导致节点无法连接到集群。为此,您可以将 --hostname-override 标志附加到 kubelet 和 kube-proxy 服务路径末尾。请将该标志设置为节点的实例名称,然后重启这些服务。

如需更新配置,请运行以下命令:

sc.exe config service-name binPath="existing-service-binpath --hostname-override=node-instance-name"

其中:

  • service-namekubeletkube-proxy。针对每项服务运行一次该脚本。
  • existing-service-binpath 是该服务的 binPath。您可以使用 sc.exe qc service-name 检索此内容。
  • node-instance-name 是节点虚拟机的实例名称。

如此便可解决问题,并使节点和主机 Pod 得以恢复。此外,还可避免 Active Directory 中的名称冲突。

关于 Managed Service for Microsoft Active Directory 的说明

Managed Service for Microsoft Active Directory 中,设置 gMSA 需要执行一些额外的步骤。由于 Managed Microsoft AD 中的默认对象和权限与标准 AD 存在一些差异,因此该过程会稍有不同。了解如何在 Managed Microsoft AD 中创建 gMSA

Windows 节点变为 NotReady,出现错误:“PLEG 运行状况不佳”

这是一个已知的 Kubernetes 问题,在单个 Windows 节点上以非常快的速度启动多个 Pod 时,就会发生此问题。如需从此情况中恢复,请重启 Windows Server 节点。为避免此问题,建议的一种解决方法是将创建 Windows Pod 的速率限制为每 30 秒创建一个 Pod。

不一致的 TerminationGracePeriod

容器的 Windows 系统超时设置可能与您配置的宽限期不同。这种差异可能会导致 Windows 在传递到运行时的宽限期结束之前强制终止容器。

您可以通过在构建映像时修改容器本地注册表项来修改 Windows 超时设置。如果您修改了 Windows 超时设置,则可能还需要调整 TerminationGracePeriodSeconds 以使其匹配。

网络连接问题

如果您在 Windows Server 容器中遇到网络连接问题,可能是因为 Windows Server 容器网络通常假定网络 MTU 为 1500,而该 MTU 与 Google Cloud 的 MTU 1460 不兼容。

请检查容器中网络接口的 MTU 以及 Windows Server 节点本身的网络接口的 MTU 是否均不超过 1460。如需了解如何设置 MTU,请参阅 Windows 容器的已知问题

后续步骤