Container-Image-Digests in Kubernetes-Manifesten verwenden

Last reviewed 2023-07-21 UTC

In dieser Anleitung wird Entwicklern und Anbietern, die Container in Kubernetes bereitstellen, gezeigt, wie Container-Image-Digests zur Identifizierung von Container-Images verwendet werden können. Ein Container-Image-Digest identifiziert ein Container-Image eindeutig und unveränderlich.

Das Bereitstellen von Container-Images mithilfe des Image-Digest bietet im Vergleich zur Verwendung von Image-Tags mehrere Vorteile. Bevor Sie mit dieser Anleitung fortfahren, finden Sie weitere Informationen zu Image-Digests im zugehörigen Dokument zur Verwendung von Container-Image-Digests.

Das Argument image für Container in einer Kubernetes Pod-Spezifikation akzeptiert Images mit Digests. Dieses Argument wird überall dort angewendet, wo Sie eine Pod-Spezifikation verwenden, z. B. im Abschnitt template der Deployment-, StatefulSet-, DaemonSet-, ReplicaSet-, CronJob- und Jobressourcen.

Zur Bereitstellung eines Images mithilfe des Digest verwenden Sie den Image-Namen, gefolgt von @sha256: und dem Digest-Wert. Das folgende Beispiel zeigt eine Deployment-Ressource, die ein Image mit einem Digest verwendet:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo-deployment
spec:
  selector:
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        ports:
        - containerPort: 8080

Ein Nachteil der Verwendung von Image-Digests ist, dass Sie den Digest-Wert erst kennen, wenn Sie das Image in einer Registry veröffentlicht haben. Wenn Sie neue Images erstellen, ändert sich der Digest-Wert und Sie müssen bei jeder Bereitstellung die Möglichkeit haben, Ihre Kubernetes-Manifeste zu aktualisieren.

In dieser Anleitung wird beschrieben, wie Sie Tools wie Skaffold, kpt, digester, kustomize, gke-deploy und ko nutzen, um Image-Digests in Ihren Manifesten zu verwenden.

Empfehlungen

In diesem Dokument werden verschiedene Möglichkeiten zur Verwendung von Image-Digests in Kubernetes-Deployments vorgestellt. Die in diesem Dokument beschriebenen Tools ergänzen sich. Sie können beispielsweise die Ausgabe einer kpt-Funktion mit kustomize verwenden, um Varianten für verschiedene Umgebungen zu erstellen. Skaffold kann Images mit ko erstellen und diese mit kubectl oder kpt in Ihren Kubernetes-Clustern bereitstellen.

Die Tools ergänzen sich, weil sie strukturierte Änderungen auf der Grundlage des Kubernetes-Ressourcenmodells (KRM) vornehmen. Durch dieses Modell sind die Tools plugbar und Sie können Ihre Nutzung der Tools zum Erstellen von Prozessen und Pipelines verbessern, mit denen Sie Ihre Anwendungen und Dienste bereitstellen.

Wir empfehlen Ihnen für den Einstieg die Vorgehensweise, die am besten mit Ihren vorhandenen Tools und Prozessen funktioniert:

  • Skaffold kann Digests zu Image-Referenzen hinzufügen. Sie aktivieren diese Funktion mit einer kleinen Konfigurationsänderung. Die Verwendung von Skaffold bietet zusätzliche Vorteile, z. B. die Abstraktion, wie verschiedene Tools und Container-Images erstellen und bereitstellen.

  • Wenn Sie das Digest-Tool als mutierenden Zulassungs-Webhook in Ihren Kubernetes-Clustern verwenden, können Sie allen Ihren Bereitstellungen Digests mit minimaler Auswirkung auf Ihre aktuellen Prozesse zum Erstellen und Bereitstellen von Container-Images hinzufügen. Der Digest-Webhook vereinfacht auch die Akzeptanz der Binärautorisierung, da nur ein Label zu einem Namespace hinzugefügt werden muss.

  • kpt ist eine gute Möglichkeit, wenn Sie ein flexibles Tool benötigen, um Kubernetes-Manifeste zu bearbeiten. Das Digest-Tool kann als clientseitige KRM-Funktion in einer kpt-Pipeline verwendet werden.

  • Wenn Sie kustomize bereits für die Verwaltung von Kubernetes-Manifesten in verschiedenen Umgebungen verwenden, empfehlen wir Ihnen, die Image-Transformer zur Bereitstellung von Images nach Digest zu verwenden.

  • ko ist eine gute Möglichkeit, um Images für Go-Anwendungen zu erstellen und zu veröffentlichen. Es wird von Open-Source-Projekten wie Knative und Tekton und sigstore.verwendet.

Wenn Sie keines der in diesem Dokument beschriebenen Tools verwenden, empfehlen wir, mit Skaffold und dem Digest-Webhook zu beginnen. Skaffold ist ein gängiges Tool, das von Entwicklern und Release-Teams verwendet wird und sich in die anderen Tools in dieser Anleitung integrieren lässt. Diese Integrationsoptionen können Sie nutzen, wenn sich Ihre Anforderungen ändern. Der Digest-Kubernetes-Webhook ergänzt Skaffold durch die Aktivierung von Digest-basierten Bereitstellungen für einen gesamten Cluster.

Lernziele

  • Verwenden Sie Skaffold, um ein Image zu erstellen und per Push zu übertragen sowie den Image-Namen und den Digest in ein Kubernetes-Manifest einzufügen.
  • Verwenden Sie die clientseitige Digest-Funktion und den mutierenden Zulassungs-Webhook, um Digests zu Images in Kubernetes-Pods und Pod-Vorlagen hinzuzufügen.
  • Mit kpt-Settern können Sie ein Image-Tag in einem Kubernetes-Manifest durch einen Image-Digest ersetzen.
  • Verwenden Sie kustomize, um ein Kubernetes-Manifest mit einem Image-Digest zu generieren.
  • Verwenden Sie gke-deploy, um ein Image-Tag in einen Digest in einem Kubernetes-Manifest aufzulösen.
  • Verwenden Sie ko, um ein Image zu erstellen und per Push zu übertragen und den Image-Namen und das Digest in ein Kubernetes-Manifest einzufügen.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Artifact Registry API.

    Enable the API

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. Legen Sie in Cloud Shell das Standardprojekt für die Google Cloud CLI fest:

    gcloud config set project PROJECT_ID
    

    Ersetzen Sie PROJECT_ID durch Ihre [project ID].

  6. Erstellen Sie in Artifact Registry ein Container-Image-Repository:

    gcloud artifacts repositories create REPOSITORY \
        --location=LOCATION \
        --repository-format=docker
    

    Ersetzen Sie Folgendes:

    • REPOSITORY: Der Name, den Sie für Ihr Repository verwenden möchten, z. B. digest-tutorial.
    • LOCATION: ein Artifact Registry-Speicherort, z. B. us-central1.
  7. Konfigurieren Sie die Authentifizierung am Artifact Registry-Speicherort für die in dieser Anleitung verwendeten Befehlszeilentools:

    gcloud auth configure-docker LOCATION-docker.pkg.dev
    

Skaffold verwenden

Skaffold ist ein Befehlszeilentool für die kontinuierliche Entwicklung und Bereitstellung von Anwendungen auf Kubernetes-Clustern.

Verwenden Sie Skaffold, um ein Image zu erstellen, das Image per Push an Artifact Registry zu übertragen und den Platzhalterwert image in einer Kubernetes-Manifestvorlage durch den Namen, das Tag und den Digest des übertragenen Images zu ersetzen:

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/skaffold
    cd ~/container-image-digests-tutorial/skaffold
    
  2. Klonen Sie das Git-Repository für Skaffold:

    git clone https://github.com/GoogleContainerTools/skaffold.git
    
  3. Rufen Sie das Verzeichnis des Beispiels getting-started auf:

    cd skaffold/examples/getting-started
    
  4. Sehen Sie sich das Git-Tag an, das Ihrer Version von Skaffold entspricht:

    git checkout $(skaffold version)
    
  5. Sehen Sie sich die Konfigurationsdatei skaffold.yaml an:

    cat skaffold.yaml
    

    Die Datei sieht in etwa so aus:

    apiVersion: skaffold/v4beta6
    kind: Config
    build:
      artifacts:
      - image: skaffold-example
    manifests:
      rawYaml:
      - k8s-pod.yaml
    

    Der Abschnitt build.artifacts enthält einen Platzhalter-Image-Namen. Skaffold sucht in den Eingabemanifestdateien nach diesem Platzhalter.

    Im Abschnitt manifests wird Skaffold angewiesen, ein Eingabemanifest aus dem aktuellen Verzeichnis mit dem Namen k8s-pod.yaml zu lesen.

    Eine Übersicht über alle verfügbaren Optionen finden Sie in der Referenzdokumentation zu skaffold.yaml.

  6. Sehen Sie sich die Kubernetes-Manifestvorlage an:

    cat k8s-pod.yaml
    

    Dies ist die Datei:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - name: getting-started
        image: skaffold-example
    

    Der Platzhalterwert skaffold-example im Feld image entspricht dem Wert des Felds image in der Datei skaffold.yaml. Skaffold ersetzt diesen Platzhalterwert durch den vollständigen Image-Namen und den Digest in der gerenderten Ausgabe.

  7. Erstellen Sie das Image und übertragen Sie es per Push in die Artifact Registry:

    skaffold build \
        --default-repo=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY \
        --file-output=artifacts.json \
        --interactive=false \
        --push=true \
        --update-check=false
    

    Dieser Befehl verwendet die folgenden Flags:

    • Das Flag --file-output gibt die Datei an, in der Skaffold Informationen zum erstellten Image speichert, einschließlich des Digest-Werts.
    • Das Flag --push weist Skaffold an, das erstellte Image in die durch das Flag --default-repo angegebene Container-Image-Registry zu übertragen.
    • Die Flags --interactive und --update-check sind beide auf false gesetzt. Setzen Sie diese Flags in nicht interaktiven Umgebungen wie Build-Pipelines auf false, behalten Sie sie aber als Standardwerte (true für beide Flags) für die lokale Entwicklung bei.

    Wenn Sie für die Bereitstellung in GKE Cloud Deploy verwenden, verwenden Sie die Datei aus dem --file-output-Flag als Wert für das --build-artifacts-Flag, wenn Sie ein Release erstellen.

  8. Rendern Sie das erweiterte Kubernetes-Manifest mit dem Namen, dem Tag und dem Digest des Container-Images aus dem vorherigen Schritt:

    skaffold render \
        --build-artifacts=artifacts.json \
        --digest-source=none \
        --interactive=false \
        --offline=true \
        --output=rendered.yaml \
        --update-check=false
    

    Dieser Befehl verwendet die folgenden Flags:

    • Das Flag --build-artifacts verweist auf die Ausgabedatei aus dem Befehl skaffold build im vorherigen Schritt.
    • Das Flag --digest-source=none bedeutet, dass Skaffold den Digest-Wert aus der im Flag --build-artifacts angegebenen Datei verwendet, anstatt den Digest aus der Container-Image-Registry aufzulösen.
    • Das Argument --offline=true bedeutet, dass Sie den Befehl ausführen können, ohne Zugriff auf einen Kubernetes-Cluster zu benötigen.
    • Das Flag --output gibt die Ausgabedatei für das gerenderte Manifest an.
  9. Rufen Sie das gerenderte Manifest auf:

    cat rendered.yaml
    

    Die Ausgabe sollte so aussehen:

    apiVersion: v1
    kind: Pod
    metadata:
      name: getting-started
    spec:
      containers:
      - image: LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/skaffold-example:TAG@sha256:DIGEST
        name: getting-started
    

    In dieser Ausgabe sehen Sie die folgenden Werte:

    • TAG: das Tag, das dem Image vom Skaffold zugewiesen wurde.
    • DIGEST: der Wert des Image-Digests

Digest verwenden

Digester fügt Digests zu Container- und init-Container-Images in Kubernetes-Pod- und Pod-Vorlagenspezifikationen hinzu. Digester ersetzt Container-Image-Referenzen, die Tags verwenden:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10

Mit Verweisen, die den Image-Digest verwenden:

spec:
  containers:
  - image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

Digester kann entweder als mutierender Zulassungs-Webhook in einem Kubernetes-Cluster oder als clientseitige KRM-Funktion mit den kpt- oder kustomize-Befehlszeilentools ausgeführt werden.

Digest-KRM-Funktion verwenden

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/digester-fn
    cd ~/container-image-digests-tutorial/digester-fn
    
  2. Laden Sie die Digest-Binärdatei herunter:

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    curl -L "https://github.com/google/k8s-digester/releases/download/${DIGESTER_VERSION}/digester_$(uname -s)_$(uname -m)" --output ${HOME}/bin/digester
    chmod +x ${HOME}/bin/digester
    
  3. Erstellen Sie mit dem Tag 1.10 ein Kubernetes-Deployment-Manifest, das auf das Image gcr.io/google-containers/echoserver verweist:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Führen Sie die Digester-KRM-Funktion mit kpt mit den Manifesten im aktuellen Verzeichnis (.) aus:

    kpt fn eval . --exec digester
    

    Wenn Sie diesen Befehl ausführen, führt kpt eine direkte Aktualisierung der Manifeste im aktuellen Verzeichnis durch. Wenn Sie möchten, dass kpt das aktualisierte Manifest in der Konsole anzeigt und die Manifestdatei unverändert lässt, fügen Sie das Flag --output unwrap hinzu.

  5. Rufen Sie das aktualisierte Manifest auf:

    cat pod.yaml
    

    Dies ist die Datei:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
        - name: echoserver
          image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
          ports:
            - containerPort: 8080
    

Digest-Zulassungs-Webhook verwenden

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/digester-webhook
    cd ~/container-image-digests-tutorial/digester-webhook
    
  2. Erstellen Sie einen lokalen Kubernetes-Cluster mit kind:

    kind create cluster
    

    „kind“ ist ein Befehlszeilentool zum Ausführen lokaler Kubernetes-Cluster mit Docker.

  3. Stellen Sie den Digest-Webhook bereit:

    DIGESTER_VERSION=$(curl -sL https://api.github.com/repos/google/k8s-digester/releases/latest | jq -r .tag_name)
    kustomize build "https://github.com/google/k8s-digester.git/manifests?ref=${DIGESTER_VERSION}" | kubectl apply -f -
    
  4. Erstellen Sie einen Kubernetes-Namespace namens digester-demo im Typcluster:

    kubectl create namespace digester-demo
    
  5. Fügen Sie dem Namespace digester-demo das Label digest-resolution: enabled hinzu:

    kubectl label namespace digester-demo digest-resolution=enabled
    

    Der Digest-Webhook fügt Digests zu Pods in Namespaces mit diesem Label hinzu.

  6. Erstellen Sie mit dem Tag 1.10 ein Kubernetes-Deployment-Manifest, das auf das Image gcr.io/google-containers/echoserver verweist:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  7. Wenden Sie das Manifest im Namespace digester-demo an:

    kubectl apply --filename deployment.yaml --namespace digester-demo \
        --output jsonpath='{.spec.template.spec.containers[].image}{"\n"}'
    

    Das Flag --output weist kubectl an, den Image-Namen an die Konsole auszugeben, gefolgt von einem Zeilenumbruch. Die Ausgabe sieht so aus:

    gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    

    Diese Ausgabe zeigt, dass der Digest-Webhook den Image-Digest der Pod-Vorlagenspezifikation in der Deployment-Ressource hinzugefügt hat.

  8. Löschen Sie den Typcluster, um Ressourcen in der Cloud Shell-Sitzung freizugeben:

    kind delete cluster
    

kpt-Setter verwenden

kpt ist ein Befehlszeilentool zum Verwalten, Bearbeiten, Anpassen und Anwenden von Kubernetes-Ressourcenmanifesten

Sie können die KRM-Funktionen create-setters und apply-setters aus dem kpt Functions-Katalog verwenden, um beim Erstellen neuer Images Image-Digests in Ihren Kubernetes-Manifesten zu aktualisieren.

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/kpt
    cd ~/container-image-digests-tutorial/kpt
    
  2. Erstellen Sie ein kpt-Paket im aktuellen Verzeichnis:

    kpt pkg init --description "Container image digest tutorial"
    
  3. Erstellen Sie mit dem Tag 1.10 ein Kubernetes-Deployment-Manifest, das auf das Image gcr.io/google-containers/echoserver verweist:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Verwenden Sie kpt, um einen Setter namens echoimage für das Manifestfeld zu erstellen, wobei der vorhandene Wert gcr.io/google-containers/echoserver:1.10 ist:

    kpt fn eval . \
        --image gcr.io/kpt-fn/create-setters@sha256:0220cc87f29ff9abfa3a3b5643aa50f18d355d5e9dc9e1f518119633ddc4895c \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10"
    
  5. Rufen Sie die Anzeige des Manifests auf:

    cat pod.yaml
    

    Dies ist die Datei:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    
  6. Rufen Sie den Digest-Wert des Container-Images ab:

    DIGEST=$(gcloud container images describe \
        gcr.io/google-containers/echoserver:1.10 \
        --format='value(image_summary.digest)')
    
  7. Legen Sie den neuen Feldwert fest:

    kpt fn eval . \
        --image gcr.io/kpt-fn/apply-setters@sha256:4d4295727183396f0c3c6a75d2560254c2f9041a39e95dc1e5beffeb49cc1a12 \
        -- "echoimage=gcr.io/google-containers/echoserver:1.10@$DIGEST"
    

    Wenn Sie diesen Befehl ausführen, führt kpt eine direkte Ersetzung des Feldwerts image im Manifest durch.

  8. Rufen Sie das aktualisierte Manifest auf:

    cat pod.yaml
    

    Dies ist die Datei:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 # kpt-set: ${echoimage}
        ports:
        - containerPort: 8080
    

kustomize-Image-Transformer verwenden

kustomize ist ein Befehlszeilentool, mit dem Sie Kubernetes-Manifeste mithilfe von Overlays, Patches und Transformern anpassen können.

Sie können den kustomize-Image-Transformer nutzen, um den Image-Namen, das Tag und den Digest in Ihrem vorhandenen Manifest zu aktualisieren.

Das folgende kustomization.yaml-Snippet zeigt, wie Sie den Image-Transformer konfigurieren, um den Wert digest des Transformers für Images zu verwenden, bei denen der Wert der Pod-Spezifikation image dem Wert name des Transformers entspricht:

images:
- name: gcr.io/google-containers/echoserver
  digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229

So verwenden Sie einen kustomize-Image-Transformer mit einem Image-Digest:

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/kustomize
    cd ~/container-image-digests-tutorial/kustomize
    
  2. kustomization.yaml-Datei erstellen:

    kustomize init
    
  3. Erstellen Sie ein Kubernetes-Manifest mit einer Pod-Spezifikation, die auf das Image gcr.io/google-containers/echoserver mithilfe des Tags 1.10 verweist:

    cat << EOF > pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - name: echoserver
        image: gcr.io/google-containers/echoserver:1.10
        ports:
        - containerPort: 8080
    EOF
    
  4. Fügen Sie das Manifest als Ressource zur Datei kustomization.yaml hinzu:

    kustomize edit add resource pod.yaml
    
  5. Aktualisieren Sie den Image-Digest mit einem Image-Transformer:

    kustomize edit set image \
        gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
    
  6. Sehen Sie sich den Image-Transformer in der Datei kustomization.yaml an:

    cat kustomization.yaml
    

    Dies ist die Datei:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - pod.yaml
    images:
    - digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
      name: gcr.io/google-containers/echoserver
    
  7. Sehen Sie sich das resultierende Manifest an:

    kustomize build .
    

    Die Ausgabe sieht so aus:

    apiVersion: v1
    kind: Pod
    metadata:
      name: echo
    spec:
      containers:
      - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
        name: echoserver
        ports:
        - containerPort: 8080
    
  8. Sie können den Befehl kubectl apply mit dem Flag --kustomize verwenden, um den kustomize-Transformer auszuführen und in einem Schritt das resultierende Manifest auf einen Kubernetes-Cluster anzuwenden:

    kubectl apply --kustomize .
    

    Wenn Sie die Ausgabe später anwenden möchten, können Sie die Ausgabe des Befehls kustomize build an eine Datei weiterleiten.

gke-deploy verwenden

gke-deploy ist ein Befehlszeilentool, das Sie mit Google Kubernetes Engine (GKE) verwenden können. gke-deploy umschließt das kubectl-Befehlszeilentool und kann die Ressourcen ändern, die Sie gemäß den von Google empfohlenen Praktiken erstellen.

Wenn Sie die gke-deploy-Unterbefehle prepare oder run verwenden, löst gke-deploy die Image-Tags in Digests auf und speichert die erweiterten Manifeste mit den Image-Digests standardmäßig in der Datei output/expanded/aggregated-resources.yaml.

Sie können gke-deploy run verwenden, um das Image-Tag für einen Digest zu ersetzen und das erweiterte Manifest auf Ihren GKE-Cluster anzuwenden. Dieser Befehl ist zwar praktisch, hat aber auch einen Nachteil: Das Image-Tag wird bei der Bereitstellung ersetzt. Das mit dem Tag verknüpfte Image kann sich zwischen dem Zeitpunkt, an dem Sie sich für ein Deployment entschieden haben, und dem eigentlichen Deployment-Zeitpunkt geändert haben, wodurch ein unerwartetes Image bereitgestellt wird. Bei Produktions-Deployments empfehlen wir separate Schritte zum Generieren und Anwenden von Manifesten.

So ersetzen Sie ein Image-Tag in einem Kubernetes-Deployment-Manifest durch das Image-Digest:

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/gke-deploy
    cd ~/container-image-digests-tutorial/gke-deploy
    
  2. Installieren Sie gke-deploy:

    go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
    
  3. Erstellen Sie mit dem Tag 1.10 ein Kubernetes-Deployment-Manifest, das auf das Image gcr.io/google-containers/echoserver verweist:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echoserver
            image: gcr.io/google-containers/echoserver:1.10
            ports:
            - containerPort: 8080
    EOF
    
  4. Generieren Sie auf Basis des Manifests deployment.yaml ein erweitertes Manifest:

    gke-deploy prepare \
        --filename deployment.yaml \
        --image gcr.io/google-containers/echoserver:1.10 \
        --version 1.10
    
  5. Rufen Sie das erweiterte Manifest auf:

    cat output/expanded/aggregated-resources.yaml
    

    Die Ausgabe sieht so aus:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/managed-by: gcp-cloud-build-deploy
        app.kubernetes.io/version: "1.10"
      name: echo-deployment
      namespace: default
    spec:
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
            app.kubernetes.io/managed-by: gcp-cloud-build-deploy
            app.kubernetes.io/version: "1.10"
        spec:
          containers:
          - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
            name: echoserver
            ports:
            - containerPort: 8080
    

    Im erweiterten Manifest wird das Image-Tag durch den Digest ersetzt.

    Das Argument --version, das Sie mit dem Befehl gke-deploy verwendet haben, legt den Wert des empfohlenen app.kubernetes.io/version-Labels im Deployment und die Metadaten der Pod-Vorlage der erweiterten Manifestdatei fest.

    Informationen zur Verwendung von gke-deploy mit Cloud Build finden Sie in der Cloud Build-Dokumentation für gke-deploy.

ko verwenden

ko ist ein Befehlszeilentool und eine Bibliothek zum Erstellen von Go-Container-Images und für das entsprechende Deployment in Kubernetes-Clustern. ko erstellt Images ohne den Docker-Daemon, damit Sie es in Umgebungen verwenden können, in denen Sie Docker nicht installieren können.

Mit dem ko-Unterbefehl build werden Images erstellt und in einer Container-Image-Registry veröffentlicht oder in den lokalen Docker-Daemon geladen.

Der ko-Unterbefehl resolve führt Folgendes aus:

  • Ermittelt die Images, die erstellt werden sollen. Dazu werden in den image-Feldern der Kubernetes-Manifeste, die Sie mit dem Argument --filename angeben, Platzhalter gesucht.
  • Erstellt und veröffentlicht Images.
  • Ersetzt die Platzhalterwerte des Typs image durch die Namen und Digests der erstellten Images.
  • Gibt die erweiterten Manifeste aus.

Die ko-Unterbefehle apply, create und run führen dieselben Schritte wieresolve und anschließend kubectl apply, create oderrun mit den erweiterten Manifesten aus.

So erstellen Sie ein Image aus dem Go-Quellcode und fügen den Digest des Images einem Kubernetes-Deployment-Manifest hinzu:

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und rufen Sie es auf, um die in diesem Bereich erstellten Dateien zu speichern:

    mkdir -p ~/container-image-digests-tutorial/ko
    cd ~/container-image-digests-tutorial/ko
    
  2. Laden Sie ko herunter und fügen Sie es Ihrem PATH hinzu:

    mkdir -p ${HOME}/bin
    export PATH=${HOME}/bin:${PATH}
    KO_VERSION=$(curl -sL https://api.github.com/repos/ko-build/ko/releases/latest | jq -r .tag_name | cut -c2-)
    curl -L "https://github.com/ko-build/ko/releases/download/v${KO_VERSION}/ko_${KO_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar -zxC ${HOME}/bin ko
    
  3. Erstellen Sie eine Go-Anwendung mit dem Modulnamen example.com/hello-world in einem neuen Verzeichnis namens app:

    mkdir -p app/cmd/ko-example
    
    cd app
    
    go mod init example.com/hello-world
    
    cat << EOF > cmd/ko-example/main.go
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world")
    }
    EOF
    
  4. Legen Sie das Image-Repository fest, mit dem ko Images veröffentlicht:

    export KO_DOCKER_REPO=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY
    

    In diesem Beispiel wird Artifact Registry verwendet. Sie können ko aber auch mit einer anderen Container-Image-Registry verwenden.

  5. Führen Sie einen der folgenden Schritte aus, um ein Image für Ihre Anwendung zu erstellen und zu veröffentlichen:

    • Erstellen und veröffentlichen Sie ein Image für Ihre Anwendung. Geben Sie dazu den Pfad zu Ihrem Go-Hauptpaket an:

      ko build --base-import-paths ./cmd/ko-example
      

      Das optionale Argument --base-import-paths bedeutet, dass ko den Kurznamen des Hauptpaketverzeichnisses als Image-Namen verwendet.

      ko gibt den Image-Namen und den Digest in stdout im folgenden Format aus:

      LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
      

      In dieser Ausgabe ist DIGEST der Image-Digest-Wert.

    • Verwenden Sie ko, um einen Manifest-Platzhalter durch den Namen und Digest des Images zu ersetzen, das erstellt und veröffentlicht wird:

      1. Erstellen Sie ein Kubernetes-Pod-Manifest. Im Manifest wird der Platzhalter ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE als Wert für das Feld image verwendet:

        cat << EOF > ko-pod.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: ko://example.com/hello-world/cmd/ko-example
        EOF
        
      2. Erstellen und veröffentlichen Sie ein Image für Ihre Anwendung und ersetzen Sie den Manifestplatzhalter durch den Image-Namen und den Digest:

        ko resolve --base-import-paths --filename ko-pod.yaml
        

        ko gibt das Manifest mit dem Image-Namen und dem Digest an stdout aus:

        apiVersion: v1
        kind: Pod
        metadata:
          name: ko-example
        spec:
          containers:
          - name: hello-world
            image: LOCATION-docker.pkg.dev/PROJECT_ID/ko-example@sha256:DIGEST
        

        In dieser Ausgabe ist DIGEST der Image-Digest-Wert.

Bereinigen

Am einfachsten können Sie weitere Kosten vermeiden, wenn Sie das Google Cloud-Projekt löschen, das Sie für die Anleitung erstellt haben. Alternativ haben Sie die Möglichkeit, die einzelnen Ressourcen zu löschen.

Projekt löschen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Ressourcen löschen

Wenn Sie das in dieser Anleitung verwendete Google Cloud-Projekt beibehalten möchten, löschen Sie die einzelnen Ressourcen:

  1. Löschen Sie in Cloud Shell die Dateien, die Sie in dieser Anleitung erstellt haben:

    cd
    rm -rf ~/container-image-digests-tutorial
    
  2. Löschen Sie das Container-Image-Repository in Artifact Registry:

    gcloud artifacts repositories delete REPOSITORY \
        --location=LOCATION --async --quiet
    

Nächste Schritte