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.
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
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry API.
-
In the Google Cloud console, activate Cloud Shell.
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].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
.
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:
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
Klonen Sie das Git-Repository für Skaffold:
git clone https://github.com/GoogleContainerTools/skaffold.git
Rufen Sie das Verzeichnis des Beispiels
getting-started
auf:cd skaffold/examples/getting-started
Sehen Sie sich das Git-Tag an, das Ihrer Version von Skaffold entspricht:
git checkout $(skaffold version)
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 Namenk8s-pod.yaml
zu lesen.Eine Übersicht über alle verfügbaren Optionen finden Sie in der Referenzdokumentation zu
skaffold.yaml
.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 Feldimage
entspricht dem Wert des Feldsimage
in der Dateiskaffold.yaml
. Skaffold ersetzt diesen Platzhalterwert durch den vollständigen Image-Namen und den Digest in der gerenderten Ausgabe.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 auffalse
gesetzt. Setzen Sie diese Flags in nicht interaktiven Umgebungen wie Build-Pipelines auffalse
, 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.- Das Flag
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 Befehlskaffold 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.
- Das Flag
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
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
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
Erstellen Sie mit dem Tag
1.10
ein Kubernetes-Deployment-Manifest, das auf das Imagegcr.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
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.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
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
Erstellen Sie einen lokalen Kubernetes-Cluster mit kind:
kind create cluster
„kind“ ist ein Befehlszeilentool zum Ausführen lokaler Kubernetes-Cluster mit Docker.
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 -
Erstellen Sie einen Kubernetes-Namespace namens
digester-demo
im Typcluster:kubectl create namespace digester-demo
Fügen Sie dem Namespace
digester-demo
das Labeldigest-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.
Erstellen Sie mit dem Tag
1.10
ein Kubernetes-Deployment-Manifest, das auf das Imagegcr.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
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
weistkubectl
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.
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.
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
Erstellen Sie ein kpt-Paket im aktuellen Verzeichnis:
kpt pkg init --description "Container image digest tutorial"
Erstellen Sie mit dem Tag
1.10
ein Kubernetes-Deployment-Manifest, das auf das Imagegcr.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
Verwenden Sie kpt, um einen Setter namens
echoimage
für das Manifestfeld zu erstellen, wobei der vorhandene Wertgcr.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"
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
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)')
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.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:
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
kustomization.yaml
-Datei erstellen:kustomize init
Erstellen Sie ein Kubernetes-Manifest mit einer Pod-Spezifikation, die auf das Image
gcr.io/google-containers/echoserver
mithilfe des Tags1.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
Fügen Sie das Manifest als Ressource zur Datei
kustomization.yaml
hinzu:kustomize edit add resource pod.yaml
Aktualisieren Sie den Image-Digest mit einem Image-Transformer:
kustomize edit set image \ gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
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
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
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:
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
Installieren Sie
gke-deploy
:go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
Erstellen Sie mit dem Tag
1.10
ein Kubernetes-Deployment-Manifest, das auf das Imagegcr.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
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
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 Befehlgke-deploy
verwendet haben, legt den Wert des empfohlenenapp.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ürgke-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:
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
Laden Sie
ko
herunter und fügen Sie es IhremPATH
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
Erstellen Sie eine Go-Anwendung mit dem Modulnamen
example.com/hello-world
in einem neuen Verzeichnis namensapp
: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
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.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, dassko
den Kurznamen des Hauptpaketverzeichnisses als Image-Namen verwendet.ko
gibt den Image-Namen und den Digest instdout
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:Erstellen Sie ein Kubernetes-Pod-Manifest. Im Manifest wird der Platzhalter
ko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE
als Wert für das Feldimage
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
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 anstdout
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
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- 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:
Löschen Sie in Cloud Shell die Dateien, die Sie in dieser Anleitung erstellt haben:
cd rm -rf ~/container-image-digests-tutorial
Löschen Sie das Container-Image-Repository in Artifact Registry:
gcloud artifacts repositories delete REPOSITORY \ --location=LOCATION --async --quiet
Nächste Schritte
- Weitere Informationen zu Container-Image-Digests
- Weitere Informationen zur digester clientseitigen KRM-Funktion und zum mutierenden Webhook in Kubernetes
- Continuous Delivery gemäß GitOps mit Cloud Build