Anleitung für das gcloud-Befehlszeilentool in einem Cloud Run-Dienst


In dieser Anleitung erstellen Sie ein Inventar von Cloud Run-Diensten mithilfe der Google Cloud CLI in einem Cloud Run-Dienst. Sie können die in dieser Anleitung erworbenen Kenntnisse auf vorhandene Cloud Operations-Skripts anwenden oder ein Proof of Concept erstellen, bevor Sie mit Clientbibliotheken einen stabileren Dienst erstellen.

Sie können die gcloud CLI wie jedes andere Shell-Skript beispielsweise innerhalb eines Webdienstes verwenden, wie in der Shell-Kurzanleitung beschrieben. In Cloud Run funktionieren beide Tools mit Google Cloud-Diensten, indem sie automatisch mit der Cloud Run-Dienstidentität authentifiziert werden. Alle Berechtigungen, die der Dienstidentität gegeben werden, stehen der gcloud CLI zur Verfügung.

Die gcloud CLI ist dazu geeignet, in so weitreichender Weise Informationen in Google Cloud zu erfassen und Ressourcen zu verwalten, dass die Herausforderung seiner Nutzung in einem Webdienst das Risiko minimiert, dass ein Aufrufer diese Funktionen missbraucht. Ohne Sicherheitsfunktionen könnten Sie Risiken für andere Dienste oder Ressourcen auslösen, die im selben Projekt ausgeführt werden, indem Sie versehentliche oder absichtliche schädliche Aktivitäten zulassen. Folgende Beispiele für diese Risiken gehören dazu:

  • Erkennung von IP-Adressen privater virtueller Maschinen ermöglichen
  • Zugriff auf private Daten aus einer Datenbank im selben Projekt ermöglichen
  • Löschen anderer ausgeführter Dienste ermöglichen

In einer Reihe von Schritten dieser Anleitung wird beschrieben, wie Sie Kontrollmaßnahmen einsetzen, um Risiken zu minimieren, z. B. die Angabe, dass der Befehl gcloud im Code ausgeführt werden soll statt ihn als Nutzereingabe offen zu lassen.

Das Skript mit dem Befehlszeilentool in einem Cloud Run-Dienst ähnelt der lokalen Verwendung der Befehlszeile. Der Hauptunterschied liegt in den zusätzlichen Einschränkungen, die Sie bei der primären Skriptlogik einfügen sollten.

Ziele

  • Mit einem Dockerfile einen benutzerdefinierten Container schreiben und erstellen
  • Einen Cloud Run-Dienst schreiben, erstellen und bereitstellen
  • gcloud CLI sicher in einem Webdienst verwenden
  • Einen Bericht zu Cloud Run-Diensten erstellen und in Cloud Storage speichern

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.

Hinweise

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

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

    Go to project selector

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

  6. Enable the Artifact Registry, Cloud Build, Cloud Run, and Cloud Storage APIs.

    Enable the APIs

  7. Installieren und initialisieren Sie die gcloud CLI.

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Ausführen der Anleitung benötigen:

Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

gcloud-Standardeinstellungen einrichten

So konfigurieren Sie gcloud mit Standardeinstellungen für den Cloud Run-Dienst:

  1. Legen Sie ein Standardprojekt fest:

    gcloud config set project PROJECT_ID

    Ersetzen Sie PROJECT_ID durch den Namen des Projekts, das Sie für diese Anleitung erstellt haben.

  2. Konfigurieren Sie gcloud für die von Ihnen ausgewählte Region:

    gcloud config set run/region REGION

    Ersetzen Sie REGION durch die unterstützte Cloud Run-Region Ihrer Wahl.

Cloud Run-Standorte

Cloud Run ist regional. Die Infrastruktur, in der die Cloud Run-Dienste ausgeführt werden, befindet sich demnach in einer bestimmten Region. Aufgrund der Verwaltung durch Google sind die Anwendungen in allen Zonen innerhalb dieser Region redundant verfügbar.

Bei der Auswahl der Region, in der Ihre Cloud Run-Dienste ausgeführt werden, ist vorrangig, dass die Anforderungen hinsichtlich Latenz, Verfügbarkeit oder Langlebigkeit erfüllt werden. Sie können im Allgemeinen die Region auswählen, die Ihren Nutzern am nächsten liegt, aber Sie sollten den Standort der anderen Google Cloud-Produkte berücksichtigen, die von Ihrem Cloud Run-Dienst verwendet werden. Die gemeinsame Nutzung von Google Cloud-Produkten an mehreren Standorten kann sich auf die Latenz und die Kosten des Dienstes auswirken.

Cloud Run ist in diesen Regionen verfügbar:

Unterliegt Preisstufe 1

Unterliegt Preisstufe 2

  • africa-south1 (Johannesburg)
  • asia-east2 (Hongkong)
  • asia-northeast3 (Seoul, Südkorea)
  • asia-southeast1 (Singapur)
  • asia-southeast2 (Jakarta)
  • asia-south1 (Mumbai, Indien)
  • asia-south2 (Delhi, Indien)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Warschau, Polen)
  • europe-west10 (Berlin)Blattsymbol Niedriger CO2-Ausstoß
  • europe-west12 (Turin)
  • europe-west2 (London, Vereinigtes Königreich) Blattsymbol Niedriger CO2-Ausstoß
  • europe-west3 (Frankfurt, Deutschland) Blattsymbol Niedriger CO2-Ausstoß
  • europe-west6 (Zürich, Schweiz) Blattsymbol Niedriger CO2-Ausstoß
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montreal) Blattsymbol Niedriger CO2-Ausstoß
  • northamerica-northeast2 (Toronto) Blattsymbol Niedriger CO2-Ausstoß
  • southamerica-east1 (Sao Paulo, Brasilien) Blattsymbol Niedriger CO2-Ausstoß
  • southamerica-west1 (Santiago, Chile) Blattsymbol Niedriger CO2-Ausstoß
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Wenn Sie bereits einen Cloud Run-Dienst erstellt haben, können Sie dessen Region im Cloud Run-Dashboard der Google Cloud Console aufrufen.

Codebeispiel abrufen

So rufen Sie das gewünschte Codebeispiel ab:

  1. Klonen Sie das Repository der Beispiel-App auf Ihren lokalen Computer:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples.git

    Sie können auch das Beispiel als ZIP-Datei herunterladen und extrahieren.

  2. Wechseln Sie in das Verzeichnis, das den Cloud Run-Beispielcode enthält:

    cd cloud-run-samples/gcloud-report/

Code ansehen

Dieser Abschnitt enthält Informationen zu dem abgerufenen Codebeispiel.

Bericht erstellen und in Cloud Storage hochladen

Dieses Shell-Skript erstellt einen Bericht über Cloud Run-Dienste im aktuellen Projekt und in der aktuellen Region und lädt das Ergebnis in Cloud Storage hoch. Es listet Dienste auf, deren Name das angegebene String-search-Argument enthält.

Das Skript verwendet den Befehl gcloud run services list, erweiterte gcloud-Formatoptionen und den Kopiermodus per gcloud-Stream-Übertragung.

set -eo pipefail

# Check for required environment variables.
requireEnv() {
  test "${!1}" || (echo "gcloud-report: '$1' not found" >&2 && exit 1)
}
requireEnv GCLOUD_REPORT_BUCKET

# Prepare formatting: Default search term to include all services.
search=${1:-'.'}
limits='spec.template.spec.containers.resources.limits.flatten("", "", " ")'
format='table[box, title="Cloud Run Services"](name,status.url,metadata.annotations.[serving.knative.dev/creator],'${limits}')'

# Create a specific object name that will not be overridden in the future.
obj="gs://${GCLOUD_REPORT_BUCKET}/report-${search}-$(date +%s).txt"

# Write a report containing the service name, service URL, service account or user that
# deployed it, and any explicitly configured service "limits" such as CPU or Memory.
gcloud run services list \
  --format "${format}" \
  --filter "metadata.name~${search}" | gsutil -q cp -J - "${obj}"

# /dev/stderr is sent to Cloud Logging.
echo "gcloud-report: wrote to ${obj}" >&2
echo "Wrote report to ${obj}"

Dieses Skript kann sicher als Dienst ausgeführt werden, da wiederholte Aufrufe den Bericht ohne weitere kostspielige Abwanderung aktualisieren. Andere Skripts, die die gcloud CLI verwenden, können teurer sein, wenn sie wiederholt aufgerufen werden, wie beispielsweise das Erstellen neuer Cloud-Ressourcen oder das Ausführen teurer Aufgaben. Idempotente Skripts, die dasselbe Ergebnis bei wiederholten Aufrufen erhalten, können sicherer als Dienst ausgeführt werden.

Script für HTTP-Anfrage aufrufen

Dieser Go-Code richtet einen Webdienst ein, der ein Shell-Skript zum Erstellen eines Berichts ausführt. Da die Suchanfrage Nutzereingaben ist, überprüft der Code sie, ob sie nur Buchstaben, Zahlen oder Bindestriche enthält, um zu verhindern, dass schädliche Befehle eingegeben werden. Diese Reihe von Zeichen ist schmal genug, um Angriffs-Injection-Angriffe zu verhindern.

Der Webdienst übergibt den Suchparameter als Argument an das Shell-Skript.


// Service gcloud-report is a Cloud Run shell-script-as-a-service.
package main

import (
	"log"
	"net/http"
	"os"
	"os/exec"
	"regexp"
)

func main() {
	http.HandleFunc("/", scriptHandler)

	// Determine port for HTTP service.
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("defaulting to port %s", port)
	}

	// Start HTTP server.
	log.Printf("listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

func scriptHandler(w http.ResponseWriter, r *http.Request) {
	search := r.URL.Query().Get("search")
	re := regexp.MustCompile(`^[a-z]+[a-z0-9\-]*$`)
	if !re.MatchString(search) {
		log.Printf("invalid search criteria %q, using default", search)
		search = "."
	}

	cmd := exec.CommandContext(r.Context(), "/bin/bash", "script.sh", search)
	cmd.Stderr = os.Stderr
	out, err := cmd.Output()
	if err != nil {
		log.Printf("Command.Output: %v", err)
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	w.Write(out)
}

Die Datei go.mod deklariert die Anwendungsabhängigkeiten in einem Go-Modul:

module github.com/GoogleCloudPlatform/cloud-run-samples/gcloud-report

go 1.19

Containerumgebung definieren

Mit dem Dockerfile wird definiert, wie die Umgebung für den Dienst zusammengesetzt wird. Sie ähnelt dem Dockerfile aus dem helloworld-shell quickstart, mit dem Unterschied, dass das endgültige Container-Image auf dem Google Cloud CLI-Image gcloud basiert. Dadurch kann Ihr Dienst gcloud ohne benutzerdefinierte Installations- und Konfigurationsschritte für die Google Cloud CLI verwenden.


# Use the official golang image to create a binary.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.20-buster as builder

# Create and change to the app directory.
WORKDIR /app

# Retrieve application dependencies.
# This allows the container build to reuse cached dependencies.
# Expecting to copy go.mod and if present go.sum.
COPY go.* ./
RUN go mod download

# Copy local code to the container image.
COPY invoke.go ./

# Build the binary.
RUN go build -mod=readonly -v -o server

# Use a gcloud image based on debian:buster-slim for a lean production container.
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM gcr.io/google.com/cloudsdktool/cloud-sdk:slim

WORKDIR /app

# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/server /app/server
COPY *.sh /app/
RUN chmod +x /app/*.sh

# Run the web service on container startup.
CMD ["/app/server"]

Artifact Registry-Standard-Repository erstellen

Erstellen Sie ein Artifact Registry-Standard-Repository zum Speichern des Docker-Container-Images:

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

Ersetzen Sie:

  • REPOSITORY durch einen eindeutigen Namen für das Repository.
  • REGION durch die Google Cloud-Region der Artifact Registry.

Cloud Storage-Bucket einrichten

Erstellen Sie einen Cloud Storage-Bucket zum Hochladen von Berichten:

gcloud storage buckets create gs://REPORT_ARCHIVE_BUCKET

Ersetzen Sie REPORT_ARCHIVE_BUCKET durch einen global eindeutigen Bucket-Namen.

Dienstidentität einrichten

Sie erstellen eine Dienstidentität und passen die spezifischen IAM-Berechtigungen an, die für die Arbeit erforderlich sind, um den Zugriff des Dienstes auf anderweitige Infrastruktur zu beschränken.

In diesem Fall sind die Berechtigungen zum Lesen von Cloud Run-Diensten und zum Lesen von und zum Schreiben in den Cloud Storage-Bucket erforderlich.

  1. Erstellen Sie ein Dienstkonto:

    gcloud iam service-accounts create gcloud-report-identity

  2. Gewähren Sie dem Dienstkonto die Berechtigung zum Lesen von Cloud Run-Diensten:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=serviceAccount:gcloud-report-identity@PROJECT_ID.iam.gserviceaccount.com \
      --role roles/run.viewer
  3. Gewähren Sie dem Dienstkonto die Berechtigungen zum Lesen von und Schreiben in den Cloud Storage-Bucket:

    gcloud storage buckets add-iam-policy-binding gs://REPORT_ARCHIVE_BUCKET \
      --member=serviceAccount:gcloud-report-identity@PROJECT_ID.iam.gserviceaccount.com \
      --role=roles/storage.objectUser

Der eingeschränkte Zugriff dieser benutzerdefinierten Dienstidentität verhindert, dass der Dienst auf andere Google Cloud-Ressourcen zugreift.

Dienst versenden

Der Versand von Code besteht aus drei Schritten:

  • Ein Container-Image mit Cloud Build erstellen
  • Container-Image per Push an Artifact Registry hochladen
  • Das Container-Image in Cloud Run bereitstellen

So versenden Sie den Code:

  1. Erstellen Sie einen Container und veröffentlichen Sie ihn in Artifact Registry.

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/gcloud-report

    Ersetzen Sie:

    • PROJECT_ID durch Ihre Google Cloud-Projekt-ID
    • REPOSITORY durch den Namen des Artifact Registry-Repositorys.
    • REGION durch die Google Cloud-Region der Artifact Registry.

    gcloud-report ist der Name Ihres Dienstes.

    Bei Erfolg wird in einer SUCCESS-Meldung die ID, die Erstellungszeit und der Image-Name angezeigt. Das Image wird in Artifact Registry gespeichert und kann bei Bedarf wiederverwendet werden.

  2. Stellen Sie die Anwendung mit dem folgenden Befehl bereit:

    gcloud run deploy gcloud-report \
       --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/gcloud-report \
       --update-env-vars GCLOUD_REPORT_BUCKET=REPORT_ARCHIVE_BUCKET \
       --service-account gcloud-report-identity \
       --no-allow-unauthenticated

    Ersetzen Sie:

    • PROJECT_ID durch Ihre Google Cloud-Projekt-ID.
    • REPOSITORY durch den Namen des Artifact Registry-Repositorys.
    • REGION durch die Google Cloud-Region des Dienstes.

    gcloud-report ist Teil des Containernamens und des Dienstes. Das Container-Image wird für den Dienst und die Region (Cloud Run) bereitgestellt, die Sie zuvor unter gcloud einrichten konfiguriert haben.

    Das Flag --no-allow-unauthenticated beschränkt den nicht authentifizierten Zugriff auf den Dienst. Wenn Sie den Dienst privat nutzen, können Sie sich darauf verlassen, dass mit der in Cloud Run integrierten Authentifizierung nicht autorisierte Anfragen blockiert werden. Weitere Informationen zur Authentifizierung auf Grundlage des Identity and Access Management (IAM) finden Sie unter Zugriff mit IAM verwalten.

    Warten Sie, bis die Bereitstellung abgeschlossen ist. Dies kann etwa eine halbe Minute dauern. Bei Erfolg wird in der Befehlszeile die Dienst-URL angezeigt.

  3. Wenn Sie eine Codeaktualisierung für den Dienst bereitstellen möchten, wiederholen Sie die vorherigen Schritte. Bei jeder Bereitstellung für einen Dienst wird eine neue Version erstellt und der Traffic wird automatisch verarbeitet, sobald der Dienst bereit ist.

Unter Zugriff mit IAM verwalten erfahren Sie, wie Sie Google Cloud-Nutzern Zugriff zum Aufrufen dieses Dienstes gewähren. Projektbearbeiter und -inhaber haben automatisch Zugriff.

Bericht generieren

So erstellen Sie einen Bericht der Cloud Run-Dienste:

  1. Verwenden Sie curl, um eine authentifizierte Anfrage zu senden:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" SERVICE_URL

    Ersetzen Sie SERVICE_URL durch die von Cloud Run bereitgestellte URL, nachdem die Bereitstellung abgeschlossen ist.

    Wenn Sie ein neues Projekt erstellt haben und dieser Anleitung gefolgt sind, sieht die Ausgabe ungefähr so aus:

    Wrote report to gs://REPORT_ARCHIVE_BUCKET/report-.-DATE.txt

    Der . im Dateinamen ist das Standardsuchargument, wie im Quellcode erwähnt.

    Wenn Sie die Suchfunktion verwenden möchten, fügen Sie der Anfrage ein search-Argument hinzu:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" SERVICE_URL?search=gcloud

    Diese Abfrage gibt eine Ausgabe ähnlich wie hier zurück:

    Wrote report to gs://REPORT_ARCHIVE_BUCKET/report-gcloud-DATE.txt
  2. Rufen Sie die Datei lokal mit der gcloud CLI ab:

    gcloud storage cp gs://REPORT_FILE_NAME .

    Der . im Befehl steht für das aktuelle Arbeitsverzeichnis.

    Ersetzen Sie REPORT_FILE_NAME durch die Ausgabe des Cloud Storage-Objektnamens im vorherigen Schritt.

Öffnen Sie die Datei, um sich den Bericht anzusehen. Das sollte so aussehen:

Screenshot der Liste der Cloud Run-Dienste im Projekt mit Spalten für vier Dienstattribute
Die vier Spalten werden aus der Dienstbeschreibung abgerufen. Dazu gehören Name des Dienstes, URL bei der ersten Bereitstellung, der ursprüngliche Ersteller des Dienstes und der Dienst Limits der maximalen CPU- und Arbeitsspeicherkapazität.

Stabilität für die Zukunft verbessern

Wenn Sie diesen Dienst weiter entwickeln möchten, sollten Sie darüber nachdenken, ihn in einer stabileren Programmiersprache neu zu schreiben und dabei die Cloud Run Admin API und die Cloud Storage-Clientbibliothek zu verwenden.

Sie können die ausgeführten API-Aufrufe (und einige Details zur Authentifizierung) prüfen, indem Sie --log-http zu den gcloud CLI-Befehlen hinzufügen.

Vorgang automatisieren

Nachdem der Bericht der Cloud Run-Dienste jetzt durch eine HTTP-Anfrage ausgelöst werden kann, verwenden Sie die Automatisierung, um bei Bedarf Berichte zu erstellen:

Bereinigen

Wenn Sie ein neues Projekt für diese Anleitung erstellt haben, löschen Sie das Projekt. Wenn Sie ein vorhandenes Projekt verwendet haben und es beibehalten möchten, ohne die Änderungen in dieser Anleitung hinzuzufügen, löschen Sie die für die Anleitung erstellten Ressourcen.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten, wenn Sie das zum Ausführen der Anleitung erstellte Projekt löschen.

So löschen Sie das Projekt:

  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.

Anleitungsressourcen löschen

  1. Löschen Sie den Cloud Run-Dienst, den Sie in dieser Anleitung bereitgestellt haben:

    gcloud run services delete SERVICE-NAME

    Dabei ist SERVICE-NAME der von Ihnen ausgewählte Dienstname.

    Sie können Cloud Run-Dienste auch über die Google Cloud Console löschen.

  2. Entfernen Sie die Konfiguration der Standardregion gcloud, die Sie während der Einrichtung für die Anleitung hinzugefügt haben:

     gcloud config unset run/region
    
  3. Entfernen Sie die Projektkonfiguration:

     gcloud config unset project
    
  4. Löschen Sie sonstige Google Cloud-Ressourcen, die in dieser Anleitung erstellt wurden:

Nächste Schritte