Tutorial sulla riga di comando gcloud all'interno di un servizio Cloud Run


In questo tutorial, crei un inventario dei servizi Cloud Run utilizzando Google Cloud CLI all'interno di un servizio Cloud Run. Puoi applicare ciò che impari in questo tutorial ai tuoi script Cloud Operations esistenti o per creare una proof of concept prima di utilizzare le librerie client per creare un servizio più solido.

Utilizzi gcloud CLI come qualsiasi script shell all'interno di un servizio web, ad esempio, come mostrato nella guida rapida di Shell. Su Cloud Run, entrambi gli strumenti funzionano con i servizi Google Cloud eseguendo automaticamente l'autenticazione con l'identità del servizio Cloud Run. Tutte le autorizzazioni concesse all'identità di servizio sono disponibili per gcloud CLI.

La gcloud CLI è in grado di raccogliere informazioni e gestire risorse in modo così ampio su Google Cloud che la sfida di utilizzarla all'interno di un servizio web consiste nel ridurre al minimo il rischio che un chiamante utilizzi in modo improprio queste funzionalità. Senza controlli di sicurezza, potresti creare rischi per altri servizi o risorse in esecuzione nello stesso progetto consentendo attività dannose accidentali o intenzionali. Alcuni esempi di questi rischi includono:

  • Attivazione del rilevamento degli indirizzi IP delle macchine virtuali private
  • Attivare l'accesso ai dati privati da un database nello stesso progetto
  • Abilitazione dell'eliminazione di altri servizi in esecuzione

Diversi passaggi di questo tutorial mostrano come imporre controlli per ridurre al minimo i rischi, ad esempio specificando il comando gcloud da eseguire nel codice, anziché lasciarlo aperto come input utente.

L'utilizzo di script con lo strumento a riga di comando all'interno di un servizio Cloud Run è simile all'utilizzo della riga di comando in locale. La differenza principale sono le limitazioni aggiuntive che devi aggiungere alla logica dello script principale.

Obiettivi

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova gratuita.

Prima di iniziare

  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. Installa e inizializza gcloud CLI.
  8. Ruoli obbligatori

    Per ottenere le autorizzazioni necessarie per completare il tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM per il progetto:

    Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

    Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Configura i valori predefiniti di gcloud

Per configurare gcloud con i valori predefiniti per il tuo servizio Cloud Run:

  1. Imposta il progetto predefinito:

    gcloud config set project PROJECT_ID

    Sostituisci PROJECT_ID con il nome del progetto che hai creato per questo tutorial.

  2. Configura gcloud per la regione scelta:

    gcloud config set run/region REGION

    Sostituisci REGION con la regione Cloud Run supportata che preferisci.

Località Cloud Run

Cloud Run è regionale, il che significa che l'infrastruttura che esegue i tuoi servizi Cloud Run si trova in una regione specifica ed è gestita da Google per essere disponibile in modo ridondante in tutte le zone all'interno di quella regione.

Il rispetto dei requisiti di latenza, disponibilità o durabilità sono fattori primari per la selezione della regione in cui vengono eseguiti i servizi Cloud Run. In genere puoi selezionare la regione più vicina ai tuoi utenti, ma devi considerare la posizione degli altri Google Cloud prodotti utilizzati dal tuo servizio Cloud Run. L'utilizzo combinato dei prodotti Google Cloud in più località può influire sulla latenza e sui costi del servizio.

Cloud Run è disponibile nelle seguenti regioni:

Soggetto ai prezzi di Livello 1

Soggetto ai prezzi di Livello 2

  • africa-south1 (Johannesburg)
  • asia-east2 (Hong Kong)
  • asia-northeast3 (Seul, Corea del Sud)
  • asia-southeast1 (Singapore)
  • asia-southeast2 (Giacarta)
  • asia-south2 (Delhi, India)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Varsavia, Polonia)
  • europe-west10 (Berlino) icona foglia Bassi livelli di CO2
  • europe-west12 (Torino)
  • europe-west2 (Londra, Regno Unito) icona foglia Bassi livelli di CO2
  • europe-west3 (Francoforte, Germania) icona foglia Bassi livelli di CO2
  • europe-west6 (Zurigo, Svizzera) icona foglia Bassi livelli di CO2
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montreal) icona foglia Bassi livelli di CO2
  • northamerica-northeast2 (Toronto) icona foglia Bassi livelli di CO2
  • southamerica-east1 (San Paolo, Brasile) icona foglia Bassi livelli di CO2
  • southamerica-west1 (Santiago, Cile) icona foglia Bassi livelli di CO2
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Se hai già creato un servizio Cloud Run, puoi visualizzare la regione nella dashboard di Cloud Run nella consoleGoogle Cloud .

Recupero dell'esempio di codice

Per recuperare l'esempio di codice da utilizzare:

  1. Clona il repository dell'app di esempio sulla tua macchina locale:

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

    In alternativa, puoi scaricare il campione come file ZIP ed estrarlo.

  2. Passa alla directory che contiene il codice campione di Cloud Run:

    cd cloud-run-samples/gcloud-report/

Esamina il codice

Questa sezione include informazioni sul codice campione che hai recuperato.

Genera un report e caricalo su Cloud Storage

Questo script shell genera un report dei servizi Cloud Run nel progetto e nella regione correnti e carica il risultato in Cloud Storage. Elenca i servizi il cui nome contiene l'argomento search della stringa fornita.

Lo script utilizza il comando gcloud run services list, le gcloudopzioni di formato avanzate e la modalità di copia gcloudtrasferimento in streaming.

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}"

L'esecuzione di questo script come servizio è sicura perché le invocazioni ripetute aggiornano il report senza ulteriori costose modifiche. Altri script che utilizzano gcloud CLI possono essere più costosi se richiamati ripetutamente, ad esempio per creare nuove risorse cloud o eseguire attività costose. Gli script idempotenti, che producono lo stesso risultato in caso di invocazioni ripetute, sono più sicuri da eseguire come servizio.

Richiamare lo script su richiesta HTTP

Questo codice Go configura un servizio web che esegue uno script shell per generare un report. Poiché la query di ricerca è input utente#39;utente, il codice la convalida per assicurarsi che contenga solo lettere, numeri o trattini per impedire comandi dannosi come input. Questo insieme di caratteri è sufficientemente ristretto da impedire attacchi di iniezione di comandi.

Il servizio web passa il parametro di ricerca come argomento allo script shell.


// 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)
}

Un file go.mod dichiara le dipendenze dell'applicazione in un modulo Go:

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

go 1.19

Definisci l'ambiente del container

Il Dockerfile definisce il modo in cui viene assemblato l'ambiente per il servizio. È simile al Dockerfile della guida rapida helloworld-shell, tranne per il fatto che l'immagine container finale si basa sull'immagine gcloud di Google Cloud CLI. In questo modo, il tuo servizio può utilizzare gcloud senza passaggi di installazione e configurazione personalizzati per Google Cloud CLI.


# 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"]

Crea un repository standard Artifact Registry

Crea un repository standard di Artifact Registry per archiviare l'immagine container:

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

Sostituisci:

  • REPOSITORY con un nome univoco per il repository.
  • REGION con la regione Google Cloud di Artifact Registry.

Configura il bucket Cloud Storage

Crea un bucket Cloud Storage per caricare i report:

gcloud storage buckets create gs://REPORT_ARCHIVE_BUCKET

Sostituisci REPORT_ARCHIVE_BUCKET con un nome di bucket univoco a livello globale.

Configura l'identità del servizio

Per limitare i privilegi che il servizio ha su altre infrastrutture, crea un'identità di servizio e personalizza le autorizzazioni IAM specifiche necessarie per svolgere il lavoro.

In questo caso, i privilegi richiesti sono l'autorizzazione a leggere i servizi Cloud Run e l'autorizzazione a leggere e scrivere nel bucket Cloud Storage.

  1. Crea un account di servizio:

    gcloud iam service-accounts create gcloud-report-identity

  2. Concedi all'account di servizio l'autorizzazione per leggere i servizi Cloud Run:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=serviceAccount:gcloud-report-identity@PROJECT_ID.iam.gserviceaccount.com \
      --role roles/run.viewer
  3. Concedi all'account di servizio l'autorizzazione per leggere e scrivere nel bucket Cloud Storage:

    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

L'accesso limitato di questa identità di servizio personalizzata impedisce al servizio di accedere ad altre risorse Google Cloud .

Spedire il servizio

Il codice di spedizione prevede tre passaggi:

  • Creazione di un'immagine container con Cloud Build
  • Caricamento dell'immagine container in Artifact Registry
  • Deployment dell'immagine container in Cloud Run.

Per spedire il codice:

  1. Crea il container e pubblicalo su Artifact Registry:

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

    Sostituisci:

    • PROJECT_ID con l'ID progetto Google Cloud
    • REPOSITORY con il nome del repository Artifact Registry.
    • REGION con la regione Google Cloud di Artifact Registry.

    gcloud-report è il nome del tuo servizio.

    In caso di esito positivo, un messaggio di operazione riuscita mostra l'ID, l'ora di creazione e il nome dell'immagine. L'immagine è archiviata in Artifact Registry e può essere riutilizzata, se necessario.

  2. Esegui questo comando per eseguire il deployment del servizio:

    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

    Sostituisci:

    • PROJECT_ID con l'ID progetto Google Cloud .
    • REPOSITORY con il nome del repository Artifact Registry.
    • REGION con la regione Google Cloud del servizio.

    gcloud-report fa parte del nome del contenitore e del nome del servizio. L'immagine container viene sottoposta a deployment nel servizio e nella regione (Cloud Run) che hai configurato in precedenza in Configurazione di gcloud.

    Il flag --no-allow-unauthenticated limita l'accesso non autenticato al servizio. Mantenendo privato il servizio, puoi fare affidamento sull'autenticazione integrata di Cloud Run per bloccare le richieste non autorizzate. Per maggiori dettagli sull'autenticazione basata su Identity and Access Management (IAM), consulta Gestire l'accesso utilizzando IAM.

    Attendi il completamento del deployment. Questa operazione può richiedere circa 30 secondi. Se l'operazione riesce, la riga di comando visualizza l'URL del servizio.

  3. Se vuoi eseguire il deployment di un aggiornamento del codice nel servizio, ripeti i passaggi precedenti. Ogni deployment in un servizio crea una nuova revisione e inizia automaticamente a pubblicare il traffico quando è pronto.

Per informazioni su come concedere l'accesso per richiamare questo servizio, vedi Gestire l'accesso utilizzando IAM. Google Cloud Gli editor e i proprietari del progetto dispongono automaticamente di questo accesso.

Genera un report

Per generare un report dei servizi Cloud Run:

  1. Utilizza curl per inviare una richiesta autenticata:

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

    Sostituisci SERVICE_URL con l'URL fornito da Cloud Run dopo aver completato il deployment.

    Se hai creato un nuovo progetto e hai seguito questo tutorial, l'output sarà simile a questo:

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

    . nel nome file è l'argomento di ricerca predefinito, come indicato nel codice sorgente.

    Per utilizzare la funzionalità di ricerca, aggiungi un argomento search alla richiesta:

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

    Questa query restituirà un output simile a:

    Wrote report to gs://REPORT_ARCHIVE_BUCKET/report-gcloud-DATE.txt
  2. Recupera il file utilizzando gcloud CLI in locale:

    gcloud storage cp gs://REPORT_FILE_NAME .

    . nel comando indica la directory di lavoro corrente.

    Sostituisci REPORT_FILE_NAME con il nome dell'oggetto Cloud Storage output nel passaggio precedente.

Apri il file per visualizzare il report. Dovrebbe avere il seguente aspetto:

Screenshot dell'elenco dei servizi Cloud Run nel progetto con colonne per quattro attributi del servizio.
Le quattro colonne vengono estratte dalla descrizione del servizio. Questi includono il nome del servizio, l'URL assegnato al primo deployment, il creatore iniziale del servizio e i limiti del servizio relativi a CPU e memoria massime.

Migliorare la robustezza per il futuro

Se intendi sviluppare ulteriormente questo servizio, valuta la possibilità di riscriverlo in un linguaggio di programmazione più solido e di utilizzare l'API Cloud Run Admin e la libreria client Cloud Storage.

Puoi esaminare le chiamate API effettuate (e visualizzare alcuni dettagli di autenticazione) aggiungendo --log-http ai comandi gcloud CLI.

Automatizza questa operazione

Ora che il report dei servizi Cloud Run può essere attivato da una richiesta HTTP, utilizza l'automazione per generare report quando ne hai bisogno:

Esegui la pulizia

Se hai creato un nuovo progetto per questo tutorial, elimina il progetto. Se hai utilizzato un progetto esistente e vuoi conservarlo senza le modifiche aggiunte in questo tutorial, elimina le risorse create per il tutorial.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto creato per il tutorial.

Per eliminare il progetto:

  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.

Eliminazione delle risorse del tutorial

  1. Elimina il servizio Cloud Run di cui hai eseguito il deployment in questo tutorial:

    gcloud run services delete SERVICE-NAME

    Dove SERVICE-NAME è il nome del servizio che hai scelto.

    Puoi anche eliminare i servizi Cloud Run dalla Google Cloud console.

  2. Rimuovi la configurazione della regione predefinita di gcloud che hai aggiunto durante la configurazione del tutorial:

     gcloud config unset run/region
    
  3. Rimuovi la configurazione del progetto:

     gcloud config unset project
    
  4. Elimina le altre risorse Google Cloud create in questo tutorial:

Passaggi successivi