אפשר להגדיר ולשלוח תוכנית של צינור עיבוד נתונים של Image Builder באופן פרוגרמטי באמצעות Google Cloud CLI או Terraform. הגדרת צינור העברת הנתונים באופן פרוגרמטי מאפשרת להגדיר הגדרות תשתית, קובצי אימג' של מערכת הפעלה בסיסית, פעולות התאמה אישית ובדיקות אימות בקובצי תצורה הצהרתיים.
לפני שמתחילים
- משלימים את השלבים להגדרת הסביבה במאמר הכנת הסביבה.
- אם אתם מתכוונים לפרוס את צינור עיבוד הנתונים באמצעות Terraform או להפוך את הבנייה לאוטומטית ממאגר, אתם יכולים לחבר את המאגר שלכם ב-GitHub, ב-GitLab או ב-Bitbucket באמצעות מאגרי Cloud Build (
2nd gen) או קישורי חיבור של Developer Connect. - אם אתם מתכננים להשתמש ב-Terraform, אתם צריכים להתקין את Terraform CLI בגרסה 1.3 ואילך.
-
אם עדיין לא עשיתם את זה, תצטרכו להגדיר אימות.
אימות הוא תהליך שבו מאמתים את הזהות שלכם כדי לקבל גישה לממשקי API ולשירותים של Google Cloud . כדי להריץ קוד או דוגמאות מסביבת פיתוח מקומית, אפשר לבצע אימות ל-Compute Engine באחת מהדרכים הבאות:
צריך לבחור את הכרטיסייה הרלוונטית לאופן שבו תכננתם להשתמש בדוגמאות בדף הזה:
gcloud
-
התקינו את ה-CLI של Google Cloud. אחר כך, אתחלו את ה-CLI של Google Cloud באמצעות הפקודה הבאה:
gcloud initאם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
-
- הגדרת אזור ותחום כברירת מחדל
-
התקינו את ה-CLI של Google Cloud.
-
אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
-
אם אתם משתמשים במעטפת מקומית, אתם צריכים ליצור פרטי כניסה לאימות מקומי עבור חשבון המשתמש:
gcloud auth application-default login
אם אתם משתמשים ב-Cloud Shell, אין צורך לבצע את הפעולה הזו.
אם מוחזרת שגיאת אימות ואתם משתמשים בספק זהויות חיצוני (IdP), ודאו ש נכנסתם ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.
Terraform
כדי להשתמש בסביבת פיתוח מקומית בדוגמאות של Terraform שבדף הזה, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.
מידע נוסף זמין במאמר הגדרת אימות לסביבת פיתוח מקומית.
התפקידים הנדרשים
כדי לקבל את ההרשאות שדרושות ליצירה ולשליחה של צינורות להתאמה אישית של תמונות באמצעות Google Cloud CLI או Terraform, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:
- עריכה ב-Cloud Build (
roles/cloudbuild.builds.editor) - משתמש בחשבון שירות (
roles/iam.serviceAccountUser)
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
יצירת קובצי תצורה
כדי להגדיר את הפייפליין באמצעות ה-CLI של gcloud או Terraform, צריך ליצור שני קובצי תצורה:
-
imagebuilder.yaml: הגדרת מתכון ההתאמה האישית של התמונה, כולל תמונת מערכת ההפעלה הבסיסית, הגדרות התשתית של מכונת ה-VM של העובד, פרטי הפלט של תמונת היעד ושלבי ההתאמה האישית הרציפים, כמו הפעלת סקריפטים של מעטפת, העברת קבצים או ביצוע הפעלה מחדש. -
cloudbuild.yaml: מבצע תזמור של השלבים בתהליך ה-build ב-Cloud Build, כולל ניתוח, אימות, יצירה, בדיקה ופרסום של תמונת מערכת ההפעלה בהתאמה אישית.
יצירת קובץ הגדרות אישיות של תמונה
כדי לציין את הגדרות התמונה, יוצרים קובץ בשם imagebuilder.yaml בספרייה המקומית. רשימה מלאה של כל שדות הסכימה הנתמכים ופעולות ההתאמה האישית מופיעה במאמרים סכימת מתכוני התאמה אישית ופעולות התאמה אישית נתמכות.
קובץ imagebuilder.yaml לדוגמה שמופיע בהמשך מגדיר פייפליין שיוצר אימג' מותאם אישית של Ubuntu 22.04 LTS באמצעות worker VM e2-standard-4 באזור ובאזור הזמין שצוינו, ומבצע עדכון של חבילת מערכת.
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"
מחליפים את ערכי ה-placeholder הבאים:
PROJECT_ID: מזהה הפרויקט.-
REGION: מיקום האחסון של תמונת היעד, לדוגמה,us-east1אוeurope-west1. חשוב לוודא שאתם עומדים בדרישות האזוריות והאזוריאליות הבאות:- הכלי Image Builder נתמך רק באזורים שבהם Cloud Build זמין.
- המכונה הווירטואלית של העובד
ZONEצריכה להיות ממוקמת בתוךREGIONשציינתם. - כדי לצמצם את זמן האחזור ברשת ולמנוע חיובים על תעבורת נתונים יוצאת (egress) בין אזורים, צריך לוודא שהאזור של המכונה הווירטואלית של העובד, קטגוריית האחסון הזמני ב-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'
מחליפים את ערכי ה-placeholder הבאים:
-
STAGING_BUCKET_NAME: קטגוריה קיימת של Cloud Storage בפרויקט שלכם, שתשמש כסביבת עבודה זמנית להכנה. אם אין לכם קטגוריית אחסון, אתם יכולים ליצור אותה באמצעות הפקודהgcloud storage buckets create gs://STAGING_BUCKET_NAME. אם פורסים את צינור עיבוד הנתונים באמצעות Terraform, המערכת יוצרת את קטגוריית האחסון הזו באופן אוטומטי. -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
REGION: האזור Google Cloud של מאגר Artifact Registry, לדוגמה,us-east1אוeurope-west1. -
SERVICE_ACCOUNT_EMAIL: כתובת האימייל של חשבון השירות שהגדרתם לו את הרשאות ה-IAM הנדרשות. -
REPOSITORYו-PACKAGE: מאגר היעד ושם החבילה שנוצרו ב-Artifact Registry. כדי להגדיר את מאגר Artifact Registry, אפשר לעיין במאמר הגדרת Artifact Registry.
יצירה ושליחה של צינור עיבוד נתונים לבנייה
כדי להריץ את פייפליין התאמה אישית של התמונה, שולחים גרסת build באמצעות ה-CLI של gcloud או פורסים את הפייפליין באמצעות Terraform. בוחרים אחת מהכרטיסיות הבאות:
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 . -
REGION: ה Google Cloud אזור שבו יופעל ג'וב צינור ההתאמה האישית של התמונה. -
SERVICE_ACCOUNT_EMAIL: כתובת האימייל של חשבון השירות שהוגדר עם הרשאות IAM הנדרשות.
הפקודה הזו מעלה את סביבת העבודה להתאמה אישית, רושמת את ההפעלה של Cloud Build ומפעילה את קונטיינרים של תזמור.
Terraform
כדי להקצות את התשתית שנדרשת לבנייה ולאימות אוטומטיים של תמונות מערכת הפעלה בהתאמה אישית, אפשר להשתמש ב-Terraform. ההגדרה הזו של Terraform מבצעת את המשימות הבאות:
- הפעלת ממשקי API נדרשים Google Cloud .
- יוצר קטגוריה ייעודית של Cloud Storage (
workdir_bucket) לאחסון יומנים זמניים וארטיפקטים של בנייה. - מגדיר טריגר לפיתוח גרסת Build של Cloud Build (
image_builder_trigger) שמקושר לחיבור שלכם למאגר GitHub ב-Developer Connect.
יצירת קובצי התצורה של Terraform
כדי לארגן ולפרוס את תשתית הצינור באמצעות Terraform, מבצעים את השלבים הבאים:
יוצרים ספרייה ייעודית בתחנת העבודה המקומית או בסביבת CI/CD, בנפרד ממאגר האפליקציות, ועוברים אליה:
mkdir terraform-image-builder && cd terraform-image-builder
בספרייה הזו, יוצרים את חמשת קובצי התצורה הבאים של Terraform:
-
terraform.tfvars: הגדרת ערכים למשתנים ספציפיים לפרויקט. -
main.tf: מקצה משאבים בפרויקט Google Cloud , כולל הפעלת ממשקי ה-API הנדרשים, יצירת מאגר זמני של Cloud Storage (workdir_bucket) ופריסת טריגר לפיתוח גרסת Build (image_builder_trigger). -
outputs.tf: מגדיר ערכי פלט שמוצגים במסוף אחרי הפריסה, כמו מזהה הטריגר ושם מאגר ה-staging. -
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"
מחליפים את ה-placeholders הבאים במשאבים הקיימים:
-
PROJECT_ID: מזהה הפרויקט הקיים ב-Google Cloud . -
SERVICE_ACCOUNT_EMAIL: כתובת האימייל של חשבון השירות של שירות ה-Build שהוגדר בהגדרת חשבון השירות של 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.
מחליפים את ה-placeholders הבאים במשאבים שנוצרו ב-Terraform:
-
REGION: אזור היעד שבו Terraform מקצה את קטגוריית הביניים של Cloud Storage ואת הטריגר של Cloud Build Google Cloud, לדוגמה,us-central1. -
TRIGGER_NAME: השם של טריגר חדש למאגר Cloud Build שנוצר על ידי Terraform, לדוגמה,git-push-os-builder. -
LIFECYCLE_DAYS: תקופת השמירה בימים לפני שמחיקה אוטומטית של ארטיפקטים זמניים בקטגוריית הביניים של Cloud Storage שנוצרה על ידי Terraform, לדוגמה,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." }-
כדי לפרוס את ההגדרות, מריצים את הפקודות הבאות בספרייה שמכילה את קובצי Terraform:
- מפעילים את הספרייה:
terraform init
- בודקים את התחביר:
terraform validate
- תצוגה מקדימה של הפריסה:
terraform plan
- מחילים את ההגדרה:
terraform apply
- מפעילים את הספרייה:
אימות ומעקב אחר ה-build
כדי לעקוב אחרי ההתקדמות של צינור ה-build, מבצעים את השלבים הבאים:
במסוף Google Cloud , נכנסים לדף Cloud Build.
בתפריט הניווט, לוחצים על היסטוריה כדי לראות משרות פעילות או משרות שהושלמו.
ברשימה Builds (גרסאות Build), לוחצים על Build ID (מזהה גרסת ה-Build) של גרסת ה-Build כדי לבדוק את יומני ההפעלה של הקונטיינר. בקטעי היומן מוצגים השלבים שמבוצעים במכונה הווירטואלית של העובד, כמו עדכונים של חבילות מערכת או פקודות מותאמות אישית של מעטפת, ואחריהם תוצאות בדיקת האימות מהמכונה הווירטואלית של הבדיקה ורישום הפלט הסופי.
המאמרים הבאים
- כדי להגדיר ולהפעיל בנייה חוזרת או אוטומטית משורת הפקודה:
- אימות מקור התמונה