构建 Windows Server 多架构映像


本教程展示如何管理构建面向多个 Windows Server 版本的映像的版本控制复杂性。Windows Server 容器具有版本兼容性要求,以防止容器在多个 Windows Server 主机版本上运行。但是,Windows Server 上的 Docker 支持可跨多个 Windows Server 版本运行的多架构(或多平台)容器映像。

通过多架构映像,您可以将 Google Kubernetes Engine (GKE) Windows Server 节点池升级到首选的 Windows Server 版本,而无需重新构建映像并更改 pod 规范。例如:

  • GKE 版本 1.15 支持 Windows Server 1809
  • GKE 版本 1.16 支持 Windows Server 1909

如需自动从一个 GKE 版本升级到更高版本,您必须为 Windows 工作负载构建多架构映像。构建多架构映像包括为每个 Windows Server 版本构建映像,然后构建一个清单来为每个 Windows Server 版本引用这些映像。如果您希望完全控制映像的构建和构建过程,则可以手动构建映像。或者,您也可以使用 Cloud Build 自动构建 Windows Server 多架构映像。

目标

在本教程中,您将了解如何手动或使用 Cloud Build 创建 Windows Server 多架构映像。

  • 手动构建映像:

    • 创建两个具有不同版本或类型 Windows Server 的 Docker 映像,例如,长期服务渠道 (LTSC) 和半年渠道 (SAC)。
    • 创建 Windows Server 虚拟机。
    • 创建清单并将其推送到镜像仓库。
  • 使用 Cloud Build 构建映像:

    • 通过创建项目、启用 API 和授予权限来准备环境。
    • 创建应用、Dockerfile 和构建文件。
    • 运行命令来构建映像。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

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

  1. 安装 Google Cloud CLI 以运行 gcloud 命令。
  2. 安装 Docker 以构建容器。
  3. 安装 Go 以构建 Windows Server 二进制文件。
  4. 本教程使用 Artifact Registry 作为代码库。确保您已创建 Docker 代码库

手动构建多架构映像

手动构建多架构映像可让您灵活地构建包含任何所需 Windows Server 版本的映像。如需手动构建多架构映像,请执行以下操作:

  1. 创建 LTSC 2019 Docker 单架构映像。如需详细了解如何创建 Docker 映像,请参阅部署 Windows Server 应用。例如 us-docker.pkg.dev/my-project/docker-repo/foo:1.0-2019
  2. 创建 LTSC 2022 Docker 单架构映像。例如 us-docker.pkg.dev/my-project/docker-repo/foo:1.0-2022
  3. 创建 SAC 20H2 Docker 单架构映像。例如 us-docker.pkg.dev/my-project/docker-repo/foo:1.0-20h2
  4. 创建 Windows Server 虚拟机,例如版本 20H2。请参阅快速入门:使用 Windows Server 虚拟机
  5. 使用 RDP 连接到该虚拟机。
  6. 打开 PowerShell 窗口,以在后续步骤中运行命令。
  7. 启用 docker manifest 实验性功能。 Docker 清单是要推送到镜像仓库的映像的列表:

    PS C:\> $env:DOCKER_CLI_EXPERIMENTAL = 'enabled'
    
  8. 创建多架构清单:

    docker manifest create `
      REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0 `
      REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0-2019 `
      REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0-2022 `
      REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0-20h2
    
  9. 将新创建的多架构映像清单推送到您的 Artifact Registry 代码库:

     docker manifest push `
       REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0
    
  10. 如需确保成功构建和推送多架构映像,请导航到 REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo 并点击该映像。您会看其中有 3 个映像:

    • foo:1.0-2019
    • foo:1.0-2022
    • foo:1.0-20h2
    • foo:1.0

现在,您可以在 Pod 规范中引用多架构映像 REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0。这样即可安全地为 GKE Windows 节点池使用自动升级功能。

使用 Cloud Build gke-windows-builder 构建多架构映像

为了减少手动构建步骤的工作量,您可以使用基于 OSS windows-builderOSS gke-windows-builder。您可以将 gke-windows-builder 与 Cloud Build 搭配使用,以自动构建 Windows Server 多架构映像。GKE 更新了构建器,会在受支持的新 Windows SAC 和 LTSC 版本发布时包含这些新版本。使用构建器的另一个好处是,您无需创建自己的带有 Powershell 的 Windows 虚拟机来构建映像。Windows 虚拟机会被替换为在 Cloud Build 内部为您运行命令的 Docker 容器。

为了帮助您理解构建器的工作原理,请参照此示例构建一个“hello world”多架构映像。您可以在 Linux 或 Windows 服务器上执行这些步骤。

准备环境

要准备环境,请完成以下步骤:

  1. 在工作机器上创建工作区目录,例如 ~/gke-windows-builder/hello-world
  2. 为本教程创建或选择一个项目。
  3. 确保您的项目已启用结算功能
  4. 为项目启用 Compute Engine、Cloud Build 和 Artifact Registry API。系统会使用 Cloud Build 调用 gke-windows-builder,并将生成的多架构容器映像推送到 Artifact Registry。构建器需要 Compute Engine 才能创建和管理 Windows Server 虚拟机。

    gcloud services enable compute.googleapis.com cloudbuild.googleapis.com \
      artifactregistry.googleapis.com cloudbuild.googleapis.com
    
  5. 使用 Google Cloud CLI 将以下 Identity and Access Management (IAM) 角色授予您的 Cloud Build 服务账号:

    1. 设置变量:

      export PROJECT=$(gcloud info --format='value(config.project)')
      export MEMBER=$(gcloud projects describe $PROJECT --format 'value(projectNumber)')@cloudbuild.gserviceaccount.com
      
    2. 分配角色。构建器需要这些角色来创建 Windows Server 虚拟机、将工作区复制到 Cloud Storage 存储桶、配置网络来构建 Docker 映像,以及将生成的映像推送到 Artifact Registry:

      gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$MEMBER --role='roles/compute.instanceAdmin'
      gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$MEMBER --role='roles/iam.serviceAccountUser'
      gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$MEMBER --role='roles/compute.networkViewer'
      gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$MEMBER --role='roles/storage.admin'
      gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$MEMBER --role='roles/artifactregistry.writer'
      
  6. 添加一个名为 allow-winrm-ingress 的防火墙规则,以允许 WinRM 连接到 Windows Server 虚拟机来运行 Docker 构建:

    gcloud compute firewall-rules create allow-winrm-ingress --allow=tcp:5986 --direction=INGRESS
    
  7. 在 Artifact Registry 中为您的项目创建一个 Docker 代码库。如果您之前从未在 Artifact Registry 中使用 Docker 代码库,请先完成 Docker 快速入门。请运行以下命令,创建代码库。

    gcloud artifacts repositories create REPOSITORY \
      --repository-format=docker --location=REGISTRY_REGION \
      --description="Docker repository"
    

    替换以下内容:

在工作区中创建 hello.exe 二进制文件

在本教程中,您将创建一个使用 Go 编写的简单“hello world”应用。示例应用的代码在 GitHub 上

  1. 使用以下命令将包含本教程的示例代码的代码库克隆到本地机器:

     git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
     cd kubernetes-engine-samples/windows/windows-multi-arch
    
  2. hello.go 文件输出“Hello World”:

    package main
    
    import "fmt"
    
    func main() {
    	fmt.Println("Hello World!")
    }
    
  3. 生成 hello.exe 二进制文件:

    GOOS=windows go build hello.go
    

您将在工作区中看到 hello.exe 二进制文件。

在工作区中创建 Dockerfile 和构建文件

在本部分中,您将使用 Dockerfile 构建每个单一架构 Windows Server 映像,然后使用构建文件触发 Cloud Build。构建会将单架构映像组合成多架构映像。

  1. Dockerfile 是文本文档,其中包含 Docker 如何构建映像的说明。gke-windows-builder 会将 WINDOWS_VERSION 替换成为之构建映像的特定 Windows Server 版本。例如,构建器将在 Windows Server 20H2 中运行 docker build -t multi-arch-helloworld:latest_20h2 --build-arg WINDOWS_VERSION=20H2 .

    ARG WINDOWS_VERSION=
    FROM mcr.microsoft.com/windows/servercore:${WINDOWS_VERSION}
    COPY hello.exe /hello.exe
    USER ContainerUser
    ENTRYPOINT ["hello.exe"]
  2. 在包含 Dockerfile 的同一目录中,cloudbuild.yaml 文件是您的构建配置文件。将 <REPOSITORY><REGISTRY_REGION> 替换为您在上一步中创建的 Artifact Registry 代码库的名称和区域。构建时,Cloud Build 会自动将 $PROJECT_ID 替换为您的项目 ID。

    timeout: 3600s
    steps:
    - name: 'us-docker.pkg.dev/gke-windows-tools/docker-repo/gke-windows-builder:latest'
      args:
      - --container-image-name
      # Replace <REGISTRY_REGION> and <REPOSITORY>.
      - '<REGISTRY_REGION>-docker.pkg.dev/$PROJECT_ID/<REPOSITORY>/multiarch-helloworld:latest'
      # Specify specific variants of images to be built. Or, remove the following 2 lines to default to all available variants.
      - --versions
      - '20H2,ltsc2019'

构建映像

现在,您可以构建映像并查看日志以验证构建是否成功。

  1. 要构建映像,请运行以下命令:

    gcloud builds submit --config=cloudbuild.yaml .
    
  2. 您将看到类似以下示例的日志。日志的最后一行显示构建成功:

    Creating temporary tarball archive of 2 file(s) totalling 492 bytes before compression.
    Uploading tarball of [.] to [gs://PROJECT_ID_cloudbuild/source/1600082502.509759-b949721a922d462c94a75da9be9f1181.tgz]
    Created [https://cloudbuild.googleapis.com/v1/projects/PROJECT_ID/builds/ec333452-1301-47e8-90e2-716aeb2f5650].
    Logs are available at [https://console.cloud.google.com/cloud-build/builds/ec333452-1301-47e8-90e2-716aeb2f5650?project=840737568665].
    ------------------------ REMOTE BUILD OUTPUT---------------------------------------
    ...
    ...
    
    Created manifest list REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/multiarch-helloworld:latest
    sha256:3ecbbc9f5144f358f81f7c7f1a7e28f069c98423d59c40eaff72bf184af0be02
    2020/09/14 11:34:25 Instance: 35.184.178.49 shut down successfully
    PUSH
    DONE
    -----------------------------------------------------------------------------------
    
    ID                                    CREATE_TIME                DURATION  SOURCE                                                                                      IMAGES  STATUS
    ec333452-1301-47e8-90e2-716aeb2f5650  2020-09-14T11:21:43+00:00  12M43S    gs://PROJECT_ID_cloudbuild/source/1600082502.509759-b949721a922d462c94a75da9be9f1181.tgz  -                 SUCCESS
    

您刚刚使用构建配置文件构建了映像并将映像推送到了位于 Artifact Registry (REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/multiarch-helloworld:latest)。

部署映像

要将多架构 Windows 映像部署到集群,请参阅部署 Windows Server 应用,了解如何部署映像。

高级 gke-windows-builder 用法

您可以通过将标志添加到 cloudbuild.yaml build 配置文件的 args 部分来自定义 gke-windows-builder 的行为。本部分介绍了用于常见行为的一些标志,但内容并非详尽无遗。要查看 gke-windows-builder 支持的标志的完整列表,请在 Linux 服务器或 Cloud Shell 中运行以下命令:

docker run -it us-docker.pkg.dev/gke-windows-tools/docker-repo/gke-windows-builder:latest --help

为加快构建速度,您可以为 Windows 实例使用资源规模更大的机器类型:

  - --machineType
  - 'n1-standard-8'

您可以使用 --versions 标志选择要为哪个特定 Windows Server 版本构建映像,而非为 GKE 支持的所有 Windows 版本构建映像:

  - --versions
  - '20H2,ltsc2019'

如果您的工作区有许多文件,但如果您将构建器配置为通过 Cloud Storage(而非 WinRM)复制工作区,您的映像构建将变得更加可靠。在项目中创建一个存储分区(例如 gs://{your project}_builder),然后设置 --workspace-bucket 标志:

  - --workspace-bucket
  - '{your project}_builder'

要在共享 VPC 服务项目中运行 Windows 构建器实例,请使用以下标志(它们控制实例的网络设置):

  - --subnetwork-project
  - 'shared-vpc-host-project'
  - --subnetwork
  - 'host-project-subnet-shared-with-service-project'

清理

完成本教程后,您可以清理您创建的资源,让它们停止使用配额,以免产生费用。以下部分介绍如何删除或关闭这些资源。

删除映像

如需删除 Artifact Registry 上的 multiarch-helloworld 映像,请参阅删除映像

删除项目

为了避免产生费用,最简单的方法是删除您为本教程创建的项目。

如需删除项目,请执行以下操作:

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤