Tutoriel sur la ligne de commande gcloud dans un service Cloud Run


Dans ce tutoriel, vous allez créer un inventaire de services Cloud Run à l'aide des outils de ligne de commande gcloud et gsutil dans un service Cloud Run. Vous pouvez appliquer ce que vous appenez dans ce tutoriel à vos scripts d'opérations Cloud existants ou créer une démonstration de faisabilité avant d'utiliser des bibliothèques clientes pour créer un service plus robuste.

Vous utilisez les outils gcloud et gsutil, comme n'importe quel script shell à l'intérieur d'un service Web, par exemple, comme indiqué dans le guide de démarrage rapide de Shell. Sur Cloud Run, ces deux outils fonctionnent avec les services Google Cloud en s'authentifiant automatiquement avec l'identité de service Cloud Run. Toutes les autorisations accordées à l'identité du service sont disponibles pour gcloud CLI.

gcloud CLI est tellement en mesure de collecter des informations et de gérer les ressources sur Google Cloud que le défi de son utilisation dans un service Web consiste à réduire le risque qu'un appelant utilise ces fonctionnalités de façon incorrecte. Sans contrôle de sécurité, vous risquez de créer des risques pour d'autres services ou ressources exécutés dans le même projet en autorisant des activités malveillantes accidentelles ou intentionnelles. Voici quelques exemples :

  • Activer la découverte des adresses IP de machines virtuelles privées
  • Activer l'accès aux données privées d'une base de données dans le même projet
  • Activer la suppression d'autres services en cours d'exécution

Plusieurs étapes de ce tutoriel expliquent comment imposer des contrôles afin de minimiser les risques, tels que la spécification de la commande gcloud à exécuter dans le code, au lieu de la laisser en tant qu'entrée utilisateur.

La création de script avec l'outil de ligne de commande au sein d'un service Cloud Run est semblable à la création de script avec la ligne de commande localement. La principale différence réside dans les restrictions supplémentaires que vous devez ajouter autour de la logique de script principale.

Objectifs

  • Écrire et créer un conteneur personnalisé avec un fichier Dockerfile.
  • Écrire, créer et déployer un service Cloud Run.
  • Utiliser les outils gcloud et gsutil en toute sécurité dans un service Web
  • Générer un rapport sur les services Cloud Run, puis enregistrer dans Cloud Storage

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  5. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  6. Activer les API Artifact Registry, Cloud Build, Cloud Run, and Cloud Storage.

    Activer les API

  7. Installez et initialisez gcloud CLI.

Rôles requis

Pour obtenir les autorisations nécessaires pour suivre le tutoriel, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez la section Gérer les accès.

Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

Configurer les paramètres par défaut de gcloud

Pour configurer gcloud avec les valeurs par défaut pour votre service Cloud Run, procédez comme suit :

  1. Définissez le projet par défaut :

    gcloud config set project PROJECT_ID

    Remplacez PROJECT_ID par le nom du projet que vous avez créé pour ce tutoriel.

  2. Configurez gcloud pour la région choisie :

    gcloud config set run/region REGION

    Remplacez REGION par la région Cloud Run compatible de votre choix.

Emplacements Cloud Run

Cloud Run est régional, ce qui signifie que l'infrastructure qui exécute vos services Cloud Run est située dans une région spécifique et gérée par Google pour être disponible de manière redondante dans toutes les zones de cette région.

Lors de la sélection de la région dans laquelle exécuter vos services Cloud Run, vous devez tout d'abord considérer vos exigences en matière de latence, de disponibilité et de durabilité. Vous pouvez généralement sélectionner la région la plus proche de vos utilisateurs, mais vous devez tenir compte de l'emplacement des autres produits Google Cloud utilisés par votre service Cloud Run. L'utilisation conjointe de produits Google Cloud dans plusieurs emplacements peut avoir une incidence sur la latence et le coût de votre service.

Cloud Run est disponible dans les régions suivantes :

Soumis aux tarifs de niveau 1

Soumis aux tarifs de niveau 2

  • africa-south1 (Johannesburg)
  • asia-east2 (Hong Kong)
  • asia-northeast3 (Séoul, Corée du Sud)
  • asia-southeast1 (Singapour)
  • asia-southeast2 (Jakarta)
  • asia-south1 (Mumbai, Inde)
  • asia-south2 (Delhi, Inde)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Varsovie, Pologne)
  • europe-west10 (Berlin)
  • europe-west12 (Turin)
  • europe-west2 (Londres, Royaume-Uni) icône feuille Faibles émissions de CO2
  • europe-west3 (Francfort, Allemagne) icône feuille Faibles émissions de CO2
  • europe-west6 (Zurich, Suisse) icône feuille Faibles émissions de CO2
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montréal) icône feuille Faibles émissions de CO2
  • northamerica-northeast2 (Toronto) icône feuille Faibles émissions de CO2
  • southamerica-east1 (São Paulo, Brésil) icône feuille Faibles émissions de CO2
  • southamerica-west1 (Santiago, Chili) icône feuille Faibles émissions de CO2
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Si vous avez déjà créé un service Cloud Run, vous pouvez afficher la région dans le tableau de bord Cloud Run de la console Google Cloud.

Récupérer l'exemple de code

Pour récupérer l’exemple de code à utiliser, procédez comme suit :

  1. Clonez le dépôt de l'exemple d'application sur votre machine locale :

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

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

  2. Accédez au répertoire contenant l'exemple de code Cloud Run :

    cd cloud-run-samples/gcloud-report/

Examiner le code

Cette section contient des informations sur l'exemple de code que vous avez récupéré.

Générer un rapport et l'importer dans Cloud Storage

Ce script shell génère un rapport des services Cloud Run dans le projet et la région actuels et importe le résultat dans Cloud Storage. Il répertorie les services dont le nom contient l'argument search de chaîne fourni.

Le script utilise la commande gcloud run services list, les options de format avancées gcloud et le mode copie du transfert de diffusion gsutil.

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

Ce script s'exécute sans risque en tant que service, car des appels répétés de celui-ci mettent à jour le rapport sans entraîner de pertes supplémentaires coûteuses. Les autres scripts utilisant gcloud CLI peuvent s'avérer plus coûteux lorsqu'ils sont appelés à plusieurs reprises, comme la création de ressources Cloud ou l'exécution de tâches coûteuses. Les scripts Idempotents, qui renvoient le même résultat sur des appels répétés, sont plus sûrs à s'exécuter en tant que service.

Appeler le script dans une requête HTTP

Ce code Go configure un service Web qui exécute un script shell pour générer un rapport. Étant donné que la requête de recherche est une entrée utilisateur, le code la valide afin de s'assurer qu'elle ne contient que des lettres, des chiffres ou des traits d'union pour empêcher les commandes malveillantes en entrée. Cet ensemble de caractères est suffisamment limité pour empêcher les attaques par injection de commande.

Le service Web transmet le paramètre de recherche en tant qu'argument au 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 fichier go.mod déclare les dépendances de l'application dans un module Go :

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

go 1.19

Définir l'environnement de conteneur

Le fichier Dockerfile définit la manière dont l'environnement est mis en place pour le service. Il est semblable au fichier Dockerfile du démarrage rapide helloworld-shell, sauf que l'image de conteneur finale est basée sur l'image de Google Cloud CLI gcloud. Cela permet à notre service d'utiliser gcloud et gsutil sans étapes d'installation et de configuration personnalisées pour 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"]

Créer un dépôt standard Artifact Registry

Créez un dépôt standard Artifact Registry pour stocker votre image de conteneur :

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

Remplacez :

  • REPOSITORY par un nom unique pour le dépôt
  • REGION par la région Google Cloud d'Artifact Registry

Configurer le bucket Cloud Storage

Créez un bucket Cloud Storage dans lequel importer des rapports :

gsutil mb gs://REPORT_ARCHIVE_BUCKET

Remplacez REPORT_ARCHIVE_BUCKET par un nom de bucket unique.

Configurer l'identité du service

Afin de limiter les droits d'accès du service à d'autres infrastructures, vous devez créer une identité de service et personnaliser les autorisations IAM spécifiques nécessaires pour le travail.

Dans ce cas, les privilèges requis sont des autorisations pour lire les services Cloud Run, et pour lire depuis le bucket Cloud Storage et y écrire.

  1. Créez un compte de service :

    gcloud iam service-accounts create gcloud-report-identity

  2. Accordez au compte de service l'autorisation de lire les services 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. Accordez à ce compte de service l'autorisation de lire depuis le bucket Cloud Storage et d'y écrire :

    gsutil iam ch \
      serviceAccount:gcloud-report-identity@PROJECT_ID.iam.gserviceaccount.com:objectViewer,objectCreator \
      gs://REPORT_ARCHIVE_BUCKET

L'accès limité de cette identité de service personnalisée empêche le service d'accéder à d'autres ressources Google Cloud.

Transmettre le service

La transmission du code comprend trois étapes :

  • Créer une image de conteneur avec Cloud Build
  • Importer l'image de conteneur dans Artifact Registry
  • Déployer l'image de conteneur dans Cloud Run

Pour transmettre votre code, procédez comme suit :

  1. Créez votre conteneur et publiez-le dans Artifact Registry :

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

    Remplacez :

    • PROJECT_ID par l'ID de votre projet Google Cloud
    • REPOSITORY par le nom du dépôt Artifact Registry
    • REGION par la région Google Cloud d'Artifact Registry

    gcloud-report est le nom de votre service.

    En cas de réussite, un message SUCCESS apparaît et indique l'ID, l'heure de création et le nom de l'image. L'image est stockée dans Artifact Registry et peut être réutilisée si nécessaire.

  2. Exécutez la commande suivante pour déployer votre service :

    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

    Remplacez :

    • PROJECT_ID par l'ID de votre projet Google Cloud
    • REPOSITORY par le nom du dépôt Artifact Registry
    • REGION par la région Google Cloud du service.

    gcloud-report fait partie du nom du conteneur et du nom du service. L'image de conteneur est déployée dans le service et la région (Cloud Run) que vous avez configurés précédemment dans Configurer gcloud.

    L'option --no-allow-unauthenticated limite l'accès non authentifié au service. En maintenant le service privé, le processus d'authentification intégré de Cloud Run vous permet de bloquer les requêtes non autorisées. Pour en savoir plus sur l'authentification basée sur Identity and Access Management (IAM), consultez la page Gérer les accès à l'aide d'IAM.

    Patientez jusqu'à la fin du déploiement. Cette opération peut prendre environ 30 secondes. En cas de réussite, la ligne de commande affiche l'URL du service.

  3. Si vous souhaitez déployer une mise à jour de code sur le service, répétez les opérations précédentes. Chaque déploiement sur un service crée une nouvelle révision et commence automatiquement à acheminer le trafic une fois prêt.

Consultez la page Gérer les accès à l'aide d'IAM pour découvrir comment autoriser les utilisateurs de Google Cloud à appeler ce service. Les éditeurs et propriétaires du projet disposent automatiquement de cet accès.

Générer un rapport

Pour générer un rapport sur les services Cloud Run, procédez comme suit :

  1. Utilisez curl pour envoyer une requête authentifiée :

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

    Remplacez SERVICE_URL par l'URL fournie par Cloud Run une fois le déploiement terminé.

    Si vous avez créé un projet et suivi ce tutoriel, le résultat ressemble à ceci :

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

    Le . du nom de fichier est l'argument de recherche par défaut mentionné dans le code source.

    Pour utiliser la fonctionnalité de recherche, ajoutez un argument search à la requête :

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

    Cette requête renvoie un résultat semblable à celui-ci :

    Wrote report to gs://REPORT_ARCHIVE_BUCKET/report-gcloud-DATE.txt
  2. Récupérez le fichier en local à l'aide de l'outil gsutil :

    gsutil cp gs://REPORT_FILE_NAME .

    L'élément . de la commande correspond au répertoire de travail actuel.

    Remplacez REPORT_FILE_NAME par le nom de l'objet Cloud Storage renvoyé à l'étape précédente.

Ouvrez le fichier pour afficher le rapport. Elle doit se présenter comme ceci :

Capture d'écran de la liste des services Cloud Run dans le projet avec des colonnes pour quatre attributs de service.
Les quatre colonnes sont extraites de la description du service. Elles incluent le nom du service, l'URL attribuée au premier déploiement, le créateur initial du service et les limites du processeur et de la mémoire maximales du service.

Renforcer la stabilité pour plus tard

Si vous envisagez de développer davantage ce service, envisagez de réécrire dans un langage de programmation plus performant, à l'aide de l'API Cloud Run Admin et de la bibliothèque cliente Cloud Storage.

Vous pouvez examiner les appels d'API effectués (et voir des informations d'authentification) en ajoutant --log-http aux commandes gcloud et -D aux commandes gsutil.

Automatiser cette opération

Maintenant que le rapport sur les services Cloud Run peut être déclenché par une requête HTTP, utilisez l'automatisation pour générer des rapports lorsque vous en avez besoin :

Effectuer un nettoyage

Si vous avez créé un projet pour ce tutoriel, supprimez-le. Si vous avez utilisé un projet existant et que vous souhaitez le conserver sans les modifications du présent tutoriel, supprimez les ressources créées pour ce tutoriel.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer les ressources du tutoriel

  1. Supprimez le service Cloud Run que vous avez déployé dans ce tutoriel :

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME est le nom de service que vous avez choisi.

    Vous pouvez également supprimer des services Cloud Run à partir de Google Cloud Console.

  2. Supprimez la configuration régionale gcloud par défaut que vous avez ajoutée lors de la configuration du tutoriel :

     gcloud config unset run/region
    
  3. Supprimez la configuration du projet :

     gcloud config unset project
    
  4. Supprimez les autres ressources Google Cloud créées dans ce tutoriel :

Étape suivante