透過程式輔助方式建立自訂 OS 映像檔管道

您可以使用 gcloud CLI、Terraform 或 Go 等用戶端程式庫,透過程式輔助方式設定及提交 Image Builder 管道。透過程式輔助方式設定管道,即可在宣告式設定檔中定義基礎架構設定、基本 OS 映像檔、自訂動作和驗證測試。

事前準備

  • 完成「準備環境」中的環境設定步驟。
  • 如果您打算使用 Terraform 部署管道,或從存放區自動建構,請使用 Cloud Build 存放區 (2nd gen) 或 Developer Connect 連線連結,連結 GitHub、GitLab 或 Bitbucket 存放區。
  • 如要使用 Terraform,請安裝 Terraform CLI 1.3 以上版本。
  • 如果尚未設定驗證,請先完成設定。驗證程序會確認您的身分,以便授予 Google Cloud 服務和 API 的存取權。如要從本機開發環境執行程式碼或範例,您可以選取下列其中一個選項,向 Compute Engine 進行驗證:

    請根據您打算如何使用本頁範例,選取對應的分頁標籤:

    gcloud

    1. 安裝 Google Cloud CLI。 安裝完成後,請執行下列指令,初始化 Google Cloud CLI:

      gcloud init

      若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI。

  • 設定預設區域和可用區。
  • Terraform

    如要在本機開發環境中使用本頁的 Terraform 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI。

    3. 如果您使用的是本機殼層,請為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果您使用的是 Cloud Shell,則不必執行這項操作。

      如果系統傳回驗證錯誤,且您使用的是外部識別資訊提供者 (IdP),請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

    Go

    如要在本機開發環境中使用本頁面的 Go 範例,請安裝並初始化 gcloud CLI,然後使用使用者憑證設定應用程式預設憑證。

    1. 安裝 Google Cloud CLI。

    2. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI。

    3. 如果您使用的是本機殼層,請為使用者帳戶建立本機驗證憑證:

      gcloud auth application-default login

      如果您使用的是 Cloud Shell,則不必執行這項操作。

      如果系統傳回驗證錯誤,且您使用的是外部識別資訊提供者 (IdP),請確認您已 使用聯合身分登入 gcloud CLI。

    詳情請參閱「 為本機開發環境設定驗證機制」。

必要的角色

如要取得透過程式建立及提交圖片自訂管道所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

建立設定檔

如要使用 gcloud CLI 或 Terraform 設定管道,請建立兩個設定檔:

  • imagebuilder.yaml:定義映像檔的自訂配方,包括基礎 OS 映像檔、worker VM 基礎架構設定、目標映像檔輸出詳細資料,以及依序執行的自訂步驟,例如執行殼層指令碼、傳輸檔案或重新啟動。
  • cloudbuild.yaml:在 Cloud Build 中自動調度建構程序步驟,包括剖析、驗證、建構、測試及發布自訂 OS 映像檔。

如果您使用 Go 提交建構作業,則只需建立 imagebuilder.yaml 檔案並上傳至 Cloud Storage bucket,因為 Go 範例會在程式碼中定義 Cloud Build 協調步驟。

建立映像檔設定檔

如要指定映像檔設定,請在本機目錄中建立名為 imagebuilder.yaml 的檔案。如需所有支援的結構定義欄位和自訂動作完整清單,請參閱「自訂配方結構定義」和「支援的自訂動作」。

下列 imagebuilder.yaml 檔案範例會設定管道,使用指定區域和可用區中的 e2-standard-4 worker VM 建構自訂 Ubuntu 22.04 LTS 映像檔,並執行系統套件更新。

apiVersion: imagebuilder.gcp.com/v1
kind: OSImageCustomization
metadata:
  name: customized-ubuntu-baseline
  description: "Ubuntu 22.04 LTS custom OS baseline image"
infrastructureConfig:
  machineType: e2-standard-4
  zone: ZONE
  debug: false
source:
  imageFamily: projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts
destinations:
  - diskImage:
      name: custom-ubuntu-v1
      family: custom-ubuntu-family
      project: PROJECT_ID
      storageLocations:
        - REGION
spec:
  config:
    skipSystemTests: false
  steps:
    -   name: "System Package Update"
      action: Shell
      inputs:
        command: "apt-get update -y && apt-get upgrade -y"

替換下列預留位置值:

  • PROJECT_ID:您的專案 ID。
  • REGION:目標映像檔儲存位置,例如 us-east1 或 europe-west1。請確認您符合下列區域和可用區規定:
    • Image Builder 僅適用於支援 Cloud Build 的區域。
    • worker VM ZONE 必須位於您指定的 REGION 內。
    • 為盡可能縮短網路延遲時間,並避免產生跨區域輸出費用,請確保 worker VM 可用區、Cloud Storage 暫存 bucket、Artifact Registry 存放區和目標映像檔儲存位置都位於相同區域。
  • ZONE:位於指定 REGION 內的可用區,例如 us-east1-b 或 europe-west1-b。

建立自動調度管理工具建構檔案

在同一個目錄中建立名為 cloudbuild.yaml 的檔案。這個檔案會呼叫 Image Builder 容器步驟,建構、驗證及發布自訂 OS 映像檔。

substitutions:
  _GCS_WORKDIR: 'gs://STAGING_BUCKET_NAME/workdir/'
  _IMAGE_BUILDER_CONFIG_PATH: 'imagebuilder.yaml'
  _SERVICE_ACCOUNT: 'projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL'
  _IMAGE_OUTPUT_PATH: 'image-builder/binaryOut'
  _ARTIFACT_REGISTRY_RESOURCE_URI: 'projects/PROJECT_ID/locations/REGION/repositories/REPOSITORY_NAME/packages/PACKAGE_NAME/versions/v${BUILD_ID}'

steps:
  #  Step 1: Parse configs and run OS customization on worker VM
  - name: 'REGION-docker.pkg.dev/image-builder-official/release/builder:stable'
    script: |
      #!/usr/bin/env bash
      /build
    id: 'imagebuilder-customize'
    results:
      - name: image_builder_telemetry_metrics
      - name: base_image
        attestationType: "https://cloudbuild.googleapis.com/attestations/build_content_restrictions"
        attestationContent: base_image

  # Step 2: Validate by running system boot checks on a test VM
  - name: 'REGION-docker.pkg.dev/image-builder-official/release/validator:stable'
    script: |
      #!/usr/bin/env bash
      /validate
    id: 'imagebuilder-validate'
    results:
      - name: image_builder_telemetry_metrics

  # Step 3: Register image in Compute Engine and upload tar files to Artifact Registry
  - name: 'REGION-docker.pkg.dev/image-builder-official/release/builder:stable'
    script: |
      #!/usr/bin/env bash
      /publish
    id: 'imagebuilder-publish'
    results:
      - name: image_builder_telemetry_metrics

options:
  automapSubstitutions: true
  requestedVerifyOption: VERIFIED
  substitutionOption: ALLOW_LOOSE
  dynamicSubstitutions: true
  logging: CLOUD_LOGGING_ONLY

artifacts:
  generic_artifacts:
    - folder: '${_IMAGE_OUTPUT_PATH}'
      registry_path: '${_ARTIFACT_REGISTRY_RESOURCE_URI}'

timeout: '3600s'

替換下列預留位置值:

  • STAGING_BUCKET_NAME:專案中現有的 Cloud Storage bucket,用來做為臨時暫存工作區。如果沒有 bucket,可以執行 gcloud storage buckets create gs://STAGING_BUCKET_NAME 來建立。如果您使用 Terraform 部署管道,Terraform 會自動建立這個 bucket。
  • PROJECT_ID:您的 Google Cloud 專案 ID。
  • REGION:Artifact Registry 存放區的 Google Cloud 區域,例如 us-east1 或 europe-west1。
  • SERVICE_ACCOUNT_EMAIL:已設定必要 IAM 權限的服務帳戶電子郵件地址。
  • REPOSITORY 和 PACKAGE:在 Artifact Registry 中建立的目標存放區和套件名稱。如要設定 Artifact Registry 存放區,請參閱「設定 Artifact Registry」。

建立並提交建構管道

如要執行圖片自訂管道,請使用 gcloud CLI 提交建構作業、使用 Terraform 部署管道,或使用 Go 用戶端程式庫提交建構作業。選取下列其中一個分頁:

gcloud

如要部署及執行映像檔自訂 pipeline,請在本機終端機目錄中,執行 gcloud builds submit 指令,該目錄應包含兩個設定檔:

gcloud builds submit . \
    --config=cloudbuild.yaml \
    --project=PROJECT_ID \
    --service-account="projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_EMAIL" \
    --region=REGION

更改下列內容:

  • PROJECT_ID:您的 Google Cloud 專案 ID。
  • REGION:執行映像檔自訂管道工作的 Google Cloud 區域。
  • SERVICE_ACCOUNT_EMAIL:服務帳戶的電子郵件地址,該帳戶已設定必要的 IAM 權限。

這個指令會上傳自訂工作區、註冊 Cloud Build 執行作業,並啟動自動化調度管理容器。

Terraform

如要佈建自動建構及驗證自訂 OS 映像檔所需的基礎架構,可以使用 Terraform。這項 Terraform 設定會完成下列工作:

  • 啟用必要的 Google Cloud API。
  • 建立專屬 Cloud Storage bucket (workdir_bucket),用於儲存臨時記錄和建構構件。
  • 設定連結至 Developer Connect GitHub 存放區連線的 Cloud Build 自動建構觸發條件 (image_builder_trigger)。

建立 Terraform 設定檔

如要使用 Terraform 整理及部署管道基礎架構,請完成下列步驟:

  1. 在本機工作站或 CI/CD 環境中,建立與應用程式存放區分開的專屬目錄,然後切換至該目錄:

    mkdir terraform-image-builder && cd terraform-image-builder
    
  2. 在這個目錄中,建立下列五個 Terraform 設定檔:

    • terraform.tfvars:設定專案專屬變數的值。
    • main.tf:在 Google Cloud 專案中佈建資源,包括啟用必要的 API、建立 Cloud Storage 暫存 bucket (workdir_bucket),以及部署 Cloud Build 自動建構觸發條件 (image_builder_trigger)。
    • outputs.tf:定義部署後顯示在終端機的輸出值,例如觸發條件 ID 和暫存 bucket 名稱。
    • providers.tf:指定必要的 Terraform 版本 (>= 1.3),並設定 Google Cloud 供應商 (hashicorp/google)。
    • variables.tf:定義部署作業的輸入變數、預設值和驗證規則。

    選取下列其中一個分頁標籤,即可查看各檔案的設定,並複製到本機目錄:

    terraform.tfvars

    這個檔案會為環境指定已宣告變數的參數值:

    project_id                = "PROJECT_ID"
    builder_service_account   = "SERVICE_ACCOUNT_EMAIL"
    github_repo_name          = "projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION/repositories/REPO_NAME"
    region                    = "REGION"
    trigger_name              = "TRIGGER_NAME"
    cloudbuild_yaml_path      = "CLOUDBUILD_YAML_PATH"
    image_builder_config_path = "RECIPE_PATH"
    gcs_lifecycle_age_days    = LIFECYCLE_DAYS
    ar_repository_id          = "REPOSITORY_NAME"
    ar_package_name           = "PACKAGE_NAME"
    

    將下列預留位置替換為現有資源:

    • PROJECT_ID:現有的Google Cloud 專案 ID。
    • SERVICE_ACCOUNT_EMAIL:建構服務帳戶的電子郵件地址,該帳戶是在「設定 Image Builder 服務帳戶」中設定。
    • LOCATION、CONNECTION 和 REPO_NAME:您在「連結存放區」中設定的 Developer Connect 主機區域、連線名稱和存放區連結。
    • CLOUDBUILD_YAML_PATH:本機目錄中 cloudbuild.yaml 檔案的相對路徑。您不需要將 cloudbuild.yaml 簽入 Git 存放區。
    • RECIPE_PATH:imagebuilder.yaml 自訂配方檔案的相對路徑,該檔案已簽入 Git 存放區。
    • REPOSITORY_NAME:在「設定 Artifact Registry」中建立的現有一般 Artifact Registry 存放區。

    將下列預留位置替換為 Terraform 建立的資源:

    • REGION:Terraform 佈建 Cloud Storage 暫存 bucket 和 Cloud Build 自動建構觸發條件的目標 Google Cloud區域,例如 us-central1。
    • TRIGGER_NAME:Terraform 建立的新 Cloud Build 存放區觸發條件名稱,例如 git-push-os-builder。
    • LIFECYCLE_DAYS:Terraform 建立的 Cloud Storage 暫存 bucket 中,中繼構件自動刪除前的保留天數,例如 30。
    • PACKAGE_NAME:Terraform 在 Artifact Registry 存放區中建立套件時,應使用的名稱。這個套件會儲存已發布的 OS 映像檔版本,例如 ubuntu-custom。

    main.tf

    這個檔案會宣告部署作業的核心基礎架構資源和資料來源:

    # Main resource configurations for Image Builder.
    # 1. Enable Required APIs
    resource "google_project_service" "apis" {
      for_each = toset([
        "compute.googleapis.com",
        "cloudbuild.googleapis.com",
        "artifactregistry.googleapis.com",
        "serviceusage.googleapis.com",
        "cloudresourcemanager.googleapis.com",
        "iam.googleapis.com",
        "storage.googleapis.com"
      ])
      project = var.project_id
      service = each.key
      disable_on_destroy = false
    }
    
    # 2. Project data source to retrieve Project Number
    data "google_project" "project" {
      project_id = var.project_id
      depends_on = [google_project_service.apis]
    }
    
    locals {
      builder_sa = var.builder_service_account
    }
    
    # 3. Storage Bucket for Image Builder Workdir
    resource "google_storage_bucket" "workdir_bucket" {
      name                        = var.gcs_bucket_name != "" ? var.gcs_bucket_name : "${var.project_id}-vm-builder-workdir"
      project                     = var.project_id
      location                    = var.region
      force_destroy               = true
      uniform_bucket_level_access = true
      lifecycle_rule {
        action {
          type = "Delete"
        }
        condition {
          age = var.gcs_lifecycle_age_days
        }
      }
      depends_on = [google_project_service.apis]
    }
    
    # 4. Cloud Build Trigger
    resource "google_cloudbuild_trigger" "image_builder_trigger" {
      name        = var.trigger_name
      location    = var.region
      project     = var.project_id
      description = "Trigger that runs Image Builder customization"
    
      service_account = var.builder_service_account != "" ? "projects/${var.project_id}/serviceAccounts/${var.builder_service_account}" : null
    
      repository_event_config {
        repository = replace(var.github_repo_name, "gitRepositoryLinks", "repositories")
        push {
          branch = "^main$"
        }
      }
      filename = var.cloudbuild_yaml_path
    
      substitutions = {
        _GCS_WORKDIR                    = "gs://${google_storage_bucket.workdir_bucket.name}/workdir/"
        _SERVICE_ACCOUNT                = "projects/${var.project_id}/serviceAccounts/${local.builder_sa}"
        _IMAGE_OUTPUT_PATH              = "image-builder/binaryOut"
        _PROJECT_ID                     = var.project_id
        _LOCATION                       = var.region
        _REPOSITORY_NAME                = var.ar_repository_id
        _PACKAGE_NAME                   = var.ar_package_name
        _IMAGE_BUILDER_CONFIG_PATH      = var.image_builder_config_path
        _ARTIFACT_REGISTRY_RESOURCE_URI = "projects/${var.project_id}/locations/${var.region}/repositories/${var.ar_repository_id}/packages/${var.ar_package_name}/versions/v$${BUILD_ID}"
      }
      depends_on = [
        google_project_service.apis
      ]
    }
    

    outputs.tf

    這個檔案定義了部署後傳回終端機的輸出屬性:

    output "builder_service_account" {
      value       = local.builder_sa
      description = "The email representation of the resolved Image Builder service account."
    }
    
    output "workdir_bucket" {
      value       = google_storage_bucket.workdir_bucket.name
      description = "The name of the storage workdir bucket."
    }
    
    output "artifact_registry_repository" {
      value       = "projects/${var.project_id}/locations/${var.region}/repositories/${var.ar_repository_id}"
      description = "The fully qualified resource path of the Artifact Registry repository."
    }
    
    output "cloud_build_trigger_id" {
      value       = google_cloudbuild_trigger.image_builder_trigger.trigger_id
      description = "The unique ID for the created Cloud Build Trigger."
    }
    

    providers.tf

    這個檔案會設定必要的 Terraform 版本和區域設定:

    terraform {
      required_version = ">= 1.3"
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = ">= 5.0, < 7.0"
        }
      }
    }
    
    provider "google" {
      project = var.project_id
      region  = var.region
    }
    

    variables.tf

    這個檔案會宣告所有必要和選用的輸入變數和驗證規則:

    variable "project_id" {
      type        = string
      description = "The target Project ID where resources will be created."
      validation {
        condition     = can(regex("^[a-z0-9-]{6,30}$", var.project_id))
        error_message = "The project_id must consist of lowercase letters, numbers, and hyphens, and be between 6 and 30 characters."
      }
    }
    
    variable "region" {
      type        = string
      default     = "us-central1"
      description = "Location used for cloud build triggers, storage buckets, and artifact registry."
    }
    
    variable "github_repo_name" {
      type        = string
      default     = ""
      description = "Developer Connect github repository details, format: projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION/repositories/REPO_LINK"
      validation {
        condition     = can(regex("^projects/[^/]+/locations/[^/]+/connections/[^/]+/(gitRepositoryLinks|repositories)/[^/]+$", var.github_repo_name))
        error_message = "The github_repo_name must follow either the Cloud Build v2 repository link format (using '/repositories/') or the Developer Connect resource format (using '/gitRepositoryLinks/')."
      }
    }
    
    variable "builder_service_account" {
      type        = string
      default     = ""
      description = "The email representation of the pre-existing Image Builder service account. If omitted, the default Cloud Build service account will be used."
    }
    
    variable "gcs_bucket_name" {
      type        = string
      default     = ""
      description = "Custom name for the workdir storage bucket. If left empty, a default name using the project ID will be constructed."
    }
    
    variable "gcs_lifecycle_age_days" {
      type        = number
      default     = 30
      description = "The number of days after which temporary logs and artifacts in the storage workdir bucket are deleted."
    }
    
    variable "ar_repository_id" {
      type        = string
      default     = "vm-images"
      description = "The repository ID for the generic Artifact Registry hosting the final OS image tarballs."
    }
    
    variable "ar_package_name" {
      type        = string
      default     = "image-builder"
      description = "The package name under which the generic OS image artifact will be registered in Artifact Registry."
    }
    
    variable "trigger_name" {
      type        = string
      default     = "custom-os-image-builder"
      description = "The name of the Cloud Build trigger."
    }
    
    variable "cloudbuild_yaml_path" {
      type        = string
      default     = "cloudbuild.yaml"
      description = "The path to the cloudbuild.yaml configuration file relative to the repository root."
    }
    
    variable "image_builder_config_path" {
      type        = string
      default     = "imagebuilder.yaml"
      description = "The path to the imagebuilder.yaml configuration file relative to the repository root."
    }
    
  3. 如要部署設定,請在包含 Terraform 檔案的目錄中執行下列指令:

    1. 初始化目錄:
      terraform init
    2. 驗證語法:
      terraform validate
    3. 預覽部署作業:
      terraform plan
    4. 套用設定:
      terraform apply

Go

執行這個範例前,請先將 imagebuilder.yaml 設定檔上傳至 Cloud Storage 暫存 bucket,例如 gs://STAGING_BUCKET_NAME/imagebuilder.yaml。

如要使用 Cloud Build Go 用戶端程式庫,提交執行 Image Builder 管道的 Cloud Build 建構作業,請使用下列範例:

import (
	"context"
	"encoding/json"
	"fmt"
	"io"

	"google.golang.org/api/cloudbuild/v1"
)

// submitBuild submits a Cloud Build build that uses Image Builder to
// customize, validate, and publish a VM image to Compute Engine and Artifact
// Registry.
//
// Before you run this sample, upload your imagebuilder.yaml configuration file
// to Cloud Storage, create a generic Artifact Registry repository, and create a
// service account to run the build.
func submitBuild(w io.Writer, projectID, gcsWorkdir, configPath, serviceAccount string) error {
	// projectID := "my-project-id"
	region := "us-central1"
	// gcsWorkdir := "gs://my-bucket/workdir/"
	// configPath := "gs://my-bucket/imagebuilder.yaml"
	repository := "vm-images"
	packageName := "custom-os-images"
	// serviceAccount := "image-builder@my-project-id.iam.gserviceaccount.com"

	ctx := context.Background()
	cbService, err := cloudbuild.NewService(ctx)
	if err != nil {
		return fmt.Errorf("cloudbuild.NewService: %w", err)
	}

	sa := fmt.Sprintf("projects/%s/serviceAccounts/%s", projectID, serviceAccount)
	req := &cloudbuild.Build{
		ServiceAccount: sa,
		// AutomapSubstitutions exposes these substitutions to every step as
		// environment variables. See
		// https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values#mapping_substitutions_to_environment_variables
		Substitutions: map[string]string{
			"_GCS_WORKDIR":               gcsWorkdir,
			"_SERVICE_ACCOUNT":           sa,
			"_IMAGE_OUTPUT_PATH":         "image-builder/binaryOut",
			"_IMAGE_BUILDER_CONFIG_PATH": configPath,
			"_ARTIFACT_REGISTRY_RESOURCE_URI": fmt.Sprintf(
				"projects/%s/locations/%s/repositories/%s/packages/%s/versions/v${BUILD_ID}",
				projectID, region, repository, packageName,
			),
		},
		Steps: []*cloudbuild.BuildStep{
			{
				Id:     "imagebuilder-customize",
				Name:   "us-docker.pkg.dev/image-builder-official/release/builder:stable",
				Script: "#!/usr/bin/env bash\n/build",
				Results: []*cloudbuild.StepResult{
					{
						Name:            "base_image",
						AttestationType: "https://cloudbuild.googleapis.com/attestations/build_content_restrictions",
					},
					{Name: "image_builder_telemetry_metrics"},
				},
			},
			{
				Id:      "imagebuilder-validate",
				Name:    "us-docker.pkg.dev/image-builder-official/release/validator:stable",
				Script:  "#!/usr/bin/env bash\n/validate",
				Results: []*cloudbuild.StepResult{{Name: "image_builder_telemetry_metrics"}},
			},
			{
				Id:      "imagebuilder-publish",
				Name:    "us-docker.pkg.dev/image-builder-official/release/builder:stable",
				Script:  "#!/usr/bin/env bash\n/publish",
				Results: []*cloudbuild.StepResult{{Name: "image_builder_telemetry_metrics"}},
			},
		},
		Options: &cloudbuild.BuildOptions{
			AutomapSubstitutions:  true,
			DynamicSubstitutions:  true,
			RequestedVerifyOption: "VERIFIED",
			SubstitutionOption:    "ALLOW_LOOSE",
			// Builds that run as a user-specified service account must set a
			// logging option.
			Logging: "CLOUD_LOGGING_ONLY",
		},
		Artifacts: &cloudbuild.Artifacts{
			GenericArtifacts: []*cloudbuild.GenericArtifact{
				{
					Folder:       "${_IMAGE_OUTPUT_PATH}",
					RegistryPath: "${_ARTIFACT_REGISTRY_RESOURCE_URI}",
				},
			},
		},
		Timeout: "3600s",
	}

	parent := fmt.Sprintf("projects/%s/locations/%s", projectID, region)
	op, err := cbService.Projects.Locations.Builds.Create(parent, req).Context(ctx).Do()
	if err != nil {
		return fmt.Errorf("Builds.Create: %w", err)
	}

	// The operation metadata contains the build that was created.
	var metadata cloudbuild.BuildOperationMetadata
	if err := json.Unmarshal(op.Metadata, &metadata); err != nil {
		return fmt.Errorf("json.Unmarshal: %w", err)
	}
	fmt.Fprintf(w, "Build submitted. ID: %s\n", metadata.Build.Id)
	fmt.Fprintf(w, "Logs: %s\n", metadata.Build.LogUrl)
	return nil
}

驗證及監控建構作業

如要追蹤建構管道的進度,請完成下列步驟:

  1. 前往 Google Cloud 控制台的「Cloud Build」頁面。

    前往 Cloud Build

  2. 在導覽選單中,按一下「History」(記錄),查看執行中或已完成的工作。

  3. 在「Builds」(建構作業) 清單中,按一下建構作業的「Build ID」(建構 ID),檢查容器執行記錄。記錄會顯示在 worker VM 中執行的步驟,例如系統套件更新或自訂殼層指令,接著是測試 VM 的驗證測試結果,以及最終輸出註冊。

後續步驟