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- 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 wieSkaffold, kpt, digester, kustomize, gke-deploy
, ko
und
Bazel 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 mit HBase Images erstellen und diese mit kpt oder Kustomize 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:
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.
Skaffold kann zum Hinzufügen von Digests zu Image-Referenzen verwendet werden. 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 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 zum Erstellen von Anwendungen bereits Bazel verwenden, empfehlen wir Ihnen, den
rules_docker
-Regelsatz zum Erstellen von Images und den Regelsatzrules_k8s
zum Ergänzen von Image-Digests in Ihren Kubernetes-Manifesten hinzufügen.
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 eine gesamte Organisation.
Ziele
- 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.
- Mit kpt-Settern können Sie ein Image-Tag in einem Kubernetes-Manifest durch einen Image-Digest ersetzen.
- Verwenden Sie die clientseitige Digest-Funktion und den mutierenden Zulassungs-Webhook, um Digests zu Images in Kubernetes-Pods und Pod-Vorlagen hinzuzufügen.
- 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. - Mit Bazel können Sie ein Image erstellen und per Push übertragen und den Image-Namen und das Digest in ein Kubernetes-Manifest einfü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.
Hinweis
-
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 Container Registry API.
-
In the Google Cloud console, activate Cloud Shell.
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 Container 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/v2beta26 kind: Config build: artifacts: - image: skaffold-example deploy: kubectl: manifests: - k8s-*
Der Abschnitt
build.artifacts
enthält den Image-Kontext, in diesem Fall einen Platzhalternamen. Skaffold sucht in den Eingabemanifestdateien nach diesem Platzhalter. In diesem Abschnitt legen Sie auch die Kontextverzeichnisse fest, die von Skaffold zum Erstellen von Images verwendet werden. Standardmäßig verwendet Skaffold das aktuelle Verzeichnis als Build-Kontext.Im Abschnitt
deploy
wird Skaffold angewiesen, Eingabemanifestdateien im aktuellen Verzeichnis zu lesen, deren Namen mit dem Musterk8s-*
übereinstimmen, und gerenderte Manifeste mitkubectl apply
bereitzustellen.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 in die Container Registry:
skaffold build \ --default-repo=gcr.io/$(gcloud config get-value core/project) \ --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 Google 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 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: gcr.io/YOUR_PROJECT_ID/skaffold-example:TAG@sha256:DIGEST name: getting-started
In dieser Ausgabe sehen Sie die folgenden Werte:
YOUR_PROJECT_ID
: Ihre Cloud-Projekt-IDTAG
: das Tag, das dem Image vom Skaffold zugewiesen wurde.DIGEST
: der Wert des Image-Digests
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
Laden Sie kpt herunter:
mkdir -p ${HOME}/bin curl -L https://github.com/GoogleContainerTools/kpt/releases/download/v1.0.0-beta.1/kpt_linux_amd64 --output ${HOME}/bin/kpt chmod +x ${HOME}/bin/kpt export PATH=${HOME}/bin:${PATH}
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:v0.1@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:v0.2@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
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:
DIGESTER_VERSION=v0.1.7 mkdir -p ${HOME}/bin 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 export PATH=${HOME}/bin:${PATH}
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
Laden Sie Art herunter:
KIND_VERSION=v0.11.1 mkdir -p ${HOME}/bin curl -L "https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-linux-amd64" --output ${HOME}/bin/kind chmod +x ${HOME}/bin/kind export PATH=${HOME}/bin:${PATH}
Art ist ein Befehlszeilentool zum Ausführen lokaler Kubernetes-Cluster mit Docker.
Erstellen Sie einen lokalen Kubernetes-Cluster:
kind create cluster
Laden Sie das Digest-Webhook-kpt-Paket herunter und speichern Sie es in einem Verzeichnis mit dem Namen
manifests
:DIGESTER_VERSION=v0.1.7 kpt pkg get https://github.com/google/k8s-digester.git/manifests@${DIGESTER_VERSION} manifests
Stellen Sie den Digest-Webhook bereit:
kpt live init manifests kpt live apply manifests --reconcile-timeout=3m --output=table
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
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
kubectl apply
mit dem Flag--kustomize
verwenden, um 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. Kustomize hat weitere Funktionen, die in diesem Dokument nicht behandelt werden. Weitere Informationen finden Sie in der kustomize-Dokumentation. Kustomize ist auch als Community Builder-Image von Cloud Build verfügbar.
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.Das
gke-deploy
-Tool ist auch als vordefiniertes Image für Cloud Build verfügbar. Informationen zur Verwendung vongke-deploy
mit Cloud Build finden Sie in der Cloud Build-Dokumentation fürgke-deploy
.
ko
verwenden
ko
ist ein Befehlszeilentool 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 publish
werden Images erstellt und in einer Container 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 curl -L https://github.com/google/ko/releases/download/v0.9.3/ko_0.9.3_$(uname -s)_$(uname -m).tar.gz | tar -zxC ${HOME}/bin ko export PATH=${HOME}/bin:${PATH}
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=gcr.io/$(gcloud config get-value core/project)
In diesem Beispiel wird Container Registry verwendet. Sie können aber auch eine andere 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 publish --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:gcr.io/YOUR_PROJECT_ID/ko-example@sha256:DIGEST_VALUE
In dieser Ausgabe gilt:
YOUR_PROJECT_ID
: Ihre Cloud-Projekt-IDDIGEST_VALUE
: Wert des Image-Digests
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
Verwenden Sie
ko resolve
, um ein Image für Ihre Anwendung zu erstellen und zu veröffentlichen. Ersetzen Sie dann 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: gcr.io/YOUR_PROJECT_ID/ko-example@sha256:DIGEST
In dieser Ausgabe gilt:
YOUR_PROJECT_ID
: Ihre Cloud-Projekt-IDDIGEST
: der Wert des Image-Digests
Bazel verwenden
Bazel ist ein Open-Source-Build-Tool in mehreren Sprachen, das auf dem internen Blaze-Build-System von Google basiert.
rules_docker
ist ein Bazel-Regelsatz zum Erstellen und Übertragen von Container-Images. Die Regeln erstellen reproduzierbare Images, ohne den Docker-Daemon zu verwenden. Das Caching von Bazel kann das Erstellen und Übertragen von Images an Registries beschleunigen.
rules_k8s
ist ein Bazel-Regelsatz für die Arbeit mit Kubernetes-Manifesten und -Clustern.
So erstellen Sie ein Image und übertragen es mit einem Push-Vorgang, um ein Kubernetes-Manifest durch den Image-Digest zu ergänzen:
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/bazel cd ~/container-image-digests-tutorial/bazel
Git-Repository
rules_k8s
klonengit clone https://github.com/bazelbuild/rules_k8s.git
Rufen Sie das Git-Repository-Verzeichnis auf:
cd rules_k8s
Prüfen Sie ein Git-Tag:
git checkout v0.6
Ersetzen Sie in der Datei
WORKSPACE
den Namen des Basis-Image-Repositorys, das Bazel zum Hochladen von Images mit einem Repository verwendet, in dem Sie Berechtigungen zum Übertragen von Images haben:sed -i~ "s/image_chroot.*/image_chroot = \"gcr.io\/$(gcloud config get-value core\/project)\",/" WORKSPACE
In diesem Beispiel wird Container Registry verwendet. Sie können aber auch eine andere Registry verwenden.
Installieren Sie die Bazel-Version für die Verwendung mit dem Build:
sudo apt-get install -y bazel-$(cat .bazelversion)
Korrigieren Sie das Feld
apiVersion
in der beispielhaften Manifestvorlage für das Kubernetes-Deployments:sed -i~ 's/v1beta1/v1/' examples/hellohttp/deployment.yaml
Sehen Sie sich die Manifestvorlage für das Kubernetes-Deployment an:
cat examples/hellohttp/deployment.yaml
Dies ist die Datei:
apiVersion: apps/v1 kind: Deployment metadata: name: hello-http-staging spec: replicas: 1 template: metadata: labels: app: hello-http-staging spec: containers: - name: hello-http image: hello-http-image:latest imagePullPolicy: Always ports: - containerPort: 8080
Erstellen Sie das Java-Image für das Beispiel
hellohttp
, übertragen Sie es per Push an Container Registry und ersetzen Sie den Wertimage
in der Deployment-Manifestvorlage von Kubernetes durch den Namen und Digest des übertragenen Images. Leiten Sie die Ausgabestdout
weiter, um das erweiterte Manifest in einer neuen Datei mit dem Namendeployment.yaml.out
zu erfassen:bazel --output_user_root=/tmp/bazel \ run //examples/hellohttp/java:staging > deployment.yaml.out
Die Ausführung dieses Befehls dauert einige Minuten, da er die Regelsätze, Compiler und Abhängigkeiten herunterlädt.
Das Argument
--output_user_root
weist Bazel an, ein temporäres Verzeichnis außerhalb des Basisverzeichnisses für den laufwerksbasierten Cache zu verwenden. Dieses temporäre Verzeichnis ist in Cloud Shell erforderlich, damit Ihr Basisverzeichnis nicht überfüllt wird.Rufen Sie das erweiterte Manifest auf:
cat deployment.yaml.out
Die Datei sieht in etwa so aus:
apiVersion: apps/v1 kind: Deployment metadata: name: hello-http-staging spec: replicas: 1 template: metadata: labels: app: hello-http-staging spec: containers: - image: gcr.io/YOUR_PROJECT_ID/hello-http-image@sha256:b9d0a4643e9f11efe7cd300dd219ad691077ddfaccc118144cd83b7c472a8e86 imagePullPolicy: Always name: hello-http ports: - containerPort: 8080
Sehen Sie sich das von Bazel per Push übertragene Image an:
gcloud container images describe \ gcr.io/$(gcloud config get-value core/project)/hello-http-image
Bereinigen
Am einfachsten können Sie weitere Kosten vermeiden, wenn Sie das 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 Cloud-Projekt beibehalten möchten, löschen Sie die einzelnen Ressourcen:
Löschen Sie die Images in Container Registry:
for IMG in hello-http-image ko-example skaffold-example ; do \ gcloud container images list-tags \ gcr.io/$(gcloud config get-value core/project)/$IMG \ --format 'value(digest)' | xargs -I {} gcloud container images \ delete --force-delete-tags --quiet \ gcr.io/$(gcloud config get-value core/project)/$IMG@sha256:{} done
Löschen Sie die Dateien, die Sie in dieser Anleitung erstellt haben:
cd rm -rf ~/container-image-digests-tutorial
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
- Best Practices für das Erstellen von Containern
- Best Practices für den Betrieb von Containern.
- Referenzarchitekturen, Diagramme, Anleitungen und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center