以编程方式创建自定义操作系统映像流水线

您可以使用 gcloud CLI、Terraform 或 Go 等客户端库,以编程方式配置和提交 Image Builder 流水线。通过以编程方式配置流水线,您可以在声明式配置文件中定义基础架构设置、基础操作系统映像、自定义操作和验证测试。

准备工作

  • 完成准备环境中的环境设置步骤。
  • 如果您打算使用 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. 如果您使用的是本地 shell,请为您的用户账号创建本地身份验证凭证:

      gcloud auth application-default login

      如果您使用的是 Cloud Shell,则无需执行此操作。

      如果系统返回身份验证错误,并且您使用的是外部身份提供方 (IdP),请确认您已 使用联合身份登录 gcloud CLI。

    如需了解详情,请参阅 为本地开发环境设置身份验证。

    Go

    如需在本地开发环境中使用本页面上的 Go 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭证设置应用默认凭据。

    1. 安装 Google Cloud CLI。

    2. 如果您使用的是外部身份提供方 (IdP),则必须先 使用联合身份登录 gcloud CLI。

    3. 如果您使用的是本地 shell,请为您的用户账号创建本地身份验证凭证:

      gcloud auth application-default login

      如果您使用的是 Cloud Shell,则无需执行此操作。

      如果系统返回身份验证错误,并且您使用的是外部身份提供方 (IdP),请确认您已 使用联合身份登录 gcloud CLI。

    如需了解详情,请参阅 为本地开发环境设置身份验证。

所需的角色

如需获得以编程方式创建和提交图片自定义流水线所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

创建配置文件

如需使用 gcloud CLI 或 Terraform 配置流水线,请创建两个配置文件:

  • imagebuilder.yaml:定义映像的自定义配方,包括基础操作系统映像、工作器虚拟机基础架构设置、目标映像输出详细信息,以及顺序自定义步骤(例如运行 shell 脚本、传输文件或执行重新启动)。
  • cloudbuild.yaml:在 Cloud Build 中编排构建流程步骤,包括解析、验证、构建、测试和发布自定义操作系统映像。

如果您使用 Go 提交 build,则只需创建 imagebuilder.yaml 文件并将其上传到 Cloud Storage 存储桶,因为 Go 示例在代码中定义了 Cloud Build 编排步骤。

创建映像配置文件

如需指定映像配置,请在本地目录中创建一个名为 imagebuilder.yaml 的文件。如需查看所有受支持的架构字段和自定义操作的完整列表,请参阅自定义配方架构和支持的自定义操作。

以下示例 imagebuilder.yaml 文件配置了一个流水线,该流水线使用您指定的区域和可用区中的 e2-standard-4 工作器虚拟机机构建自定义 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 的区域受支持。
    • 工作器虚拟机 ZONE 必须位于您指定的 REGION 中。
    • 为尽可能缩短网络延迟时间并避免产生跨区域出站流量费用,请确保工作器虚拟机可用区、Cloud Storage 暂存存储桶、Artifact Registry 代码库和目标映像存储位置都位于同一区域。
  • ZONE:位于您指定的 REGION 内的可用区,例如 us-east1-b 或 europe-west1-b。

创建编排器 build 文件

在同一目录中创建一个名为 cloudbuild.yaml 的文件。此文件会调用 Image Builder 容器步骤来构建、验证和发布自定义操作系统映像。

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 存储桶。如果您没有存储桶,可以运行 gcloud storage buckets create gs://STAGING_BUCKET_NAME 创建一个。如果您使用 Terraform 部署流水线,Terraform 会自动创建此存储桶。
  • 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 提交 build、使用 Terraform 部署流水线,或使用 Go 客户端库提交 build。选择以下标签页之一:

gcloud

如需部署和运行映像自定义流水线,请在包含这两个配置文件的本地终端目录中运行 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

如需预配自动构建和验证自定义操作系统映像所需的基础设施,您可以使用 Terraform。此 Terraform 配置可完成以下任务:

  • 启用必需的 Google Cloud API。
  • 创建一个专用 Cloud Storage 存储桶 (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 暂存存储桶 (workdir_bucket) 以及部署 Cloud Build 构建触发器 (image_builder_trigger)。
    • outputs.tf:定义部署后在终端中显示的输出值,例如触发器 ID 和暂存存储桶名称。
    • 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:已签入 Git 代码库的 imagebuilder.yaml 自定义配方文件的相对路径。
    • REPOSITORY_NAME:在配置 Artifact Registry 中创建的现有通用 Artifact Registry 仓库。

    替换 Terraform 创建的资源的以下占位符:

    • REGION:Terraform 在其中预配 Cloud Storage 暂存存储桶和 Cloud Build 构建触发器的目标 Google Cloud区域,例如 us-central1。
    • TRIGGER_NAME:Terraform 创建的新 Cloud Build 代码库触发器的名称,例如 git-push-os-builder。
    • LIFECYCLE_DAYS:Terraform 创建的 Cloud Storage 暂存存储桶中的中间制品在自动删除前的保留期限(以天为单位),例如 30。
    • PACKAGE_NAME:您希望 Terraform 为 Artifact Registry 代码库中创建的软件包使用的名称。此软件包存储已发布的操作系统映像版本,例如 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 暂存存储桶(例如 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. 在导航菜单中,点击历史记录,查看正在运行或已完成的作业。

  3. 在构建列表中,点击构建的构建 ID 以检查容器运行日志。日志会显示工作器虚拟机内执行的步骤(例如系统软件包更新或自定义 shell 命令),然后显示测试虚拟机的验证测试结果,以及最终输出注册。

后续步骤