Windows Server マルチアーキテクチャ イメージのビルド

このチュートリアルでは、複数の Windows Server バージョンをターゲットとするイメージをビルドする際のバージョニングの複雑度を管理する方法について説明します。Windows Server コンテナには、複数の Windows Server ホスト バージョンでコンテナが実行されることを回避するためのバージョンの互換性に関する要件が存在します。ただし、Windows Server の Docker では、複数の Windows Server バージョンで実行できるマルチアーキテクチャ(またはマルチプラットフォーム)コンテナ イメージがサポートされています。

マルチアーキテクチャ イメージを使用することで、イメージを再ビルドして Pod 仕様を変更することなく、Google Kubernetes Engine(GKE)Windows Server のノードプールを任意の Windows Server バージョンにアップグレードできます。次に例を示します。

  • GKE バージョン 1.15 は Windows Server 1809 をサポートしています
  • GKE バージョン 1.16 は Windows Server 1909 をサポートしています

ある GKE バージョンからそれ以降のバージョンに自動的にアップグレードするには、Windows ワークロードのマルチアーキテクチャ イメージをビルドする必要があります。マルチアーキテクチャ イメージをビルドするには、Windows Server のバージョンごとにイメージをビルドしてから、Windows Server の各バージョンに対してそれらのイメージを参照するマニフェストを作成する必要があります。イメージの作成とビルドのプロセスを完全に制御する必要がある場合は、イメージを手動で作成できます。または、Cloud Build を使用して Windows Server マルチアーキテクチャ イメージを自動的にビルドすることもできます。

マルチアーキテクチャ イメージの手動ビルド

マルチアーキテクチャ イメージを手動でビルドすると、必要な 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 VM を作成します(バージョン 20H2 など)。Windows Server VM の使用に関するクイックスタートをご覧ください。
  5. RDP を使用して VM に接続します。
  6. 次の手順で、PowerShell ウィンドウを開いてコマンドを実行します。
  7. docker manifest 試験運用版機能を有効にします。Docker マニフェストは、レジストリに push するイメージのリストです。

    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 リポジトリに push します。

     docker manifest push `
       REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/foo:1.0
    
  10. マルチアーキテクチャ イメージが正常にビルドされて push されたことを確認するには、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 gke-windows-builder をベースとした gke-windows-builder を使用できます。Cloud Build で gke-windows-builder を使用して、Windows Server マルチアーキテクチャ イメージを自動的にビルドできます。リリースされた際にサポート対象の新しい Windows SAC と LTSC が含まれるように、GKE がビルダーを更新します。このビルダーを使用するもう 1 つの利点は、イメージをビルドするために Powershell を使用して独自の Windows VM を作成する必要がないことです。Windows VM は、Cloud Build 内でコマンドを実行する Docker コンテナに置き換えられます。

ビルダーの動作を理解できるように、この例の手順に沿って「hello world」のマルチアーキテクチャ イメージをビルドします。次の手順は、Linux サーバーまたは Windows サーバーで行えます。

環境の準備

環境を準備するには、次の手順を行います。

  1. 作業用マシンにワークスペース ディレクトリを作成します(例: ~/gke-windows-builder/hello-world)。
  2. このチュートリアル用のプロジェクトを作成するか選択します。
  3. プロジェクトに対して課金が有効になっていることを確認します。
  4. Compute Engine、Cloud Build、Artifact Registry の各 API をプロジェクトで使用できるようにします。gke-windows-builder が Cloud Build を使用して呼び出され、その結果として得られるマルチ アーキテクチャ コンテナ イメージが Artifact Registry に push されます。ビルダーで Windows Server VM を作成、管理するには、Compute Engine が必要です。

    gcloud services enable compute.googleapis.com cloudbuild.googleapis.com \
      artifactregistry.googleapis.com cloudbuild.googleapis.com
    
  5. Google Cloud CLI を使用して、Cloud Build サービス アカウントに次の Identity and Access Management(IAM)ロールを付与します。

    1. 変数を設定します。

      export PROJECT=$(gcloud info --format='value(config.project)')
      export MEMBER=$(gcloud projects describe $PROJECT --format 'value(projectNumber)')@cloudbuild.gserviceaccount.com
      
    2. ロールを割り当てます。ビルダーで Windows Server VM を作成して、ワークスペースを Cloud Storage バケットにコピーする場合や、Docker イメージをビルドして Artifact Registry に push できるようにネットワークを構成する場合は、以下のロールが必要です。

      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 VM に接続して 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
    

ビルド構成ファイルを使用してイメージをビルドし、ビルドしたイメージを REGISTRY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/multiarch-helloworld:latest で Artifact Registry に push しました。

イメージのデプロイ

マルチアーキテクチャ Windows イメージをクラスタにデプロイするには、Windows Server アプリケーションのデプロイをご覧になり、イメージをデプロイする方法を確認してください。

gke-windows-builder の高度な使用方法

gke-windows-builder の動作は、cloudbuild.yaml ビルド構成ファイルの args セクションにフラグを追加することでカスタマイズできます。このセクションでは、一般的な動作のフラグの一部について説明しますが、網羅的なリストではありません。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'

GKE がサポートするすべての Windows バージョン用にイメージをビルドする代わりに、--versions フラグを使用して、ビルド対象の Windows Server の特定のバージョンを選択できます。

  - --versions
  - '20H2,ltsc2019'

ワークスペースに多くのファイルがある場合、WinRM ではなく Cloud Storage を介してワークスペースをコピーするようにビルダーを構成すると、イメージビルドの信頼性が向上します。プロジェクトで 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'