מידע על תקצירי קובץ אימג' של קונטיינר

בדף הזה מוסבר מהם תקצירי תמונות, איך למצוא אותם ואיך לאכוף את השימוש בהם באשכולות של Kubernetes. הדף הזה מיועד למפתחים ולמפעילים שיוצרים ופורסים תמונות של קונטיינרים.

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

הפקודות בדף הזה מניחות שיש לכם גישה לסביבת מעטפת של Linux או macOS עם כלים כמו Google Cloud CLI,‏ Docker,‏ cURL,‏ jq ו-pack שכבר מותקנים. אפשר גם להשתמש ב-Cloud Shell, שבו הכלים האלה מותקנים מראש.

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

כשעובדים עם קובצי אימג' של קונטיינר, צריך דרך להפנות לקובצי האימג' שבהם משתמשים. תגי תמונות הם דרך נפוצה להתייחס לגרסאות שונות של תמונה. גישה נפוצה היא לתייג קובצי אימג' עם מזהה גרסה בזמן ה-build. לדוגמה, v1.0.1 יכול להתייחס לגרסה שנקראת 1.0.1.

תגים מאפשרים לחפש בקלות גרסאות של תמונות באמצעות מחרוזות שקריאות לאנשים. עם זאת, תגים הם הפניות שניתנות לשינוי, כלומר התמונה שאליה מפנה התג יכולה להשתנות, כפי שמוצג בתרשים הבא:

תג תמונה שמפנה לתמונה לא עדכנית.

כפי שרואים בתרשים הקודם, אם מפרסמים תמונה חדשה באמצעות אותו תג כמו תמונה קיימת, התג מפסיק להצביע על התמונה הקיימת ומתחיל להצביע על התמונה החדשה.

החסרונות של תגי תמונה

מכיוון שתגים ניתנים לשינוי, יש להם את החסרונות הבאים כשמשתמשים בהם לפריסת קובץ אימג':

  • ב-Kubernetes, פריסה לפי תג עלולה להוביל לתוצאות לא צפויות. לדוגמה, נניח שיש לכם משאב Deployment קיים שמפנה לקובץ אימג' של קונטיינר באמצעות התג v1.0.1. כדי לתקן באג או לבצע שינוי קטן, תהליך ה-build יוצר קובץ אימג' חדש עם אותו תג v1.0.1. יכול להיות שפודים חדשים שנוצרו ממשאב הפריסה ישתמשו בתמונה הישנה או בתמונה החדשה, גם אם לא תשנו את המפרט של משאב הפריסה. הבעיה הזו רלוונטית גם למשאבים אחרים ב-Kubernetes, כמו StatefulSets, ‏ DaemonSets, ‏ ReplicaSets ו-Jobs.

  • אם אתם משתמשים בכלים לסריקה או לניתוח של תמונות, התוצאות של הכלים האלה תקפות רק לגבי התמונה שנסרקה. כדי לוודא שאתם פורסים את התמונה שנסרקה, אל תסתמכו על התג כי יכול להיות שהתמונה שאליה התג מתייחס השתנתה.

  • אם אתם משתמשים ב-Binary Authorization עם Google Kubernetes Engine‏ (GKE), אי אפשר להשתמש בפריסה מבוססת-תגים כי אי אפשר לקבוע את התמונה המדויקת שמשמשת ליצירת Pod.

כשפורסים את התמונות, אפשר להשתמש בסיכום תמונה כדי להימנע מהחסרונות של שימוש בתגים. אתם עדיין יכולים להוסיף תגים לתמונות, אבל אתם לא חייבים לעשות את זה.

מבנה התמונה

תמונה מורכבת מהרכיבים הבאים:

הרכיבים האלה מוצגים בתרשים הבא:

רכיבים של תמונה שבה מוצגים פרטים של מניפסט תמונה, אובייקט הגדרה, שכבות של מערכת קבצים ואינדקס תמונה.

בתמונה הקודמת מוצגים פרטים נוספים על רכיבי התמונה:

  • מניפסט התמונה הוא מסמך JSON שמכיל הפניה לאובייקט ההגדרות האישיות, לשכבות של מערכת הקבצים ולמטא-נתונים אופציונליים.
  • מניפסט התמונה מפנה לאובייקט ההגדרות ולכל אחת משכבות מערכת הקבצים באמצעות מאפייני digest שלהם. הערך של המאפיין digest הוא גיבוב קריפטוגרפי של התוכן שאליו מתייחס ה-digest, בדרך כלל מחושב באמצעות האלגוריתם SHA-256.
  • ערכי התקציר משמשים ליצירת כתובות קבועות לאובייקטים. התהליך הזה נקרא אחסון שניתן לגישה לפי תוכן, והמשמעות שלו היא שאפשר לאחזר מניפסטים של קובצי אימג', אינדקסים של קובצי אימג', אובייקטים של הגדרות אישיות ושכבות על סמך התקצירים שלהם.
  • התקציר של התמונה הוא הגיבוב של אינדקס התמונה או של מסמך ה-JSON של מניפסט התמונה.
  • אובייקט ההגדרה הוא מסמך JSON שמגדיר מאפיינים של התמונה, כמו ארכיטקטורת ה-CPU, נקודת הכניסה, הפורטים שנחשפים ומשתני הסביבה.
  • מערך שכבות מערכת הקבצים מגדיר את הסדר שבו זמן הריצה של הקונטיינר משתמש כדי לערום את השכבות. השכבות מופצות כקובצי tar, שבדרך כלל נדחסים באמצעות הכלי gzip.
  • אינדקס התמונות האופציונלי, שלפעמים נקרא רשימת מניפסט, מתייחס למניפסט אחד או יותר של תמונות. ההפניה היא התקציר של מניפסט התמונה. אינדקס תמונות שימושי כשיוצרים כמה תמונות קשורות לפלטפורמות שונות, כמו ארכיטקטורות amd64 ו-arm64.

למידע נוסף, קראו את הקטע בדיקת מניפסטים, סיכומי ביקורת ותגים של תמונות.

חיפוש תמציות של תמונות

כדי להשתמש בתקצירי תמונות לפריסה, קודם צריך למצוא את התקציר. לאחר מכן, תוכלו להשתמש בתקציר עם פקודת הפריסה או לכלול אותו במניפסטים של Kubernetes.

יש כמה דרכים לקבל את התקציר של תמונה, בהתאם למצב הנוכחי שלכם. בקטעים הבאים יש דוגמאות למוצרים ולכלים שונים.

בקטעים הבאים, מריצים את הפקודות ב-Cloud Shell או בסביבת מעטפת שבה כבר מותקנים כלים כמו ה-CLI של gcloud, ‏Docker, ‏cURL ו-jq.

Artifact Registry

  • לתמונות שמאוחסנות ב-Artifact Registry, אפשר להשתמש בפקודה gcloud artifacts docker images describe.

    gcloud artifacts docker images describe \
        LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG \
        --format 'value(image_summary.digest)'
    

    מחליפים את מה שכתוב בשדות הבאים:

Container Registry

  • לתמונות שמאוחסנות ב-Container Registry, אתם יכולים להשתמש בפקודה gcloud container images describe כדי לקבל את תקציר התמונה על ידי ציון השם והתג. משתמשים בדגל --format כדי להציג רק את התקציר:

    gcloud container images describe \
        gcr.io/google-containers/pause-amd64:3.2 \
        --format 'value(image_summary.digest)'
    

    הפלט אמור להיראות כך, אבל יכול להיות שערך ה-digest יהיה שונה:

    sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
    

Cloud Build

כדי לקבל את ה-digest של קובץ אימג' שנוצר באמצעות Cloud Build, משתמשים בפקודה gcloud builds describe עם הדגל --format. הגישה הזו פועלת בלי קשר למרשם שבו השתמשתם כדי לפרסם את קובץ האימג'.

  • כדי להציג את תוצאות ה-build שכבר הושלם:

    1. מציגים רשימה של גרסאות build של הפרויקט:

      gcloud builds list
      

      רושמים הערה לגבי BUILD_ID.

    2. קבלת תקציר התמונה:

      gcloud builds describe BUILD_ID \
          --format 'value(results.images[0].digest)'
      

      מחליפים את BUILD_ID במזהה הייחודי ש-Cloud Build הקצה ל-build.

  • משיגים את שם התמונה ואת ה-digest של ה-build האחרון מ-Cloud Build לפרויקט הנוכחי:

    gcloud builds describe \
        $(gcloud builds list --limit 1 --format 'value(id)') \
        --format 'value[separator="@"](results.images[0].name,results.images[0].digest)'
    
  • אם ה-build הפיק כמה קובצי אימג', מסננים את הפלט ומקבלים את תקציר ה-digest של אחד מקובצי האימג':

    gcloud builds describe BUILD_ID --format json \
        | jq -r '.results.images[] | select(.name=="YOUR_IMAGE_NAME") | .digest'
    

    מחליפים את YOUR_IMAGE_NAME בשם של אחד מהאימג'ים בקובץ cloudbuild.yaml.

  • אם אתם שולחים build ל-Cloud Build באמצעות הפקודה gcloud builds submit, אתם יכולים לתעד את סיכום קובץ האימג' מהפלט במשתנה סביבה:

    IMAGE_DIGEST=$(gcloud builds submit \
        --format 'value(results.images[0].digest)' | tail -n1)
    

Cloud Native Buildpacks

  • אם אתם משתמשים ב-Cloud Native Buildpacks וב- Google Cloud builder כדי ליצור ולפרסם קובצי אימג', אתם יכולים לתעד את השם והתקציר של קובץ האימג' באמצעות הדגל --quiet עם הפקודה pack:

    pack build --builder gcr.io/buildpacks/builder:v1 --publish --quiet \
        LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \
        > image-with-digest.txt
    

    מחליפים את מה שכתוב בשדות הבאים:

    הקובץ image-with-digest.txt מכיל את שם התמונה ואת ה-digest.

    אם רוצים להוסיף תגים לתמונה, משתמשים בדגל --tag.

לקוח Docker

  • אפשר להשתמש בפקודת המשנה manifest של לקוח שורת הפקודה docker כדי לאחזר מניפסטים של קובצי אימג' ורשימות של מניפסטים ממאגרי קובצי אימג' של קונטיינרים.

    מקבלים את ה-digest מרשימת המניפסט של התמונה registry.k8s.io/pause:3.9, עבור ארכיטקטורת המעבד amd64 ומערכת ההפעלה linux:

    docker manifest inspect --verbose registry.k8s.io/pause:3.9 | \
        jq -r 'if type=="object"
            then .Descriptor.digest
            else .[] | select(.Descriptor.platform.architecture=="amd64" and
            .Descriptor.platform.os=="linux") | .Descriptor.digest
            end'
    

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

    sha256:8d4106c88ec0bd28001e34c975d65175d994072d65341f62a8ab0754b0fafe10
    
  • כדי לקבל את הגיבוב של תמונות שמאוחסנות בדמון Docker המקומי, ושנמשכו ממאגר תמונות או נדחפו אליו, אפשר להשתמש בכלי של שורת הפקודה של Docker:

    1. מושכים את קובץ האימג' אל הדמון המקומי של Docker:

      docker pull docker.io/library/debian:bookworm
      
    2. מקבלים את תקציר התמונה:

      docker inspect docker.io/library/debian:bookworm \
          | jq -r '.[0].RepoDigests[0]' \
          | cut -d'@' -f2
      

      הפלט אמור להיראות כך, אבל יכול להיות שערך התקציר יהיה שונה:

      sha256:3d868b5eb908155f3784317b3dda2941df87bbbbaa4608f84881de66d9bb297b
      
  • מציגים את כל קובצי האימג' והתקצירים ב-Docker daemon המקומי:

    docker images --digests
    

    הפלט מציג תקצירים של תמונות שיש להן ערך תקציר. לתמונות יש ערך גיבוב רק אם הן נמשכו ממאגר תמונות או נדחפו אליו.

crane וגם gcrane

אתם יכולים להשתמש בכלי שורת הפקודה בקוד פתוח crane ו-gcrane כדי לקבל את תקציר ה-SHA של קובץ אימג' בלי למשוך את קובץ האימג' ל-Docker daemon מקומי.

  1. מורידים את crane ואת gcrane לספרייה הנוכחית:

    VERSION=$(curl -sL https://api.github.com/repos/google/go-containerregistry/releases/latest | jq -r .tag_name)
    curl -L "https://github.com/google/go-containerregistry/releases/download/${VERSION}/go-containerregistry_$(uname -s)_$(uname -m).tar.gz" | tar -zxf - crane gcrane
    
  2. לקבלת סיכום של תמונות:

    ./gcrane digest gcr.io/distroless/static-debian11:nonroot
    

    ל-crane ול-gcrane יש תכונות נוספות שלא נכללות בדף הזה. מידע נוסף זמין במאמרי העזרה בנושא crane ו-gcrane.

אכיפת השימוש בתקצירי תמונות בפריסות של Kubernetes

אם רוצים לאכוף שימוש בערכי גיבוב (digest) לתמונות שמבצעים להן פריסה באשכולות Kubernetes, אפשר להשתמש ב-Policy Controller או ב-Open Policy Agent (OPA) Gatekeeper. ‫Policy Controller מבוסס על פרויקט הקוד הפתוח OPA Gatekeeper.

גם Policy Controller וגם OPA Gatekeeper מבוססים על מנוע המדיניות של OPA. ‫Policy Controller ו-OPA Gatekeeper מספקים webhook לאימות הרשאות גישה ב-Kubernetes כדי לאכוף כללי מדיניות, והגדרות של משאבים בהתאמה אישית (CRD) לתבניות של אילוצים ואילוצים.

תבניות אילוצים מכילות לוגיקה של מדיניות שמוצגת באמצעות שפה הצהרתית ברמה גבוהה שנקראת Rego. זאת תבנית אילוצים שמאמתת שקונטיינרים, קונטיינרים של init וקונטיינרים זמניים במפרט של משאב ב-Kubernetes משתמשים בתמונות עם סיכומי ביקורת:

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8simagedigests
  annotations:
    metadata.gatekeeper.sh/title: "Image Digests"
    metadata.gatekeeper.sh/version: 1.0.1
    description: >-
      Requires container images to contain a digest.

      https://kubernetes.io/docs/concepts/containers/images/
spec:
  crd:
    spec:
      names:
        kind: K8sImageDigests
      validation:
        openAPIV3Schema:
          type: object
          description: >-
            Requires container images to contain a digest.

            https://kubernetes.io/docs/concepts/containers/images/
          properties:
            exemptImages:
              description: >-
                Any container that uses an image that matches an entry in this list will be excluded
                from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

                It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
                in order to avoid unexpectedly exempting images from an untrusted repository.
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8simagedigests

        import data.lib.exempt_container.is_exempt

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not is_exempt(container)
          not regex.match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)
          msg := sprintf("container <%v> uses an image without a digest <%v>", [container.name, container.image])
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.initContainers[_]
          not is_exempt(container)
          not regex.match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)
          msg := sprintf("initContainer <%v> uses an image without a digest <%v>", [container.name, container.image])
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.ephemeralContainers[_]
          not is_exempt(container)
          not regex.match("@[a-z0-9]+([+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+", container.image)
          msg := sprintf("ephemeralContainer <%v> uses an image without a digest <%v>", [container.name, container.image])
        }
      libs:
        - |
          package lib.exempt_container

          is_exempt(container) {
              exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
              img := container.image
              exemption := exempt_images[_]
              _matches_exemption(img, exemption)
          }

          _matches_exemption(img, exemption) {
              not endswith(exemption, "*")
              exemption == img
          }

          _matches_exemption(img, exemption) {
              endswith(exemption, "*")
              prefix := trim_suffix(exemption, "*")
              startswith(img, prefix)
          }

המדיניות שלמעלה מכילה ביטוי רגולרי כקלט של הפונקציה re_match. הביטוי הרגולרי הזה תואם ל-digest של קובץ האימג' של הקונטיינר, והוא מבוסס על פורמט ה-digest במפרט של Open Container Initiative Image.

האילוצים מחילים את המדיניות על משאבים ב-Kubernetes על ידי התאמה למאפיינים כמו kind ו-namespace. האילוץ הבא לדוגמה מחיל את המדיניות מתבנית האילוצים על כל המשאבים מסוג Pod במרחב השמות default.

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sImageDigests
metadata:
  name: container-image-must-have-digest
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - "default"

אחרי שיוצרים את תבנית האילוץ ואת האילוץ, כל pod חדש במרחב השמות default חייב להשתמש בתקצירי תמונות כדי להפנות לקובצי אימג' של קונטיינרים.

לדוגמה המלאה, עיינו במדיניות imagedigests בספריית המדיניות של Gatekeeper.

מידע על מניפסטים, סיכומי ביקורת ותגים של קובצי אימג'

בקטע הזה נסביר איך לבדוק תמונות קיימות במאגרים באמצעות כלים של שורת הפקודה, כמו curl ו-docker. מריצים את הפקודות ב-Cloud Shell או בסביבת מעטפת שבה כבר מותקנים כלים כמו ה-CLI של gcloud,‏ Docker,‏ cURL ו-jq. הפקודות הבאות משתמשות בתמונות ציבוריות ב-Artifact Registry.

  • מורידים את המניפסט של קובץ האימג' gcr.io/google-containers/pause-amd64:3.2 באמצעות cURL וכתובת ה-URL של המניפסט:

    curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2
    

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

    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
       "config": {
          "mediaType": "application/vnd.docker.container.image.v1+json",
          "size": 759,
          "digest": "sha256:80d28bedfe5dec59da9ebf8e6260224ac9008ab5c11dbbe16ee3ba3e4439ac2c"
       },
       "layers": [
          {
             "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
             "size": 296534,
             "digest": "sha256:c74f8866df097496217c9f15efe8f8d3db05d19d678a02d01cc7eaed520bb136"
          }
       ]
    }
    

    בקטע config יש מאפיין של תקציר, ואפשר להשתמש בערך הזה כדי לאחזר את אובייקט ההגדרה. באופן דומה, לכל שכבה יש מאפיין digest שאפשר להשתמש בו כדי לאחזר את קובץ ה-tar של אותה שכבה.

  • אם התמונה כוללת את אינדקס התמונות האופציונלי, בקשת HTTP GET לכתובת ה-URL של המניפסט באמצעות תג מחזירה את אינדקס התמונות במקום את מניפסט התמונה.

    קבלת אינדקס התמונה של התמונה gcr.io/google-containers/pause:3.2:

    curl -s https://gcr.io/v2/google-containers/pause/manifests/3.2
    

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

    {
       "schemaVersion": 2,
       "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
       "manifests": [
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 526,
             "digest": "sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108",
             "platform": {
                "architecture": "amd64",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 526,
             "digest": "sha256:bbb7780ca6592cfc98e601f2a5e94bbf748a232f9116518643905aa30fc01642",
             "platform": {
                "architecture": "arm",
                "os": "linux",
                "variant": "v7"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 526,
             "digest": "sha256:31d3efd12022ffeffb3146bc10ae8beb890c80ed2f07363515580add7ed47636",
             "platform": {
                "architecture": "arm64",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 526,
             "digest": "sha256:7f82fecd72730a6aeb70713476fb6f7545ed1bbf32cadd7414a77d25e235aaca",
             "platform": {
                "architecture": "ppc64le",
                "os": "linux"
             }
          },
          {
             "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
             "size": 526,
             "digest": "sha256:1175fd4d728641115e2802be80abab108b8d9306442ce35425a4e8707ca60521",
             "platform": {
                "architecture": "s390x",
                "os": "linux"
             }
          }
       ]
    }
    
  • מסננים את התוצאה כדי לחלץ את תקציר התמונה לפלטפורמה הרצויה. קבלת התקציר של מניפסט התמונה עבור amd64 ארכיטקטורת המעבד ומערכת ההפעלה linux:

    curl -s https://gcr.io/v2/google-containers/pause/manifests/3.2 | \
        jq -r '.manifests[] | select(.platform.architecture=="amd64" and .platform.os=="linux") | .digest'
    

    הסינון בפקודה הזו מחקה את האופן שבו סביבות זמן ריצה של קונטיינרים, כמו containerd, בוחרות את התמונה שתואמת לפלטפורמת היעד מאינדקס התמונות.

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

    sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
    

    תקציר התמונה הוא התוצאה של החלת גיבוב עמיד בפני התנגשויות על אינדקס התמונה או על מניפסט התמונה, בדרך כלל באמצעות אלגוריתם SHA-256.

  • קבלת התקציר של התמונה gcr.io/google-containers/pause-amd64:3.2:

    curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \
        | shasum -a 256 \
        | cut -d' ' -f1
    

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

    4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
    

    אפשר להפנות לתמונה הזו באמצעות ערך ה-digest של התמונה באופן הבא:

    gcr.io/google-containers/pause-amd64@sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
    
  • באמצעות הקונספט של אחסון שניתן לגישה לפי תוכן, מקבלים את מניפסט התמונה באמצעות שימוש בתקציר כהפניה:

    curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
    
  • הרבה מאגרי קובצי אימג' של קונטיינרים מחזירים את תקציר המניפסטים, אינדקסי התמונות, אובייקטי ההגדרות ושכבות מערכת הקבצים בכותרת Docker-Content-Digest בתגובה לבקשות HTTP HEAD. משיגים את תקציר אינדקס התמונות של התמונה gcr.io/google-containers/pause-amd64:3.2:

    curl -s --head https://gcr.io/v2/google-containers/pause/manifests/3.2 \
        | grep -i Docker-Content-Digest \
        | cut -d' ' -f2
    

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

    sha256:927d98197ec1141a368550822d18fa1c60bdae27b78b0c004f705f548c07814f
    

    הכותרת Docker-Content-Digest לא נדרשת לפי המפרטים של Open Container Initiative Distribution, ולכן יכול להיות שהגישה הזו לא תעבוד עם כל מאגרי קובצי האימג' של קונטיינרים. אפשר להשתמש בו עם Artifact Registry ועם Container Registry.

  • כדי לאחזר אובייקט של הגדרת אימג' באמצעות ערך התקציר ממניפסט האימג':

    1. מקבלים את תקציר ההגדרות:

      CONFIG_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \
          | jq -r '.config.digest')
      
    2. משתמשים בתקציר ההגדרות כדי לאחזר את אובייקט ההגדרות, ומשתמשים ב-jq כדי לעצב את הפלט כך שיהיה קל יותר לקרוא אותו:

      curl -sL https://gcr.io/v2/google-containers/pause-amd64/blobs/$CONFIG_DIGEST \
          | jq
      

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

      {
        "architecture": "amd64",
        "config": {
          "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
          ],
          "Entrypoint": [
            "/pause"
          ],
          "WorkingDir": "/",
          "OnBuild": null
        },
        "created": "2020-02-14T10:51:50.60182885-08:00",
        "history": [
          {
            "created": "2020-02-14T10:51:50.60182885-08:00",
            "created_by": "ARG ARCH",
            "comment": "buildkit.dockerfile.v0",
            "empty_layer": true
          },
          {
            "created": "2020-02-14T10:51:50.60182885-08:00",
            "created_by": "ADD bin/pause-amd64 /pause # buildkit",
            "comment": "buildkit.dockerfile.v0"
          },
          {
            "created": "2020-02-14T10:51:50.60182885-08:00",
            "created_by": "ENTRYPOINT [\"/pause\"]",
            "comment": "buildkit.dockerfile.v0",
            "empty_layer": true
          }
        ],
        "os": "linux",
        "rootfs": {
          "type": "layers",
          "diff_ids": [
            "sha256:ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770"
          ]
        }
      }
      
  • כדי לאחזר שכבות של מערכת קבצים באמצעות ערכי הגיבוב ממניפסט התמונה:

    1. משיגים את התקציר של השכבה שרוצים לאחזר:

      LAYER_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \
          | jq -r '.layers[0].digest')
      
    2. משתמשים בסיכום השכבה כדי לאחזר את קובץ ה-tar של השכבה, ומציגים את התוכן:

      curl -sL https://gcr.io/v2/google-containers/pause-amd64/blobs/$LAYER_DIGEST \
          | tar --list
      

      בשכבה הזו יש רק קובץ אחד, שנקרא pause.

  • כדי לחפש תגים שמשויכים לתקציר תמונה:

    1. מגדירים את התקציר שרוצים לחפש:

      IMAGE_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \
          | shasum -a 256 \
          | cut -d' ' -f1)
      

      משתנה הסביבה IMAGE_DIGEST מכיל את תקציר התמונה שאליו מפנה התג 3.2.

    2. משתמשים בנקודת הקצה של רשימת תגי התמונות, /tags/list, כדי להציג את פרטי התגים ולחלץ את התגים של ערך התקציר:

      curl -s "https://gcr.io/v2/google-containers/pause-amd64/tags/list?n=1" \
          | jq ".manifest.\"sha256:$IMAGE_DIGEST\".tag"
      

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

      [
        "3.2"
      ]
      
  • כדי לקבל את המניפסט של קובץ אימג' ממאגר קובצי אימג' של קונטיינרים ב-Artifact Registry באמצעות cURL, צריך לכלול אסימון גישה בכותרת הבקשה Authorization:

    curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        https://LOCATION-docker.pkg.dev/v2/PROJECT_ID/REPOSITORY/IMAGE/manifests/DIGEST
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫LOCATION: המיקום האזורי או הרב-אזורי של המאגר
    • ‫PROJECT_ID: Google Cloud מזהה הפרויקט ב-
    • ‫REPOSITORY: שם המאגר שלכם
    • ‫IMAGE: שם התמונה
    • ‫DIGEST: תקציר התמונה בפורמט sha256:DIGEST_VALUE

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

  • למידע נוסף על קובצי אימג', קראו את המפרטים של Open Container Initiative בנושא פורמט תמונה והפצה.