Connecter Cloud Spanner à GKE Autopilot

1. Introduction

Cloud Spanner est un service de base de données relationnelle entièrement géré, évolutif horizontalement et distribué à l'échelle mondiale. Il fournit des transactions ACID et une sémantique SQL sans faire de compromis sur les performances et la haute disponibilité.

GKE Autopilot est un mode de fonctionnement dans GKE dans lequel Google gère la configuration de votre cluster, y compris vos nœuds, le scaling, la sécurité et d'autres paramètres préconfigurés, conformément aux bonnes pratiques. Par exemple, GKE Autopilot permet à Workload Identity de gérer les autorisations de service.

L'objectif de cet atelier est de vous guider tout au long du processus de connexion de plusieurs services de backend exécutés sur GKE Autopilot à une base de données Cloud Spanner.

3d810aa9ec80a271.png

Dans cet atelier, vous allez d'abord configurer un projet et lancer Cloud Shell. Vous déploierez ensuite l'infrastructure à l'aide de Terraform.

Une fois cette opération terminée, vous interagirez avec Cloud Build et Cloud Deploy pour effectuer une migration de schéma initiale pour la base de données "Games" (Jeux), déployer les services de backend, puis déployer les charges de travail.

Les services présentés dans cet atelier de programmation sont les mêmes que ceux de l'atelier de programmation Premiers pas avec le développement de jeux avec Cloud Spanner. Il n'est pas obligatoire de suivre cet atelier de programmation pour que les services s'exécutent sur GKE et se connectent à Spanner. Mais si vous souhaitez en savoir plus sur les spécificités de ces services compatibles avec Spanner, consultez-les.

Une fois les charges de travail et les services de backend en cours d'exécution, vous pouvez commencer à générer une charge et observer comment les services fonctionnent ensemble.

Enfin, vous allez nettoyer les ressources que vous avez créées dans cet atelier.

Ce que vous allez faire

Au cours de cet atelier, vous allez:

  • Provisionner l'infrastructure à l'aide de Terraform
  • Créer le schéma de base de données à l'aide d'un processus de migration de schéma dans Cloud Build
  • Déployer les quatre services de backend Golang qui utilisent Workload Identity pour se connecter à Cloud Spanner
  • Déployez les quatre services de charge de travail utilisés pour simuler la charge des services de backend.

Points abordés

  • Provisionner des pipelines GKE Autopilot, Cloud Spanner et Cloud Deploy à l'aide de Terraform
  • Comment Workload Identity permet aux services sur GKE d'emprunter l'identité de comptes de service afin d'accéder aux autorisations IAM pour fonctionner avec Cloud Spanner
  • Générer une charge de type production sur GKE et Cloud Spanner à l'aide de Locust.io

Prérequis

  • Un projet Google Cloud associé à un compte de facturation
  • Un navigateur (Chrome ou Firefox, par exemple).

2. Préparation

Créer un projet

Si vous ne possédez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform ( console.cloud.google.com) et créez un projet.

Si vous avez déjà un projet, cliquez sur le menu déroulant de sélection du projet dans l'angle supérieur gauche de la console :

6c9406d9b014760.png

et cliquez sur NOUVEAU PROJET. dans la boîte de dialogue qui s'affiche pour créer un projet:

949d83c8a4ee17d9.png

Si vous n'avez pas encore de projet, une boîte de dialogue semblable à celle-ci apparaîtra pour vous permettre d'en créer un :

870a3cbd6541ee86.png

La boîte de dialogue de création de projet suivante vous permet de saisir les détails de votre nouveau projet :

6a92c57d3250a4b3.png

Notez l'ID du projet. Il s'agit d'un nom unique pour tous les projets Google Cloud, ce qui implique que le nom ci-dessus n'est plus disponible pour vous… Désolé ! Tout au long de cet atelier de programmation, nous utiliserons PROJECT_ID pour faire référence à cet ID.

Ensuite, si ce n'est pas déjà fait, vous devez activer la facturation dans Developers Console afin de pouvoir utiliser les ressources Google Cloud puis activer l'API Cloud Spanner.

15d0ef27a8fbab27.png

Suivre cet atelier de programmation ne devrait pas vous coûter plus d'un euro. Cependant, cela peut s'avérer plus coûteux si vous décidez d'utiliser davantage de ressources ou si vous n'interrompez pas les ressources (voir la section "Effectuer un nettoyage" à la fin du présent document). Pour consulter les tarifs de Google Cloud Spanner, cliquez ici. Pour consulter les tarifs de GKE Autopilot, cliquez ici.

Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un Essai gratuit avec 300 $ de crédits afin de suivre gratuitement le présent atelier.

Configuration de Cloud Shell

Bien que Google Cloud et Spanner puissent être utilisés à distance depuis votre ordinateur portable, nous allons utiliser Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans le cloud.

Cette machine virtuelle basée sur Debian contient tous les outils de développement dont vous aurez besoin. Elle intègre un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Cela signifie que tout ce dont vous avez besoin pour cet atelier de programmation est un navigateur (oui, tout fonctionne sur un Chromebook).

  1. Pour activer Cloud Shell depuis la console Cloud, il vous suffit de cliquer sur Activer Cloud Shell gcLMt5IuEcJJNnMId-Bcz3sxCd0rZn7IzT_r95C8UZeqML68Y1efBG_B0VRp7hc7qiZTLAF-TXD7SsOadxn8uadgHhaLeASnVS3ZHK39eOlKJOgj9SJua_oeGhMxRrbOg3qigddS2A. Le provisionnement et la connexion à l'environnement ne devraient pas prendre plus de quelques minutes.

JjEuRXGg0AYYIY6QZ8d-66gx_Mtc-_jDE9ijmbXLJSAXFvJt-qUpNtsBsYjNpv2W6BQSrDc1D-ARINNQ-1EkwUhz-iUK-FUCZhJ-NtjvIEx9pIkE-246DomWuCfiGHK78DgoeWkHRw

Capture d'écran du 2017-06-14 à 10.13.43 PM.png

Une fois connecté à Cloud Shell, vous êtes normalement déjà authentifié et le projet PROJECT_ID est sélectionné :

gcloud auth list

Résultat de la commande

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si, pour une raison quelconque, le projet n'est pas défini, exécutez simplement la commande suivante :

gcloud config set project <PROJECT_ID>

Vous recherchez votre PROJECT_ID ? Vérifiez l'ID que vous avez utilisé pendant les étapes de configuration ou recherchez-le dans le tableau de bord Cloud Console :

158fNPfwSxsFqz9YbtJVZes8viTS3d1bV4CVhij3XPxuzVFOtTObnwsphlm6lYGmgdMFwBJtc-FaLrZU7XHAg_ZYoCrgombMRR3h-eolLPcvO351c5iBv506B3ZwghZoiRg6cz23Qw

Par défaut, Cloud Shell définit certaines variables d'environnement qui pourront s'avérer utiles pour exécuter certaines commandes dans le futur.

echo $GOOGLE_CLOUD_PROJECT

Résultat de la commande

<PROJECT_ID>

Télécharger le code

Dans Cloud Shell, vous pouvez télécharger le code de cet atelier:

git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git

Résultat de la commande

Cloning into 'spanner-gaming-sample'...
*snip*

Cet atelier de programmation est basé sur la version v0.1.3. Vérifiez donc ce tag:

cd spanner-gaming-sample
git fetch --all --tags

# Check out v0.1.3 release
git checkout tags/v0.1.3 -b v0.1.3-branch

Résultat de la commande

Switched to a new branch 'v0.1.3-branch'

À présent, définissez le répertoire de travail actuel en tant que variable d'environnement DEMO_HOME. Cela facilitera la navigation dans les différentes parties de l'atelier de programmation.

export DEMO_HOME=$(pwd)

Résumé

Au cours de cette étape, vous avez configuré un nouveau projet, activé Cloud Shell et téléchargé le code de cet atelier.

Étape suivante

Vous allez ensuite provisionner l'infrastructure à l'aide de Terraform.

3. Provisionner l'infrastructure

Présentation

Votre projet étant prêt, il est temps de mettre en œuvre l'infrastructure. Cela inclut la mise en réseau VPC, Cloud Spanner, GKE Autopilot, Artifact Registry pour stocker les images qui seront exécutées sur GKE, les pipelines Cloud Deploy pour les services de backend et les charges de travail, et enfin les comptes de service et les droits IAM permettant d'utiliser ces services.

C'est beaucoup. Heureusement, Terraform peut simplifier cette configuration. Terraform est un outil de type qui nous permet de spécifier ce dont nous avons besoin pour ce projet dans une série . Cela simplifie le provisionnement de l'infrastructure.

Il n'est pas nécessaire de connaître Terraform pour cet atelier de programmation. Toutefois, si vous voulez savoir ce que font les prochaines étapes, vous pouvez voir ce qui a été créé dans ces fichiers situés dans le répertoire infrastructure:

  • vpc.tf
  • backend_gke.tf
  • spanner.tf
  • artifact_registry.tf
  • pipelines.tf
  • iam.tf

Configurer Terraform

Dans Cloud Shell, accédez au répertoire infrastructure et initialisez Terraform:

cd $DEMO_HOME/infrastructure
terraform init

Résultat de la commande

Initializing the backend...

Initializing provider plugins...
*snip*
Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Ensuite, configurez Terraform en copiant terraform.tfvars.sample et en modifiant la valeur du projet. Les autres variables peuvent également être modifiées, mais le projet est la seule variable à modifier pour fonctionner avec votre environnement.

cp  terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars

Provisionner l'infrastructure

Il est maintenant temps de provisionner l'infrastructure.

terraform apply
# review the list of things to be created
# type 'yes' when asked

Résultat de la commande

Plan: 46 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_project_service.project["container.googleapis.com"]: Creating...
*snip*
Apply complete! Resources: 46 added, 0 changed, 0 destroyed.

Vérifier ce qui a été créé

Pour vérifier ce qui a été créé, vous devez vérifier les produits dans la console Cloud.

Cloud Spanner

Commencez par vérifier Cloud Spanner en accédant au menu hamburger et en cliquant sur Spanner. Vous devrez peut-être cliquer sur "Afficher plus de produits" pour le trouver dans la liste.

La liste des instances Spanner s'affiche. Cliquez sur l'instance pour afficher les bases de données. Voici un exemple :

10b7fc0c4a86c59.png

GKE Autopilot

Consultez ensuite GKE en accédant au menu hamburger et en cliquant sur Kubernetes Engine => Clusters. Ici, le cluster sample-games-gke s'exécute en mode Autopilot.

9cecb1a702e6b7ff.png

Artifact Registry

Voyons maintenant où les images sont stockées. Cliquez sur le menu hamburger et recherchez Artifact Registry=>Repositories. Artifact Registry se trouve dans la section "CI/CD" du menu.

Vous verrez ici un registre Docker nommé spanner-game-images. Ce champ est vide pour le moment.

3f805eee312841b.png

Cloud Deploy

C'est dans Cloud Deploy que les pipelines ont été créés afin que Cloud Build puisse fournir les étapes nécessaires à la création des images, puis les déployer sur notre cluster GKE.

Accédez au menu hamburger et recherchez Cloud Deploy, qui se trouve également dans la section CI/CD du menu.

Ici, vous remarquerez deux pipelines: un pour les services de backend et un pour les charges de travail. Toutes deux déploient les images sur le même cluster GKE, mais cela permet de séparer nos déploiements.

d2e4a659145ddf5e.png

IAM

Enfin, consultez la page IAM dans la console Cloud pour vérifier les comptes de service qui ont été créés. Accédez au menu hamburger et recherchez IAM and Admin=>Service accounts. Voici un exemple :

bed3d1af94974916.png

Six comptes de service au total sont créés par Terraform:

  • Compte de service de l'ordinateur par défaut. Ce nom n'est pas utilisé dans cet atelier de programmation.
  • Le compte cloudbuild-cicd est utilisé pour les étapes Cloud Build et Cloud Deploy.
  • Quatre "applications" les comptes utilisés par nos services de backend pour interagir avec Cloud Spanner.

Vous devez maintenant configurer kubectl pour qu'il interagit avec le cluster GKE.

Configurer kubectl

# Name of GKE cluster from terraform.tfvars file
export GKE_CLUSTER=sample-game-gke 

# get GKE credentials
gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1

# Check that no errors occur
kubectl get serviceaccounts

Résultat de la commande

#export GKE_CLUSTER=sample-game-gke

# gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for sample-game-gke.

# kubectl get serviceaccounts
NAME              SECRETS   AGE
default           0         37m
item-app          0         35m
matchmaking-app   0         35m
profile-app       0         35m
tradepost-app     0         35m

Résumé

Parfait ! Vous avez pu provisionner une instance Cloud Spanner, un cluster GKE Autopilot, dans un VPC pour mettre en réseau privé.

Deux pipelines Cloud Deploy ont également été créés pour les services de backend et les charges de travail, ainsi qu'un dépôt Artifact Registry pour stocker les images compilées.

Enfin, les comptes de service ont été créés et configurés pour fonctionner avec Workload Identity afin que les services de backend puissent utiliser Cloud Spanner.

kubectl est également configuré pour interagir avec le cluster GKE dans Cloud Shell après le déploiement des services et charges de travail de backend.

Étape suivante

Avant de pouvoir utiliser les services, vous devez définir le schéma de la base de données. C'est la prochaine étape.

4. Créer le schéma de base de données

Présentation

Avant de pouvoir exécuter les services de backend, vous devez vous assurer que le schéma de base de données est bien en place.

Si vous examinez les fichiers du répertoire $DEMO_HOME/schema/migrations à partir du dépôt de démonstration, vous verrez une série de fichiers .sql qui définissent notre schéma. Cela imite un cycle de développement au cours duquel les modifications du schéma sont suivies dans le dépôt lui-même. Elle peut être liée à certaines fonctionnalités des applications.

Pour cet exemple d'environnement, l'outil associées à une clé applique nos migrations de schéma à l'aide de Cloud Build.

Cloud Build

Le fichier $DEMO_HOME/schema/cloudbuild.yaml décrit les étapes à suivre:

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:
- name: gcr.io/cloud-builders/curl
 id: fetch-wrench
 args: ['-Lo', '/workspace/wrench.tar.gz', 'https://github.com/cloudspannerecosystem/wrench/releases/download/v1.4.1/wrench-1.4.1-linux-amd64.tar.gz' ]

- name: gcr.io/cloud-builders/gcloud
 id: migrate-spanner-schema
 entrypoint: sh
 args:
 - '-xe'
 - '-c'
 - |
   tar -xzvf wrench.tar.gz

   chmod +x /workspace/wrench

   # Assumes only a single spanner instance and database. Fine for this demo in a dedicated project
   export SPANNER_PROJECT_ID=${PROJECT_ID}
   export SPANNER_INSTANCE_ID=$(gcloud spanner instances list | tail -n1 | awk '{print $1}')
   export SPANNER_DATABASE_ID=$(gcloud spanner databases list --instance=$$SPANNER_INSTANCE_ID | tail -n1 | awk '{print $1}')

   if [ -d ./migrations ]; then
     /workspace/wrench migrate up --directory .
   else
     echo "[Error] Missing migrations directory"
   fi
timeout: 600s

Il y a essentiellement deux étapes:

  • télécharger une clé à molette dans l'espace de travail Cloud Build
  • exécuter la migration de la clé à molette

Les variables d'environnement de projet, d'instance et de base de données Spanner sont nécessaires pour que la clé à molette puisse se connecter au point de terminaison d'écriture.

Cloud Build peut effectuer ces modifications, car il s'exécute en tant que compte de service cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com:

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com

Le rôle spanner.databaseUser a été ajouté à ce compte de service par Terraform, ce qui lui permet de mettre à jour le DDL.

Migrations de schémas

Cinq étapes de migration sont effectuées en fonction des fichiers du répertoire $DEMO_HOME/schema/migrations. Voici un exemple de fichier 000001.sql qui crée une table players et l'indexe:

CREATE TABLE players (
   playerUUID STRING(36) NOT NULL,
   player_name STRING(64) NOT NULL,
   email STRING(MAX) NOT NULL,
   password_hash BYTES(60) NOT NULL,
   created TIMESTAMP,
   updated TIMESTAMP,
   stats JSON,
   account_balance NUMERIC NOT NULL DEFAULT (0.00),
   is_logged_in BOOL,
   last_login TIMESTAMP,
   valid_email BOOL,
   current_game STRING(36)
) PRIMARY KEY (playerUUID);

CREATE UNIQUE INDEX PlayerAuthentication ON players(email) STORING(password_hash);
CREATE UNIQUE INDEX PlayerName ON players(player_name);
CREATE INDEX PlayerGame ON players(current_game);

Envoyer la migration de schéma

Pour envoyer la compilation afin d'effectuer la migration du schéma, accédez au répertoire schema et exécutez la commande gcloud suivante:

cd $DEMO_HOME/schema
gcloud builds submit --config=cloudbuild.yaml

Résultat de la commande

Creating temporary tarball archive of 8 file(s) totalling 11.2 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/7defe982-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/7defe982-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 7defe982-(snip)
CREATE_TIME: (created time)
DURATION: 3M11S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: -
STATUS: SUCCESS

Dans le résultat ci-dessus, vous remarquerez un lien vers le processus de compilation cloud Created. Si vous cliquez dessus, vous serez redirigé vers la compilation dans la console Cloud où vous pourrez surveiller la progression de la compilation et voir ce qu'elle fait.

11b1cf107876d797.png

Résumé

Au cours de cette étape, vous avez utilisé Cloud Build pour envoyer la migration de schéma initiale qui a appliqué cinq opérations LDD différentes. Ces opérations représentent le moment où des fonctionnalités ont été ajoutées et nécessitaient des modifications du schéma de la base de données.

Dans un scénario de développement normal, il serait souhaitable de rendre les modifications de schéma rétrocompatibles avec l'application actuelle afin d'éviter les pannes.

Pour les modifications non rétrocompatibles, vous devez déployer les modifications apportées à l'application et au schéma par étapes afin d'éviter toute interruption de service.

Étape suivante

Une fois le schéma en place, l'étape suivante consiste à déployer les services de backend.

5. Déployer les services de backend

Présentation

Les services de backend de cet atelier de programmation sont des API REST Golang qui représentent quatre services différents:

  • Profil:permet aux joueurs de s'inscrire à notre exemple de "jeu" et de s'y authentifier.
  • Mise en correspondance:interagissez avec les données des joueurs pour faciliter la mise en correspondance, suivre les informations sur les jeux créés et mettre à jour les statistiques des joueurs à la fermeture des matchs.
  • Objet:permet aux joueurs d'acquérir des objets et de l'argent au cours d'une partie.
  • Tradepost::permet aux joueurs d'acheter et de vendre des articles dans un post.

d36e958411d44b5d.png

Pour en savoir plus sur ces services, consultez l'atelier de programmation Premiers pas avec le développement de jeux Cloud Spanner. Pour les besoins de cet atelier, nous voulons que ces services s'exécutent sur notre cluster GKE Autopilot.

Ces services doivent pouvoir modifier les données Spanner. Pour ce faire, chaque service dispose d'un compte de service qui lui attribue le rôle "databaseUser" rôle de ressource.

Workload Identity permet à un compte de service Kubernetes d'emprunter l'identité des Google Cloud en procédant comme suit dans notre fichier Terraform:

  • Créer la ressource du compte de service Google Cloud (GSA) du service
  • Attribuez le rôle databaseUser à ce compte de service.
  • Attribuez le rôle workloadIdentityUser à ce compte de service.
  • Créez un compte de service Kubernetes (KSA) qui référence le système Google Search Appliance.

Un diagramme approximatif ressemblerait à ceci:

a8662d31d66b5910.png

Terraform a créé les comptes de service et les comptes de service Kubernetes à votre place. Vous pouvez également vérifier les comptes de service Kubernetes à l'aide de kubectl:

# kubectl get serviceaccounts
NAME              SECRETS   AGE
default           0         37m
item-app          0         35m
matchmaking-app   0         35m
profile-app       0         35m
tradepost-app     0         35m

La compilation fonctionne comme suit:

serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:

#
# Building of images
#
 - name: gcr.io/cloud-builders/docker
   id: profile
   args: ["build", ".", "-t", "${_PROFILE_IMAGE}"]
   dir: profile
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: matchmaking
   args: ["build", ".", "-t", "${_MATCHMAKING_IMAGE}"]
   dir: matchmaking
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: item
   args: ["build", ".", "-t", "${_ITEM_IMAGE}"]
   dir: item
   waitFor: ['-']
 - name: gcr.io/cloud-builders/docker
   id: tradepost
   args: ["build", ".", "-t", "${_TRADEPOST_IMAGE}"]
   dir: tradepost
   waitFor: ['-']

#
# Deployment
#
 - name: gcr.io/google.com/cloudsdktool/cloud-sdk
   id: cloud-deploy-release
   entrypoint: gcloud
   args:
     [
       "deploy", "releases", "create", "${_REL_NAME}",
       "--delivery-pipeline", "sample-game-services",
       "--skaffold-file", "skaffold.yaml",
       "--skaffold-version", "1.39",
       "--images", "profile=${_PROFILE_IMAGE},matchmaking=${_MATCHMAKING_IMAGE},item=${_ITEM_IMAGE},tradepost=${_TRADEPOST_IMAGE}",
       "--region", "us-central1"
     ]

artifacts:
 images:
   - ${_REGISTRY}/profile
   - ${_REGISTRY}/matchmaking
   - ${_REGISTRY}/item
   - ${_REGISTRY}/tradepost

substitutions:
 _PROFILE_IMAGE: ${_REGISTRY}/profile:${BUILD_ID}
 _MATCHMAKING_IMAGE: ${_REGISTRY}/matchmaking:${BUILD_ID}
 _ITEM_IMAGE: ${_REGISTRY}/item:${BUILD_ID}
 _TRADEPOST_IMAGE: ${_REGISTRY}/tradepost:${BUILD_ID}
 _REGISTRY: us-docker.pkg.dev/${PROJECT_ID}/spanner-game-images
 _REL_NAME: rel-${BUILD_ID:0:8}
options:
 dynamic_substitutions: true
 machineType: E2_HIGHCPU_8
 logging: CLOUD_LOGGING_ONLY
  • La commande Cloud Build lit ce fichier et suit les étapes indiquées. Tout d'abord, il crée les images du service. Ensuite, il exécute une commande gcloud deploy create. Vous accédez alors au fichier $DEMO_HOME/backend_services/skaffold.yaml, qui définit l'emplacement de chaque fichier de déploiement:
apiVersion: skaffold/v2beta29
kind: Config
deploy:
 kubectl:
   manifests:
     - spanner_config.yaml
     - profile/deployment.yaml
     - matchmaking/deployment.yaml
     - item/deployment.yaml
     - tradepost/deployment.yaml
  • Cloud Deploy applique les définitions du fichier deployment.yaml de chaque service. Le fichier de déploiement du service contient les informations nécessaires à la création du service. Dans le cas présent, il s'agit d'une adresse IP de cluster exécutée sur le port 80.

Le <ph type="x-smartling-placeholder"></ph>" ClusterIP" empêche les pods du service de backend de disposer d'une adresse IP externe. Ainsi, seules les entités pouvant se connecter au réseau GKE interne peuvent accéder aux services de backend. Ces services ne doivent pas être directement accessibles aux joueurs, car ils accèdent aux données Spanner et les modifient.

apiVersion: v1
kind: Service
metadata:
 name: profile
spec:
 type: ClusterIP
 selector:
   app: profile
 ports:
 - port: 80
   targetPort: 80

En plus de créer un service Kubernetes, Cloud Deploy crée également un déploiement Kubernetes. Examinons la section concernant le déploiement du service profile:

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: profile
spec:
 replicas: 2 # EDIT: Number of instances of deployment
 selector:
   matchLabels:
     app: profile
 template:
   metadata:
     labels:
       app: profile
   spec:
     serviceAccountName: profile-app
     containers:
     - name: profile-service
       image: profile
       ports:
         - containerPort: 80
       envFrom:
         - configMapRef:
             name: spanner-config
       env:
         - name: SERVICE_HOST
           value: "0.0.0.0"
         - name: SERVICE_PORT
           value: "80"
       resources:
         requests:
           cpu: "1"
           memory: "1Gi"
           ephemeral-storage: "100Mi"
         limits:
           cpu: "1"
           memory: "1Gi"
           ephemeral-storage: "100Mi"

La partie supérieure fournit des métadonnées sur le service. L'étape la plus importante consiste à définir le nombre d'instances répliquées qui seront créées par ce déploiement.

replicas: 2 # EDIT: Number of instances of deployment

Nous allons maintenant voir quel compte de service exécuter l'application et quelle image elle doit utiliser. Ils correspondent au compte de service Kubernetes créé à partir de Terraform et à l'image créée lors de l'étape Cloud Build.

spec:
  serviceAccountName: profile-app
  containers:
    - name: profile-service
      image: profile

Nous allons ensuite spécifier des informations sur les variables de mise en réseau et d'environnement.

spanner_config est un objet ConfigMap de Kubernetes qui spécifie les informations de projet, d'instance et de base de données dont l'application a besoin pour se connecter à Spanner.

apiVersion: v1
kind: ConfigMap
metadata:
  name: spanner-config
data:
  SPANNER_PROJECT_ID: ${project_id}
  SPANNER_INSTANCE_ID: ${instance_id}
  SPANNER_DATABASE_ID: ${database_id}
ports:
  - containerPort: 80
envFrom:
  - configMapRef:
    name: spanner-config
env:
  - name: SERVICE_HOST
    value: "0.0.0.0"
  - name: SERVICE_PORT
    value: "80"

SERVICE_HOST et SERVICE_PORT sont des variables d'environnement supplémentaires dont le service a besoin pour savoir où établir une liaison.

La dernière section indique à GKE le nombre de ressources à autoriser pour chaque instance répliquée dans ce déploiement. GKE Autopilot utilise également cette interface pour procéder au scaling du cluster selon les besoins.

resources:
  requests:
    cpu: "1"
    memory: "1Gi"
    ephemeral-storage: "100Mi"
  limits:
    cpu: "1"
    memory: "1Gi"
    ephemeral-storage: "100Mi"

Avec ces informations, il est temps de déployer les services de backend.

Déployer les services de backend

Comme indiqué précédemment, le déploiement des services de backend utilise Cloud Build. Comme pour les migrations de schéma, vous pouvez envoyer la requête de compilation à l'aide de la ligne de commande gcloud:

cd $DEMO_HOME/backend_services
gcloud builds submit --config=cloudbuild.yaml

Résultat de la commande

Creating temporary tarball archive of 66 file(s) totalling 864.6 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/30207dd1-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/30207dd1-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 30207dd1-(snip)
CREATE_TIME: (created time)
DURATION: 3M17S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile:30207dd1-(snip) (+3 more)
STATUS: SUCCESS

Contrairement au résultat de l'étape schema migration, le résultat de cette compilation indique que des images ont été créées. Ceux-ci seront stockés dans votre dépôt Artifact Registry.

Le résultat de l'étape gcloud build sera associé à Cloud Console. Jetons-y un coup d’œil.

Une fois que vous avez reçu la notification de réussite de Cloud Build, accédez à Cloud Deploy, puis au pipeline sample-game-services pour surveiller la progression du déploiement.

df5c6124b9693986.png

Une fois les services déployés, vous pouvez vérifier kubectl pour afficher les état:

kubectl get pods

Résultat de la commande

NAME                           READY   STATUS    RESTARTS   AGE
item-6b9d5f678c-4tbk2          1/1     Running   0          83m
matchmaking-5bcf799b76-lg8zf   1/1     Running   0          80m
profile-565bbf4c65-kphdl       1/1     Running   0          83m
profile-565bbf4c65-xw74j       1/1     Running   0          83m
tradepost-68b87ccd44-gw55r     1/1     Running   0          79m

Vérifiez ensuite les services pour voir ClusterIP en action:

kubectl get services

Résultat de la commande

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
item          ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
kubernetes    ClusterIP   10.172.XXX.XXX   <none>        443/TCP   137m
matchmaking   ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
profile       ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m
tradepost     ClusterIP   10.172.XXX.XXX   <none>        80/TCP    84m

Vous pouvez également accéder à l'interface utilisateur de GKE dans la console Cloud pour afficher Workloads, Services et ConfigMaps.

Charges de travail

da98979ae49e5a30.png

Services

406ca2fe7ad4818b.png

ConfigMaps

a0ebd34ee735ee11.png

3b9ef91c77a4e7f0.png

Résumé

Au cours de cette étape, vous avez déployé les quatre services de backend sur GKE Autopilot. Vous avez pu exécuter l'étape Cloud Build et vérifier la progression dans Cloud Deploy et dans Kubernetes dans la console Cloud.

Vous avez également découvert comment ces services utilisent Workload Identity pour emprunter l'identité d'un compte de service disposant des autorisations appropriées pour lire et écrire des données dans la base de données Spanner.

Étapes suivantes

Dans la section suivante, vous allez déployer les charges de travail.

6. Déployer les charges de travail

Présentation

Maintenant que les services de backend s'exécutent sur le cluster, vous allez déployer les charges de travail.

dd900485e2eeb611.png

Les charges de travail sont accessibles en externe, et il en existe une pour chaque service de backend utilisé dans cet atelier de programmation.

Ces charges de travail sont des scripts de génération de charge basés sur Locust qui imitent les modèles d'accès réels attendus par ces exemples de services.

Il existe des fichiers pour le processus Cloud Build:

  • $DEMO_HOME/workloads/cloudbuild.yaml (généré par Terraform)
  • $DEMO_HOME/workloads/skaffold.yaml
  • Un fichier deployment.yaml pour chaque charge de travail

Les fichiers deployment.yaml de charge de travail diffèrent légèrement des fichiers de déploiement du service de backend.

Voici un exemple issu de matchmaking-workload:

apiVersion: v1
kind: Service
metadata:
 name: matchmaking-workload
spec:
 type: LoadBalancer
 selector:
   app: matchmaking-workload
 ports:
 - port: 8089
   targetPort: 8089
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: matchmaking-workload
spec:
 replicas: 1 # EDIT: Number of instances of deployment
 selector:
   matchLabels:
     app: matchmaking-workload
 template:
   metadata:
     labels:
       app: matchmaking-workload
   spec:
     serviceAccountName: default
     containers:
     - name: matchmaking-workload
       image: matchmaking-workload
       ports:
         - containerPort: 8089
       resources:
         requests:
           cpu: "500m"
           memory: "512Mi"
           ephemeral-storage: "100Mi"
         limits:
           cpu: "500m"
           memory: "512Mi"
           ephemeral-storage: "100Mi"

La partie supérieure du fichier définit le service. Dans ce cas, un objet LoadBalancer est créé et la charge de travail s'exécute sur le port 8089.

L'équilibreur de charge fournit une adresse IP externe qui peut être utilisée pour se connecter à la charge de travail.

apiVersion: v1
kind: Service
metadata:
 name: matchmaking-workload
spec:
 type: LoadBalancer
 selector:
   app: matchmaking-workload
 ports:
 - port: 8089
   targetPort: 8089

Les métadonnées concernant la charge de travail figurent en haut de la section "Déploiement". Dans ce cas, une seule instance répliquée est déployée:

replicas: 1 

La spécification du conteneur est cependant différente. Tout d'abord, nous utilisons un compte de service Kubernetes default. Ce compte ne dispose d'aucun droit spécial, car la charge de travail n'a besoin de se connecter à aucune ressource Google Cloud, à l'exception des services de backend exécutés sur le cluster GKE.

L'autre différence est qu'aucune variable d'environnement n'est nécessaire pour ces charges de travail. Le résultat est une spécification de déploiement plus courte.

spec:
  serviceAccountName: default
  containers:
    - name: matchmaking-workload
      image: matchmaking-workload
  ports:
    - containerPort: 8089

Les paramètres de ressources sont semblables à ceux des services de backend. Rappelez-vous que c'est ainsi que GKE Autopilot détermine le nombre de ressources nécessaires pour satisfaire les requêtes de tous les pods exécutés sur le cluster.

Vous pouvez maintenant déployer les charges de travail.

Déployer les charges de travail

Comme précédemment, vous pouvez envoyer la demande de compilation à l'aide de la ligne de commande gcloud:

cd $DEMO_HOME/workloads
gcloud builds submit --config=cloudbuild.yaml

Résultat de la commande

Creating temporary tarball archive of 18 file(s) totalling 26.2 KiB before compression.
Some files were not included in the source upload.

Check the gcloud log [/tmp/tmp.4Z9EqdPo6d/logs/(snip).log] to see which files and the contents of the
default gcloudignore file used (see `$ gcloud topic gcloudignore` to learn
more).

Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/0daf20f6-(snip)?project=(snip) ].

gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit

ID: 0daf20f6-(snip)
CREATE_TIME: (created_time)
DURATION: 1M41S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile-workload:0daf20f6-(snip) (+4 more)
STATUS: SUCCESS

Pensez à consulter les journaux Cloud Build et le pipeline Cloud Deploy dans la console Cloud pour vérifier l'état. Pour les charges de travail, le pipeline Cloud Deploy est sample-game-workloads:

Une fois le déploiement terminé, vérifiez l'état avec kubectl dans Cloud Shell:

kubectl get pods

Résultat de la commande

NAME                                    READY   STATUS    RESTARTS   AGE
game-workload-7ff44cb657-pxxq2          1/1     Running   0          12m
item-6b9d5f678c-cr29w                   1/1     Running   0          9m6s
item-generator-7bb4f57cf8-5r85b         1/1     Running   0          12m
matchmaking-5bcf799b76-lg8zf            1/1     Running   0          117m
matchmaking-workload-76df69dbdf-jds9z   1/1     Running   0          12m
profile-565bbf4c65-kphdl                1/1     Running   0          121m
profile-565bbf4c65-xw74j                1/1     Running   0          121m
profile-workload-76d6db675b-kzwng       1/1     Running   0          12m
tradepost-68b87ccd44-gw55r              1/1     Running   0          116m
tradepost-workload-56c55445b5-b5822     1/1     Running   0          12m

Vérifiez ensuite les services de charge de travail pour voir LoadBalancer en action:

kubectl get services 

Résultat de la commande

NAME                   TYPE          CLUSTER-IP  EXTERNAL-IP     PORT(S)        AGE
game-workload          LoadBalancer  *snip*      35.XX.XX.XX   8089:32483/TCP   12m
item                   ClusterIP     *snip*      <none>         80/TCP          121m
item-generator         LoadBalancer  *snip*      34.XX.XX.XX   8089:32581/TCP   12m
kubernetes             ClusterIP     *snip*      <none>          443/TCP        174m
matchmaking            ClusterIP     *snip*      <none>          80/TCP         121m
matchmaking-workload   LoadBalancer  *snip*      34.XX.XX.XX   8089:31735/TCP   12m
profile                ClusterIP     *snip*      <none>          80/TCP         121m
profile-workload       LoadBalancer  *snip*      34.XX.XX.XX   8089:32532/TCP   12m
tradepost              ClusterIP     *snip*      <none>          80/TCP         121m
tradepost-workload     LoadBalancer  *snip*      34.XX.XX.XX   8089:30002/TCP   12m

Résumé

Vous avez maintenant déployé les charges de travail sur le cluster GKE. Ces charges de travail ne nécessitent aucune autorisation IAM supplémentaire et sont accessibles en externe via le port 8089 à l'aide du service LoadBalancer.

Étapes suivantes

Les services de backend et les charges de travail étant en cours d'exécution, il est temps de jouer le match !

7. Commencer à jouer

Présentation

Services de backend pour votre exemple de "jeu" sont en cours d'exécution, et vous avez la possibilité de générer des "players" interagissant avec ces services à l'aide des charges de travail.

Chaque charge de travail utilise Locust pour simuler la charge réelle sur nos API de service. Au cours de cette étape, vous allez exécuter plusieurs charges de travail pour générer une charge sur le cluster GKE et sur Spanner, ainsi que pour stocker des données sur Spanner.

Voici une description de chaque charge de travail:

  • La charge de travail item-generator est une charge de travail rapide qui permet de générer une liste d'game_items que les joueurs peuvent acquérir en jouant. le jeu.
  • Le profile-workload simule l'inscription et la connexion des joueurs.
  • Le matchmaking-workload simule la mise en file d'attente des joueurs pour être affectés à des jeux.
  • Le game-workload simule le jeu vidéo.
  • Le tradepost-workload simule la possibilité de vendre et d'acheter des articles au comptoir.

Cet atelier de programmation présente spécifiquement l'exécution de item-generator et de profile-workload.

Exécuter le générateur d'éléments

item-generator utilise le point de terminaison du service de backend item pour ajouter game_items à Spanner. Ces éléments sont nécessaires au bon fonctionnement de game-workload et tradepost-workload.

La première étape consiste à obtenir l'adresse IP externe du service item-generator. Dans Cloud Shell, exécutez la commande ci-dessous.

# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'

Résultat de la commande

{ITEMGENERATOR_EXTERNAL_IP}

Ouvrez maintenant un nouvel onglet du navigateur et faites-le pointer vers http://{ITEMGENERATOR_EXTERNAL_IP}:8089. Vous devriez obtenir une page semblable à celle-ci:

817307157d66c661.png

Vous devez conserver les valeurs par défaut de users et spawn. Pour host, saisissez http://item. Cliquez sur les options avancées, puis saisissez 10s pour la durée d'exécution.

La configuration doit se présenter comme suit:

f3143165c6285c21.png

Cliquez sur "Start swarming" (Démarrer le travail en essaim).

Les statistiques commenceront à s'afficher pour les requêtes émises sur le point de terminaison POST /items. Le chargement s'arrête au bout de 10 secondes.

Cliquez sur Charts pour consulter des graphiques sur les performances de ces requêtes.

abad0a9f3c165345.png

Vous voulez maintenant vérifier si les données sont saisies dans la base de données Spanner.

Pour ce faire, cliquez sur le menu hamburger et accédez à "Spanner". Sur cette page, accédez à sample-instance et à sample-database. Cliquez ensuite sur "Query".

Nous voulons sélectionner le nombre de game_items:

SELECT COUNT(*) FROM game_items;

Le résultat s'affiche en bas de l'écran.

137ce291a2ff2706.png

Nous n'avons pas besoin des têtes de série game_items. Mais les joueurs peuvent désormais les acquérir !

Exécuter profile-workload

Maintenant que vous avez sélectionné game_items, vous devez inciter les joueurs à s'inscrire pour jouer.

Le profile-workload utilisera Locust pour simuler la création de comptes, la connexion, l'extraction d'informations de profil et la déconnexion des joueurs. Tous ces éléments testent les points de terminaison du service de backend profile dans une charge de travail classique de type production.

Pour l'exécuter, obtenez l'adresse IP externe de profile-workload:

# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'

Résultat de la commande

{PROFILEWORKLOAD_EXTERNAL_IP}

Ouvrez maintenant un nouvel onglet du navigateur et faites-le pointer vers http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089. Vous devriez obtenir une page Locust semblable à la précédente.

Dans ce cas, vous utiliserez http://profile comme hôte. Vous n'aurez pas non plus à spécifier d'environnement d'exécution dans les options avancées. Indiquez également users sur 4, ce qui simulera quatre requêtes utilisateur à la fois.

Le test profile-workload doit se présenter comme suit:

f6e0f06efb0ad6e.png

Cliquez sur "Start swarming" (Démarrer le travail en essaim).

Comme précédemment, les statistiques des différents points de terminaison REST profile commenceront à s'afficher. Cliquez sur les graphiques pour afficher une vue d'ensemble de vos performances.

4c2146e1cb3de23e.png

Résumé

Au cours de cette étape, vous avez généré des game_items, puis interrogé la table game_items à l'aide de l'interface utilisateur de requête Spanner dans Cloud Console.

Vous avez également autorisé les joueurs à s'inscrire à votre jeu et découvert comment Locust pouvait créer des charges de travail de type production sur vos services de backend.

Étapes suivantes

Après avoir exécuté les charges de travail, vous devez vérifier le comportement du cluster GKE et de l'instance Spanner.

8. Examiner l'utilisation de GKE et Spanner

Maintenant que le service de profil est en cours d'exécution, il est temps d'en profiter pour examiner le comportement de votre cluster GKE Autopilot et de Cloud Spanner.

Vérifier l'état du cluster GKE

Accédez au cluster Kubernetes. Notez que, puisque vous avez déployé les charges de travail et les services, des informations sur le nombre total de vCPU et la mémoire ont été ajoutées au cluster. Ces informations n'étaient pas disponibles lorsque le cluster ne comporte aucune charge de travail.

61d2d766c1f10079.png

Cliquez maintenant sur le cluster sample-game-gke et accédez à l'onglet "Observabilité" :

fa9acc7e26ea04a.png

L'espace de noms Kubernetes default devrait avoir dépassé l'espace de noms kube-system pour l'utilisation du processeur, car nos charges de travail et services de backend s'exécutent sur default. Si ce n'est pas le cas, assurez-vous que profile workload est toujours en cours d'exécution et attendez quelques minutes que les graphiques soient mis à jour.

Pour savoir quelles charges de travail utilisent le plus de ressources, accédez au tableau de bord Workloads.

Au lieu d'examiner chaque charge de travail individuellement, accédez directement à l'onglet "Observabilité" du tableau de bord. Vous devriez constater que le processeur profile et profile-workload a augmenté.

f194b618969cfa9e.png

Vous allez maintenant vérifier l'état de Cloud Spanner.

Vérifier l'instance Cloud Spanner

Pour vérifier les performances de Cloud Spanner, accédez à Spanner, puis cliquez sur l'instance sample-instance et la base de données sample-game.

Vous verrez alors l'onglet System Insights (Insights système) dans le menu de gauche:

216212182a57dfd1.png

De nombreux graphiques sont disponibles pour vous aider à comprendre les performances générales de votre instance Spanner, y compris CPU utilization, transaction latency and locking et query throughput.

En plus des insights système, vous pouvez obtenir des informations plus détaillées sur la charge de travail de requête en consultant les autres liens de la section "Observabilité" :

  • Les insights sur les requêtes permettent d'identifier les requêtes topN qui utilisent des ressources sur Spanner.
  • Les insights sur les transactions et les verrouillages permettent d'identifier les transactions présentant des latences élevées.
  • Key Visualizer permet de visualiser les modèles d'accès et de dépister les hotspots dans les données.

Résumé

Au cours de cette étape, vous avez appris à vérifier certaines métriques de performances de base pour GKE Autopilot et Spanner.

Par exemple, pendant que votre charge de travail de profil est en cours d'exécution, interrogez la table players pour obtenir plus d'informations sur les données qui y sont stockées.

Étapes suivantes

Il est maintenant temps de faire le ménage !

9. Nettoyer

Avant de procéder au nettoyage, n'hésitez pas à explorer les autres charges de travail qui n'ont pas été abordées. Plus précisément, matchmaking-workload, game-workload et tradepost-workload.

Lorsque vous avez fini de jouer vous pouvez nettoyer votre terrain de jeu. Heureusement, c’est assez facile.

Tout d'abord, si votre profile-workload est toujours en cours d'exécution dans le navigateur, allez-y et arrêtez-le:

13ae755a11f3228.png

Répétez l'opération pour chaque charge de travail que vous avez peut-être testée.

Ensuite, dans Cloud Shell, accédez au dossier de l'infrastructure. Vous allez destroy l'infrastructure à l'aide de Terraform:

cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked

Résultat de la commande

Plan: 0 to add, 0 to change, 46 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

*snip*

Destroy complete! Resources: 46 destroyed.

Dans la console Cloud, accédez à Spanner, Kubernetes Cluster, Artifact Registry, Cloud Deploy et IAM pour vérifier que toutes les ressources ont bien été supprimées.

10. Félicitations !

Félicitations ! Vous avez déployé des exemples d'applications golang sur GKE Autopilot et les avez connectés à Cloud Spanner à l'aide de Workload Identity.

De plus, cette infrastructure a été facile à configurer et à supprimer de manière reproductible à l'aide de Terraform.

Pour en savoir plus sur les services Google Cloud avec lesquels vous avez interagi dans cet atelier de programmation:

Étape suivante

Maintenant que vous comprenez les bases de la synergie entre GKE Autopilot et Cloud Spanner, pourquoi ne pas passer à l'étape suivante et commencer à créer votre propre application compatible avec ces services ?