פיתוח קובצי אימג' של קונטיינרים

בדף הזה מוסבר איך להגדיר את Cloud Build כדי לבנות ולאחסן תמונות Docker. אם אתם חדשים ב-Cloud Build, כדאי לקרוא קודם את המדריכים למתחילים ואת סקירת ההגדרות של ה-Build.

‫Cloud Build מספק תמונות שנוצרו מראש שאפשר להפנות אליהן בקובץ הגדרות של Cloud Build כדי להריץ את המשימות. התמונות האלה נתמכות ומתוחזקות על ידי Google Cloud. אתם יכולים להשתמש בקובץ אימג' של Docker שנתמך ונוצר מראש כדי להריץ פקודות Docker וליצור קובצי אימג' של Docker.

לפני שמתחילים

ההוראות בדף הזה מניחות שאתם מכירים את Docker. בנוסף:

  • קוד המקור של האפליקציה וDockerfile צריכים להיות זמינים.
  • צריך מאגר Docker לאחסון תמונות ב-Artifact Registry, או ליצור מאגר חדש.
  • כדי להשתמש בפקודות gcloud שבדף הזה, צריך להתקין את Google Cloud CLI.
  • אם רוצים להריץ את קובצי האימג', צריך להתקין את Docker.
  • אם רוצים לחתום על התמונות באמצעות cosign, צריך לפעול לפי ההוראות שבמאמר איך מאשרים גישה משירות לשירות כדי ליצור חשבון שירות שמוגדר על ידי המשתמש ולהעניק את ההרשאות שנדרשות ליצירת אסימוני מזהה.

יצירת build באמצעות קובץ תצורת build

כדי ליצור קובץ אימג' של Docker באמצעות קובץ תצורת build:

  1. באותה תיקייה שמכילה את קוד המקור של האפליקציה, יוצרים קובץ בשם cloudbuild.yaml או cloudbuild.json.
  2. בקובץ תצורת ה-build:

    • מוסיפים שדה name ומציינים את קובץ האימג' של Docker המוכנה מראש. התמונה המוכנה מראש מאוחסנת במיקום gcr.io/cloud-builders/docker. בקובץ התצורה לדוגמה שבהמשך, השדה name מציין ש-Cloud Build משתמש בקובץ האימג' המובנה של Docker כדי להריץ את המשימה שמצוינת בשדה args.
    • בשדה args, מוסיפים את הארגומנטים ליצירת התמונה.

      YAML

      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ]
      

      JSON

      {
       "steps": [
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
              "."
             ]
         }
         ]
       }
      

    כאשר:

    • LOCATION: המיקום האזורי או הרב-אזורי של מאגר Docker ב-Artifact Registry.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REPOSITORY: השם של מאגר Docker ב-Artifact Registry.
    • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.

      אם קובץ ה-Dockerfile וקוד המקור נמצאים בספריות שונות, מוסיפים את -f ואת הנתיב לקובץ ה-Dockerfile לרשימת הארגומנטים בשדה args:

      YAML

      steps:
      - name: 'gcr.io/cloud-builders/docker'
        args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '-f', 'DOCKERFILE_PATH', '.' ]
      

      JSON

      {
       "steps": [
        {
            "name": "gcr.io/cloud-builders/docker",
            "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME", '-f', 'DOCKERFILE_PATH', "."
             ]
         }
         ]
       }
      

      כאשר:

      • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
      • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
      • REPOSITORY: השם של מאגר Artifact Registry.
      • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.
      • DOCKERFILE_PATH: הנתיב אל Dockerfile.
  3. מריצים את ה-build באמצעות קובץ התצורה של ה-build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    כאשר:

    • CONFIG_FILE_PATH: הנתיב לקובץ התצורה של ה-build.
    • SOURCE_DIRECTORY: הנתיב או כתובת ה-URL של קוד המקור.

    אם לא מציינים CONFIG_FILE_PATH ו-SOURCE_DIRECTORY בפקודה gcloud builds submit, ‏ Cloud Build מניח שקובץ ההגדרות וקוד המקור נמצאים בספריית העבודה הנוכחית.

יצירה באמצעות קובץ Dockerfile

באמצעות Cloud Build אפשר ליצור קובץ אימג' של Docker רק באמצעות Dockerfile. לא צריך קובץ תצורת build נפרד.

כדי לבצע Build באמצעות Dockerfile, מריצים את הפקודה הבאה מהספרייה שמכילה את קוד המקור ואת Dockerfile:

    gcloud builds submit --tag LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME

כאשר:

  • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
  • REPOSITORY: השם של מאגר Artifact Registry.
  • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.

פיתוח באמצעות buildpacks של Google Cloud

בעזרת Cloud Build אפשר ליצור קובץ אימג' בלי קובץ Dockerfile או קובץ תצורת build. אפשר לעשות זאת באמצעות buildpacks של Google Cloud.

כדי לבצע build באמצעות buildpacks, מריצים את הפקודה הבאה מהספרייה שמכילה את קוד המקור:

    gcloud builds submit --pack builder=BUILDPACK_BUILDER, \
        env=ENVIRONMENT_VARIABLE, \
        image=IMAGE_NAME

כאשר:

  • BUILDPACK_BUILDER: ה-builder של buildpacks שבו רוצים להשתמש. אם לא מציינים כלי בנייה, Cloud Build משתמש ב-gcr.io/buildpacks/builder כברירת מחדל.
  • ENVIRONMENT_VARIABLE: משתני סביבה כלשהם לבנייה.
  • IMAGE: כתובת ה-URL של התמונה ב-Artifact Registry. כתובת ה-URL של התמונה צריכה להיות בפורמט LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME.

הנה כמה פקודות לדוגמה:

  • מריצים build באמצעות ברירת המחדל gcr.io/buildpacks/builder כדי ליצור את קובץ האימג' us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app:

      gcloud builds submit --pack image=us-docker.pkg.dev/gcb-docs-project/containers/gke/hello-app
    
  • העברת כמה משתני סביבה לגרסת ה-build באמצעות ^--^ כמפריד. מידע נוסף על ביטול ברירת מחדל של ארגומנטים זמין במאמר gcloud topic escaping.

      gcloud builds submit --pack \
          ^--^image=gcr.io/my-project/myimage--env=GOOGLE_ENTRYPOINT='java -jar target/myjar.jar',GOOGLE_RUNTIME_VERSION='3.1.301'
    

הגדרת טריגרים לשימוש ב-buildpacks: בנוסף ליצירת build באמצעות שורת הפקודה, אפשר להגדיר טריגרים לשימוש ב-buildpacks כדי ליצור את התמונה באופן אוטומטי. מידע נוסף זמין במאמר בנושא יצירה וניהול של טריגרים לבנייה.

דרכים שונות לאחסון תמונות ב-Artifact Registry

אפשר להגדיר את Cloud Build לאחסון תמונה שנבנתה באחת מהדרכים הבאות:

  • אחרי שגרסת ה-build מסתיימת, משתמשים בשדה images כדי לאחסן קובץ אימג' של Docker ב-Artifact Registry.
  • אחרי שגרסת ה-build מסתיימת, משתמשים בשדה artifacts.oci כדי לאחסן קובץ אימג' של OCI ב-Artifact Registry.
  • משתמשים בפקודה docker push כדי לאחסן קובץ אימג' של קונטיינר ב-Artifact Registry כחלק מתהליך ה-build.

ההבדל בין שימוש בשדה images לבין שימוש בפקודה push של Docker הוא שאם משתמשים בשדה images, התמונה המאוחסנת תוצג בתוצאות הבנייה. הדבר כולל את הדף Build description של build במסוףGoogle Cloud , את התוצאות של Build.get() ואת התוצאות של gcloud builds list. עם זאת, אם משתמשים בפקודה push של Docker כדי לאחסן את האימג' שנוצר, האימג' לא יוצג בתוצאות הבנייה.

אם רוצים לאחסן את התמונה כחלק מתהליך ה-build ולהציג אותה בתוצאות ה-build, צריך להשתמש גם בפקודה push של Docker וגם בשדה images בקובץ ההגדרות של ה-build.

אחסון קובץ אימג' של קונטיינר ב-Artifact Registry אחרי השלמת גרסת ה-build

  1. אם מאגר היעד לא קיים, צריך ליצור מאגר חדש.
  2. באותה תיקייה שמכילה את קוד המקור של האפליקציה ואת הקובץ Dockerfile, יוצרים קובץ בשם cloudbuild.yaml או cloudbuild.json.
  3. בקובץ התצורה של ה-build, מוסיפים שלב build ליצירת תמונה, ואז מוסיפים שדה images שמציין את התמונה שנוצרה. התמונה מאוחסנת ב-Artifact Registry. בקטע הקוד הבא מוצגת הגדרת build ליצירת קובץ אימג' ולאחסון שלו ב-Artifact Registry:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.' ]
    images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
    "steps": [
    {
        "name": "gcr.io/cloud-builders/docker",
        "args": [
            "build",
            "-t",
            "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
            "."
        ]
    }
    ],
    "images": [
        "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
    ]
    }
    

    כאשר:

    • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REPOSITORY: השם של מאגר Artifact Registry.
    • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.
  4. מריצים את ה-build באמצעות קובץ התצורה של ה-build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    כאשר:

    • CONFIG_FILE_PATH הוא הנתיב לקובץ התצורה של ה-build.
    • SOURCE_DIRECTORY הוא הנתיב או כתובת ה-URL של קוד המקור.

שמירת התמונה ב-Artifact Registry כחלק מתהליך הבנייה

  1. באותה תיקייה שמכילה את קוד המקור של האפליקציה ואת הקובץ Dockerfile, יוצרים קובץ בשם cloudbuild.yaml או cloudbuild.json.

  2. בקובץ התצורה של ה-build, מוסיפים שלב build של docker כדי ליצור תמונה, ואז מוסיפים עוד שלב build של docker ומעבירים ארגומנטים כדי להפעיל את הפקודה push:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
      "steps": [
       {
          "name": "gcr.io/cloud-builders/docker",
          "args": [
              "build",
              "-t",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
              "."
           ]
       },
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
              "push",
              "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
            ]
       }
      ]
    }
    

    כאשר:

    • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REPOSITORY: השם של מאגר Artifact Registry.
    • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.
  3. מריצים את ה-build באמצעות קובץ התצורה של ה-build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    כאשר:

    • CONFIG_FILE_PATH הוא הנתיב לקובץ התצורה של ה-build.
    • SOURCE_DIRECTORY הוא הנתיב או כתובת ה-URL של קוד המקור.

אחסון תמונה כחלק מתהליך ה-build והצגת התמונה בתוצאות ה-build

  1. באותה תיקייה שמכילה את קוד המקור של האפליקציה ואת הקובץ Dockerfile, יוצרים קובץ בשם cloudbuild.yaml או cloudbuild.json.
  2. בקובץ ההגדרות של ה-build, אחרי השלב שבו נוצר קובץ האימג', מוסיפים שלב להפעלת הפקודה push של Docker, ואז מוסיפים את השדה images:

    YAML

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME', '.']
    - name: 'gcr.io/cloud-builders/docker'
      args: ['push', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME']
    

    JSON

    {
        "steps": [
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
               "build",
               "-t",
               "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
               "."
            ]
       },
       {
           "name": "gcr.io/cloud-builders/docker",
           "args": [
               "push",
               "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
            ]
       }
       ],
        "images": [
           "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME"
        ]
    }
    

    כאשר:

    • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REPOSITORY: השם של מאגר Artifact Registry.
    • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.
  3. מריצים את ה-build באמצעות קובץ התצורה של ה-build:

    gcloud builds submit --config CONFIG_FILE_PATH SOURCE_DIRECTORY
    

    כאשר:

    • CONFIG_FILE_PATH הוא הנתיב לקובץ התצורה של ה-build.
    • SOURCE_DIRECTORY הוא הנתיב או כתובת ה-URL של קוד המקור.

אחסון תמונת OCI ב-Artifact Registry אחרי שה-build מסתיים

  1. באותה תיקייה שמכילה את קוד המקור של האפליקציה ואת הקובץ Dockerfile, יוצרים קובץ בשם cloudbuild.yaml או cloudbuild.json.
  2. בקובץ תצורת ה-build, מוסיפים שדה artifacts שמציין את קובץ האימג' של OCI שנוצר. ההגדרה הזו מאחסנת את קובץ האימג' של OCI ב-Artifact Registry. בדוגמה הבאה מוצגת הגדרת build שיוצרת תמונה של OCI ומאחסנת אותה ב-Artifact Registry:

    YAML

    artifacts:
      oci:
      - file: 'OCI_IMAGE_PATH'
        registryPath: 'https://LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY'
        tags: ["primary_image"]
    

    JSON

    {
      "artifacts": {
        "oci": [
          {
            "file": "OCI_IMAGE_PATH",
            "registryPath": "https://LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY",
            "tags": ["primary_image"]
          }
        ]
      }
    }
    

    כאשר:

    • OCI_IMAGE_PATH היא הכתובת של הספרייה המקומית שמכילה את תמונת ה-OCI שרוצים להעלות, לדוגמה, /.pack/layout-repo/my-app.
    • LOCATION הוא המיקום האזורי או המיקום במספר אזורים של המאגר.
    • PROJECT_ID הוא מזהה הפרויקט. Google Cloud
    • REPOSITORY: השם של מאגר Artifact Registry.

חתימה על תמונות של קונטיינרים באמצעות cosign

אם אתם מאחסנים תמונות ב-Artifact Registry, אתם יכולים להוסיף עוד שכבת אבטחה באמצעות הכלי cosign כדי ליצור רשומה של חשבון השירות שמשמש להפעלת בנייה. הרישום הזה מבוסס על תקן OpenID Connect ‏ (OIDC), ומאפשר למבקרים לוודא שתמונה נוצרה על ידי חשבון שירות מהימן.

בשלבים הבאים מוסבר איך להשתמש בקובץ התצורה cloudbuild.yaml כדי לקבל טוקן זהות ולחתום על קובץ אימג' של קונטיינר.

YAML

  steps:
  - name: 'gcr.io/cloud-builders/docker'
    id: 'tag-and-push'
    script: |
      #!/bin/sh
      set -e
      docker build -t $_IMAGE .
      docker push "$_IMAGE"
      docker inspect $_IMAGE --format "$_IMAGE@{{.Id}}" >image_with_digest
  - name: 'gcr.io/cloud-builders/gcloud'
    id: 'generate-token'
    script: |
      #!/bin/sh
      set -e
      gcloud auth print-identity-token --audiences=sigstore > token
  - name: 'gcr.io/cloud-builders/docker'
    id: 'sign-image'
    script: |
      #!/bin/sh
      set -e
      docker run \
      --network=cloudbuild \
      --mount source=home-volume,target=/builder/home \
      --rm \
      -e SIGSTORE_NO_CACHE=true \
      -e HOME=/builder/home \
      gcr.io/projectsigstore/cosign \
      sign --identity-token=$(cat token) $(cat image_with_digest) -y
  service_account: '$_SERVICE_ACCOUNT'
  artifacts:
    images:
    - $_IMAGE
  substitutions:
    _IMAGE: 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME'
    _SERVICE_ACCOUNT_ID: 'SERVICE_ACCOUNT_ID'
    _SERVICE_ACCOUNT: projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}
  options:
    env:
    - '_IMAGE=$_IMAGE'
    dynamic_substitutions: true
    logging: CLOUD_LOGGING_ONLY

JSON

    {
        "steps": [
            {
                "name": "gcr.io/cloud-builders/docker",
                "id": "tag-and-push",
                "script": "#!/bin/sh set -e \ndocker build -t $_IMAGE . \ndocker push \"$_IMAGE\""
            },
            {
                "name": "gcr.io/cloud-builders/gcloud",
                "id": "generate-token-and-get-digest",
                "script": "#!/bin/sh set -e \ngcloud auth print-identity-token --audiences=sigstore > token \ngcloud container images describe \"$_IMAGE\" --format=\"value(image_summary.fully_qualified_digest)\" > image_with_digest"
            },
            {
                "name": "gcr.io/projectsigstore/cosign",
                "id": "sign-image",
                "script": "#!/busybox/sh cosign sign --identity-token=$(cat token) $(cat image_with_digest) -y",
                "env": [
                    "SIGSTORE_NO_CACHE=true"
                ]
            }
        ],
        "service_account": "$_SERVICE_ACCOUNT",
        "artifacts": {
            "images": [
                "$_IMAGE"
            ]
        },
        "substitutions": {
            "_IMAGE": "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME",
            "_SERVICE_ACCOUNT_ID": "SERVICE_ACCOUNT_ID",
            "_SERVICE_ACCOUNT": "projects/${PROJECT_ID}/serviceAccounts/${_SERVICE_ACCOUNT_ID}"
        },
        "options": {
            "env": [
                "_IMAGE=$_IMAGE"
            ],
            "dynamic_substitutions": true,
            "logging": "CLOUD_LOGGING_ONLY"
        }
    }

כאשר:

  • LOCATION הוא המיקום האזורי או הרב-אזורי של המאגר שבו התמונה מאוחסנת, לדוגמה us-east1 או us.

  • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .

  • REPOSITORY הוא שם המאגר שבו מאוחסן האימג'.

  • IMAGE_NAME הוא שם התמונה.

  • SERVICE_ACCOUNT_ID היא כתובת האימייל של חשבון השירות שצוין על ידי המשתמש ורוצים להריץ את הבנייה שלו. לדוגמה, כתובת האימייל בחשבון שירות נראית כך: service-account-name@project-id.iam.gserviceaccount.com.

כדי לאמת את החתימה, מתקינים את cosign במחשב המקומי, ואז מריצים את הפקודה cosign verify:

cosign verify \
--certificate-identity=SERVICE_ACCOUNT_ID \
--certificate-oidc-issuer=https://accounts.google.com \
IMAGE

כאשר:

  • SERVICE_ACCOUNT_ID היא כתובת האימייל של חשבון השירות המהימן שאמור היה לשמש ליצירת קובץ האימג' של הקונטיינר.
  • IMAGE הוא השם המלא של התמונה, כולל תמצית הגיבוב sha256 של התמונה.

הפעלת קובץ האימג' של Docker

כדי לוודא שהתמונה שיצרתם פועלת כמו שצריך, אתם יכולים להריץ אותה באמצעות Docker.

  1. מגדירים את Docker כך שישתמש בפרטי הכניסה שלכם ב-Artifact Registry כשמתקשרים עם Artifact Registry. (צריך לעשות את זה רק פעם אחת). כדי לבצע אימות באמצעות כלי העזר לפרטי כניסה של gcloud, משתמשים בפקודה הבאה.

    gcloud auth configure-docker HOSTNAME-LIST
    

    כאשר HOSTNAME-LIST היא רשימה מופרדת בפסיקים של שמות מארחים של מאגרי מידע שרוצים להוסיף להגדרות של כלי העזר לאימות.

    לדוגמה, כדי להוסיף את האזורים us-central1 ו-asia-northeast1, מריצים את הפקודה:

    gcloud auth configure-docker us-central1-docker.pkg.dev,asia-northeast1-docker.pkg.dev
    
  2. מריצים את קובץ האימג' של Docker שיצרתם קודם:

    docker run LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
    

    כאשר:

    • LOCATION: המיקום האזורי או הרב-אזורי של המאגר.
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • REPOSITORY: השם של מאגר Artifact Registry.
    • IMAGE_NAME: השם של קובץ האימג' בקונטיינר.

    הפלט אמור להיראות כך:

    Hello, world! The time is Fri Feb  2 16:09:54 UTC 2018.
    

המאמרים הבאים