1. Introduzione
Cloud Spanner è un servizio di database relazionale completamente gestito, scalabile orizzontalmente e distribuito a livello globale che fornisce transazioni ACID e semantica SQL senza rinunciare a prestazioni e disponibilità elevata.
GKE Autopilot è una modalità operativa di GKE in cui Google gestisce la configurazione del cluster, inclusi nodi, scalabilità, sicurezza e altre impostazioni preconfigurate in base alle best practice. Ad esempio, GKE Autopilot abilita Workload Identity per gestire le autorizzazioni del servizio.
L'obiettivo di questo lab è guidarti attraverso il processo per connettere diversi servizi di backend in esecuzione su GKE Autopilot a un database Cloud Spanner.
In questo lab, configurerai innanzitutto un progetto e avvierai Cloud Shell. Quindi eseguirai il deployment dell'infrastruttura utilizzando Terraform.
Al termine, interagirai con Cloud Build e Cloud Deploy per eseguire una migrazione iniziale dello schema per il database dei giochi, eseguire il deployment dei servizi di backend e quindi del deployment dei carichi di lavoro.
I servizi in questo codelab sono gli stessi del codelab Introduzione allo sviluppo di giochi di Cloud Spanner. Seguire questo codelab non è un requisito per eseguire i servizi su GKE e stabilire la connessione a Spanner. Ma se vuoi saperne di più sulle specifiche di questi servizi che funzionano su Spanner, dai un'occhiata.
Con i carichi di lavoro e i servizi di backend in esecuzione, puoi iniziare a generare carico e osservare come i servizi funzionano insieme.
Infine, eseguirai la pulizia delle risorse create in questo lab.
Cosa creerai
Nell'ambito di questo lab imparerai a:
- Eseguire il provisioning dell'infrastruttura utilizzando Terraform
- Crea lo schema del database utilizzando un processo di migrazione degli schemi in Cloud Build
- Esegui il deployment dei quattro servizi di backend Golang che utilizzano Workload Identity per la connessione a Cloud Spanner
- Esegui il deployment dei quattro servizi dei carichi di lavoro utilizzati per simulare il carico dei servizi di backend.
Cosa imparerai a fare
- Come eseguire il provisioning di pipeline GKE Autopilot, Cloud Spanner e Cloud Deploy utilizzando Terraform
- Come Workload Identity consente ai servizi su GKE di impersonare gli account di servizio per accedere alle autorizzazioni IAM per lavorare con Cloud Spanner
- Come generare un carico di tipo produzione su GKE e Cloud Spanner utilizzando Locust.io
Che cosa ti serve
2. Configurazione e requisiti
Creare un progetto
Se non disponi già di un account Google (Gmail o Google Apps), devi crearne uno. Accedi alla console della piattaforma Google Cloud ( console.cloud.google.com) e crea un nuovo progetto.
Se hai già un progetto, fai clic sul menu a discesa per la selezione del progetto in alto a sinistra nella console:
e fai clic su "NUOVO PROGETTO" nella finestra di dialogo risultante per creare un nuovo progetto:
Se non hai ancora un progetto, dovresti visualizzare una finestra di dialogo come questa per crearne uno:
La finestra di dialogo di creazione del progetto successiva ti consente di inserire i dettagli del nuovo progetto:
Ricorda l'ID progetto, che è un nome univoco tra tutti i progetti Google Cloud (il nome precedente è già in uso e non funzionerà per te). Verrà indicato più avanti in questo codelab come PROJECT_ID
.
Successivamente, se non l'hai ancora fatto, dovrai abilitare la fatturazione in Developers Console per utilizzare le risorse Google Cloud e abilitare l'API Cloud Spanner.
L'esecuzione di questo codelab non dovrebbe costare più di qualche euro, ma potrebbe essere più costoso se decidi di utilizzare più risorse o se le lasci in esecuzione (consulta la sezione relativa alla pulizia alla fine di questo documento). I prezzi di Google Cloud Spanner sono documentati qui, mentre GKE Autopilot è documentato qui.
I nuovi utenti di Google Cloud Platform hanno diritto a una prova senza costi di 300$, che dovrebbe rendere questo codelab completamente senza costi.
Configurazione di Cloud Shell
Mentre Google Cloud e Spanner possono essere gestiti da remoto dal tuo laptop, in questo codelab utilizzeremo Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.
Questa macchina virtuale basata su Debian viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Ciò significa che per questo codelab sarà sufficiente un browser (sì, funziona su Chromebook).
- Per attivare Cloud Shell dalla console Cloud, fai clic su Attiva Cloud Shell (il provisioning e la connessione all'ambiente dovrebbero richiedere solo pochi minuti).
Una volta stabilita la connessione a Cloud Shell, dovresti vedere che hai già eseguito l'autenticazione e che il progetto è già impostato su PROJECT_ID
.
gcloud auth list
Output comando
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
Output comando
[core]
project = <PROJECT_ID>
Se, per qualche motivo, il progetto non è impostato, invia semplicemente il seguente comando:
gcloud config set project <PROJECT_ID>
Stai cercando il tuo PROJECT_ID
? Controlla l'ID utilizzato nei passaggi di configurazione o cercalo nella dashboard della console Cloud:
Cloud Shell imposta anche alcune variabili di ambiente per impostazione predefinita, cosa che può essere utile quando eseguirai comandi futuri.
echo $GOOGLE_CLOUD_PROJECT
Output comando
<PROJECT_ID>
Scarica il codice
In Cloud Shell puoi scaricare il codice per questo lab:
git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git
Output comando
Cloning into 'spanner-gaming-sample'...
*snip*
Questo codelab è basato sulla release v0.1.3, quindi dai un'occhiata al 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
Output comando
Switched to a new branch 'v0.1.3-branch'
Ora imposta la directory di lavoro attuale come variabile di ambiente DEMO_HOME. In questo modo sarà più facile navigare mentre lavori tra le diverse parti del codelab.
export DEMO_HOME=$(pwd)
Riepilogo
In questo passaggio hai configurato un nuovo progetto, attivato Cloud Shell e scaricato il codice per il lab.
Successivo
Successivamente, eseguirai il provisioning dell'infrastruttura utilizzando Terraform.
3. Esegui il provisioning dell'infrastruttura
Panoramica
Con il tuo progetto pronto, è il momento di avviare l'infrastruttura. Sono inclusi il networking VPC, Cloud Spanner, GKE Autopilot, Artifact Registry per archiviare le immagini che verranno eseguite su GKE, le pipeline Cloud Deploy per i servizi e i carichi di lavoro di backend e, infine, gli account di servizio e i privilegi IAM per essere in grado di utilizzare questi servizi.
Niente male. Fortunatamente, però, Terraform può semplificare la configurazione. Terraform è una soluzione "Infrastructure as Code" che ci permette di specificare ciò di cui abbiamo bisogno per questo progetto in una serie di file ".tf" . Questo semplifica il provisioning dell'infrastruttura.
Conoscere Terraform non è un requisito per completare questo codelab. Tuttavia, se vuoi sapere cosa fanno i prossimi passaggi, puoi dare un'occhiata a cosa viene creato in questi file che si trovano nella directory infrastructure:
- vpc.tf
- backend_gke.tf
- spanner.tf
- artifact_registry.tf
- pipelines.tf
- iam.tf
Configura Terraform
In Cloud Shell, passerai alla directory infrastructure
e inizializzerai Terraform:
cd $DEMO_HOME/infrastructure
terraform init
Output comando
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.
A questo punto, configura Terraform copiando terraform.tfvars.sample
e modificando il valore del progetto. Anche le altre variabili possono essere modificate, ma il progetto è l'unico che deve essere modificato per funzionare con il tuo ambiente.
cp terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars
Esegui il provisioning dell'infrastruttura
Ora è il momento di eseguire il provisioning dell'infrastruttura.
terraform apply
# review the list of things to be created
# type 'yes' when asked
Output comando
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.
Verificare che cosa è stato creato
Per verificare cosa è stato creato, vuoi controllare i prodotti nella console Cloud.
Cloud Spanner
Per prima cosa, controlla Cloud Spanner andando al menu a tre linee e facendo clic su Spanner
. Potresti dover fare clic su "Visualizza altri prodotti" per trovarlo nell'elenco.
Verrà visualizzato l'elenco delle istanze Spanner. Fai clic sull'istanza per visualizzare i database. Il sito dovrebbe avere il seguente aspetto:
GKE Autopilot
Poi, dai un'occhiata a GKE andando al menu a tre linee e facendo clic su Kubernetes Engine => Clusters
. Qui vedrai il cluster sample-games-gke
in esecuzione in modalità Autopilot.
Artifact Registry
Ora vuoi vedere dove vengono archiviate le immagini. Fai clic sul menu a tre linee e trova Artifact Registry=>Repositories
. Artifact Registry si trova nella sezione CI/CD del menu.
Qui vedrai un registro Docker denominato spanner-game-images
. Per il momento è vuoto.
Cloud Deploy
Cloud Deploy è il luogo in cui sono state create le pipeline in modo che Cloud Build possa fornire i passaggi per creare le immagini e per eseguirne il deployment nel nostro cluster GKE.
Vai al menu a tre linee e trova Cloud Deploy
, anch'esso disponibile nella sezione CI/CD del menu.
Qui noterai due pipeline: una per i servizi di backend e una per i carichi di lavoro. Entrambi eseguono il deployment delle immagini sullo stesso cluster GKE, ma questo consente di separare i nostri deployment.
IAM
Infine, controlla la pagina IAM nella console Cloud per verificare gli account di servizio creati. Vai al menu a tre linee e trova IAM and Admin=>Service accounts
. Il sito dovrebbe avere il seguente aspetto:
Terraform crea in totale sei account di servizio:
- L'account di servizio predefinito del computer. Non viene usato in questo codelab.
- L'account cloudbuild-cicd viene utilizzato per i passaggi di Cloud Build e Cloud Deploy.
- Quattro "app" utilizzati dai nostri servizi di backend per interagire con Cloud Spanner.
Successivamente devi configurare kubectl
per interagire con il cluster GKE.
Configura 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
Output comando
#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
Riepilogo
Bene. Hai potuto eseguire il provisioning di un'istanza Cloud Spanner, un cluster GKE Autopilot, il tutto in un VPC per il networking privato.
Inoltre, sono state create due pipeline Cloud Deploy per i servizi di backend e i carichi di lavoro, nonché un repository Artifact Registry per archiviare le immagini create.
Infine, gli account di servizio sono stati creati e configurati in modo da funzionare con Workload Identity in modo che i servizi di backend possano utilizzare Cloud Spanner.
Hai inoltre configurato kubectl
per interagire con il cluster GKE in Cloud Shell dopo aver eseguito il deployment dei carichi di lavoro e dei servizi di backend.
Successivo
Prima di poter utilizzare i servizi, è necessario definire lo schema del database. Lo configurerai successivamente.
4. Crea lo schema del database
Panoramica
Prima di poter eseguire i servizi di backend, devi assicurarti che sia attivo lo schema del database.
Se osservi i file nella directory $DEMO_HOME/schema/migrations
del repository della demo, vedrai una serie di file .sql
che definiscono il nostro schema. Questo imita un ciclo di sviluppo in cui le modifiche allo schema vengono monitorate nel repository stesso e possono essere collegate a determinate funzionalità delle applicazioni.
Per questo ambiente di esempio, chiave inglese è lo strumento che applicherà le nostre migrazioni degli schemi utilizzando Cloud Build.
Cloud Build
Il file $DEMO_HOME/schema/cloudbuild.yaml
descrive i passaggi che verranno effettuati:
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
Essenzialmente composta da due passaggi:
- scarica la chiave inglese nell'area di lavoro di Cloud Build
- esegui la migrazione della chiave inglese
Le variabili di ambiente del database, dell'istanza e del progetto Spanner sono necessarie affinché la chiave inglese si connetta all'endpoint di scrittura.
Cloud Build è in grado di apportare queste modifiche perché è in esecuzione con l'account di servizio cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
Inoltre, a questo account di servizio è stato aggiunto il ruolo spanner.databaseUser
, che consente all'account di servizio di aggiornare DDL.
Migrazioni di schemi
Esistono cinque passaggi di migrazione che vengono eseguiti in base ai file presenti nella directory $DEMO_HOME/schema/migrations
. Ecco un esempio del file 000001.sql
che crea una tabella players
e gli indici:
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);
Invia la migrazione dello schema
Per inviare la build per eseguire la migrazione dello schema, passa alla directory schema
ed esegui questo comando gcloud:
cd $DEMO_HOME/schema gcloud builds submit --config=cloudbuild.yaml
Output comando
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
Nell'output riportato sopra, noterai un link al processo di Cloud Build Created
. Se fai clic sul pulsante, si aprirà la build nella console Cloud, in modo da poter monitorare l'avanzamento della build e vedere cosa sta facendo.
Riepilogo
In questo passaggio, hai utilizzato Cloud Build per inviare la migrazione iniziale dello schema con 5 diverse operazioni DDL. Queste operazioni indicano quando sono state aggiunte funzionalità che hanno richiesto modifiche allo schema del database.
In un normale scenario di sviluppo, conviene apportare modifiche allo schema compatibili con le versioni precedenti dell'applicazione per evitare interruzioni.
Per le modifiche non compatibili con le versioni precedenti, ti consigliamo di eseguire il deployment delle modifiche all'applicazione e allo schema in fasi per evitare interruzioni.
Successivo
Una volta impostato lo schema, il passaggio successivo è il deployment dei servizi di backend.
5. Esegui il deployment dei servizi di backend
Panoramica
I servizi di backend per questo codelab sono API REST golang che rappresentano quattro diversi servizi:
- Profilo: offre ai giocatori la possibilità di registrarsi e autenticarsi al nostro "gioco di esempio".
- Abbinamento: consente di interagire con i dati dei giocatori per semplificare la ricerca degli abbinamenti, tenere traccia delle informazioni sulle partite create e aggiornare le statistiche dei giocatori quando le partite sono chiuse.
- Elemento: consente ai giocatori di acquisire oggetti e denaro del gioco durante il gioco.
- Tradepost::consente ai giocatori di acquistare e vendere articoli su una piattaforma commerciale.
Scopri di più su questi servizi nel codelab Introduzione allo sviluppo di giochi di Cloud Spanner. Per i nostri scopi, vogliamo che questi servizi siano in esecuzione sul nostro cluster GKE Autopilot.
Questi servizi devono essere in grado di modificare i dati Spanner. Per farlo, ogni servizio ha un account di servizio che gli concede il ruolo "databaseUser" ruolo.
Workload Identity consente a un account di servizio Kubernetes di simulare l'identità dei servizi Google Cloud seguendo i passaggi nel nostro Terraform:
- Crea la risorsa dell'account di servizio Google Cloud (
GSA
) del servizio - Assegnare il ruolo databaseUser a quell'account di servizio.
- Assegnare il ruolo workloadIdentityUser a quell'account di servizio
- Crea un account di servizio Kubernetes (
KSA
) che fa riferimento a Gboard
Un diagramma approssimativo sarebbe simile al seguente:
Terraform ha creato gli account di servizio e gli account di servizio Kubernetes per te. Infine, puoi controllare gli account di servizio Kubernetes utilizzando 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
Ecco il funzionamento della build:
- Terraform ha generato un file
$DEMO_HOME/backend_services/cloudbuild.yaml
simile al seguente:
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
- Il comando Cloud Build legge questo file e segue i passaggi elencati. Innanzitutto, crea le immagini del servizio. quindi esegue un comando
gcloud deploy create
. Legge il file$DEMO_HOME/backend_services/skaffold.yaml
, che definisce la posizione di ciascun file di deployment:
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 seguirà le definizioni del file
deployment.yaml
di ogni servizio. Il file di deployment del servizio contiene le informazioni per la creazione di un servizio, che in questo caso è un clusterIP in esecuzione sulla porta 80.
Il " Il tipo ClusterIP" impedisce ai pod del servizio di backend di avere un IP esterno, in modo che solo le entità che possono connettersi alla rete GKE interna possano accedere ai servizi di backend. Questi servizi non dovrebbero essere accessibili direttamente ai giocatori perché accedono e modificano i dati di Spanner.
apiVersion: v1
kind: Service
metadata:
name: profile
spec:
type: ClusterIP
selector:
app: profile
ports:
- port: 80
targetPort: 80
Oltre a creare un servizio Kubernetes, Cloud Deploy crea anche un deployment Kubernetes. Esaminiamo la sezione relativa al deployment del servizio 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 parte superiore fornisce alcuni metadati sul servizio. La parte più importante di questo processo è la definizione del numero di repliche che saranno create da questo deployment.
replicas: 2 # EDIT: Number of instances of deployment
Ora vediamo quale account di servizio deve eseguire l'app e quale immagine utilizzare. Queste corrispondono all'account di servizio Kubernetes creato da Terraform e all'immagine creata durante il passaggio di Cloud Build.
spec:
serviceAccountName: profile-app
containers:
- name: profile-service
image: profile
Successivamente, specificheremo alcune informazioni sulle variabili di networking e di ambiente.
spanner_config
è un ConfigMap Kubernetes che specifica le informazioni su progetto, istanza e database necessarie all'applicazione per la connessione a 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
e SERVICE_PORT
sono variabili di ambiente aggiuntive necessarie al servizio per sapere dove eseguire l'associazione.
La sezione finale indica a GKE quante risorse consentire per ogni replica in questo deployment. Questo è anche ciò che viene utilizzato da GKE Autopilot per scalare il cluster in base alle esigenze.
resources:
requests:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
Con queste informazioni, è il momento di eseguire il deployment dei servizi di backend.
Esegui il deployment dei servizi di backend
Come accennato, il deployment dei servizi di backend utilizza Cloud Build. Proprio come per le migrazioni degli schemi, puoi inviare la richiesta di build utilizzando la riga di comando gcloud:
cd $DEMO_HOME/backend_services gcloud builds submit --config=cloudbuild.yaml
Output comando
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
A differenza dell'output del passaggio schema migration
, l'output di questa build indica che sono state create alcune immagini. Verranno archiviate nel tuo repository Artifact Registry.
L'output del passaggio gcloud build
avrà un collegamento alla console Cloud. Dai un'occhiata a questi.
Quando ricevi la notifica di esito positivo da Cloud Build, vai a Cloud Deploy, quindi alla pipeline sample-game-services
per monitorare l'avanzamento del deployment.
Una volta eseguito il deployment dei servizi, puoi controllare kubectl
per vedere i pod stato:
kubectl get pods
Output comando
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
Poi controlla i servizi per vedere ClusterIP
in azione:
kubectl get services
Output comando
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
Puoi anche andare alla UI di GKE nella console Cloud per vedere Workloads
, Services
e ConfigMaps
.
Carichi di lavoro
Servizi
ConfigMap
Riepilogo
In questo passaggio hai eseguito il deployment dei quattro servizi di backend in GKE Autopilot. Hai eseguito il passaggio Cloud Build e controllare lo stato di avanzamento in Cloud Deploy e su Kubernetes nella console Cloud.
Hai anche imparato come questi servizi utilizzano Workload Identity per impersonare un account di servizio che dispone delle autorizzazioni appropriate per leggere e scrivere dati nel database Spanner.
Passaggi successivi
Nella sezione successiva, eseguirai il deployment dei carichi di lavoro.
6. Esegui il deployment dei carichi di lavoro
Panoramica
Ora che i servizi di backend sono in esecuzione sul cluster, eseguirai il deployment dei carichi di lavoro.
I carichi di lavoro sono accessibili dall'esterno e ne esiste uno per ogni servizio di backend ai fini di questo codelab.
Questi carichi di lavoro sono script di generazione del carico basati su Locust che imitano i pattern di accesso reali previsti da questi servizi di esempio.
Sono presenti file per il processo di Cloud Build:
$DEMO_HOME/workloads/cloudbuild.yaml
(generato da Terraform)$DEMO_HOME/workloads/skaffold.yaml
- un file
deployment.yaml
per ogni carico di lavoro
I file deployment.yaml
del carico di lavoro hanno un aspetto leggermente diverso dai file di deployment del servizio di backend.
Ecco un esempio tratto dalla 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 parte superiore del file definisce il servizio. In questo caso, viene creato un LoadBalancer
e il carico di lavoro viene eseguito sulla porta 8089
.
LoadBalancer fornisce un IP esterno che può essere utilizzato per la connessione al carico di lavoro.
apiVersion: v1
kind: Service
metadata:
name: matchmaking-workload
spec:
type: LoadBalancer
selector:
app: matchmaking-workload
ports:
- port: 8089
targetPort: 8089
Nella parte superiore della sezione relativa al deployment si trovano i metadati relativi al carico di lavoro. In questo caso, viene eseguito il deployment di una sola replica:
replicas: 1
Tuttavia, le specifiche del container sono diverse. Per prima cosa, utilizziamo un account di servizio Kubernetes default
. Questo account non dispone di privilegi speciali, poiché il carico di lavoro non deve connettersi a nessuna risorsa Google Cloud, ad eccezione dei servizi di backend in esecuzione sul cluster GKE.
L'altra differenza è che non sono necessarie variabili di ambiente per questi carichi di lavoro. Il risultato è una specifica del deployment più breve.
spec:
serviceAccountName: default
containers:
- name: matchmaking-workload
image: matchmaking-workload
ports:
- containerPort: 8089
Le impostazioni delle risorse sono simili a quelle dei servizi di backend. Ricorda che è così che GKE Autopilot sa quante risorse sono necessarie per soddisfare le richieste di tutti i pod in esecuzione sul cluster.
Procedi con il deployment dei carichi di lavoro.
Esegui il deployment dei carichi di lavoro
Come in precedenza, puoi inviare la richiesta di build utilizzando la riga di comando gcloud:
cd $DEMO_HOME/workloads gcloud builds submit --config=cloudbuild.yaml
Output comando
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
Assicurati di controllare i log di Cloud Build e la pipeline di Cloud Deploy nella console Cloud per verificare lo stato. Per i carichi di lavoro, la pipeline di Cloud Deploy è sample-game-workloads
:
Al termine del deployment, controlla lo stato con kubectl
in Cloud Shell:
kubectl get pods
Output comando
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
Quindi, controlla i servizi del carico di lavoro per vedere LoadBalancer
in azione:
kubectl get services
Output comando
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
Riepilogo
A questo punto hai eseguito il deployment dei carichi di lavoro nel cluster GKE. Questi carichi di lavoro non richiedono autorizzazioni IAM aggiuntive e sono accessibili dall'esterno sulla porta 8089 mediante il servizio LoadBalancer.
Passaggi successivi
Con i servizi di backend e i carichi di lavoro in esecuzione, è il momento di "giocare" il gioco!
7. Inizia a giocare
Panoramica
I servizi di backend per il tuo "gioco" di esempio che ora sono in esecuzione e hai anche la possibilità di generare "player" a interagire con questi servizi utilizzando i carichi di lavoro.
Ogni carico di lavoro utilizza Locust per simulare il carico effettivo sulle nostre API di servizio. In questo passaggio, eseguirai diversi carichi di lavoro per generare carico sul cluster GKE e su Spanner, nonché per archiviare i dati su Spanner.
Di seguito è riportata una descrizione di ciascun carico di lavoro:
- Il carico di lavoro
item-generator
è un carico di lavoro rapido per generare un elenco di game_items che i giocatori possono acquisire durante il gioco al gioco. - Il
profile-workload
simula i giocatori che si registrano e accedono. - L'
matchmaking-workload
simula i giocatori in coda per essere assegnati ai giochi. - L'
game-workload
simula i giocatori che acquistano game_items e denaro nel corso del gioco. - La
tradepost-workload
simula la possibilità dei giocatori di vendere e acquistare articoli sul trading post.
Questo codelab evidenzia l'esecuzione specifica di item-generator
e profile-workload
.
Esegui il generatore di articoli
item-generator
utilizza l'endpoint del servizio di backend item
per aggiungere game_items
a Spanner. Questi elementi sono necessari affinché game-workload
e tradepost-workload
funzionino correttamente.
Il primo passaggio consiste nel ottenere l'IP esterno del servizio item-generator
. In Cloud Shell, esegui questo comando:
# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'
Output comando
{ITEMGENERATOR_EXTERNAL_IP}
Ora apri una nuova scheda del browser e posiziona il puntatore del mouse su http://{ITEMGENERATOR_EXTERNAL_IP}:8089
. Dovrebbe essere visualizzata una pagina simile alla seguente:
Lascerai il valore predefinito 1 per users
e spawn
. Per host
, inserisci http://item
. Fai clic sulle opzioni avanzate e inserisci 10s
per il tempo di esecuzione.
Ecco come dovrebbe apparire la configurazione:
Fai clic su "Inizia a sciamare".
Le statistiche inizieranno a essere visualizzate per le richieste inviate sull'endpoint POST /items
. Dopo 10 secondi il caricamento verrà arrestato.
Fai clic sulla Charts
per visualizzare alcuni grafici sul rendimento di queste richieste.
Ora devi verificare se i dati sono stati inseriti nel database Spanner.
Per farlo, fai clic sul menu a tre linee e vai a "Spanner". Da questa pagina, vai al sample-instance
e al sample-database
. Quindi, fai clic su "Query
".
Vogliamo selezionare il numero di game_items
:
SELECT COUNT(*) FROM game_items;
In basso vedrai il risultato.
Non abbiamo bisogno di molte teste di serie di game_items
. Ma ora sono disponibili per l'acquisizione dei giocatori!
Esegui il carico di lavoro del profilo
Con il tuo seed di game_items
, il passo successivo è far registrare i giocatori per poter giocare.
profile-workload
userà Locust per simulare i giocatori che creano account, accedono, recuperano le informazioni del profilo e si disconnettono. Tutti questi testano gli endpoint del servizio di backend profile
in un tipico carico di lavoro di tipo produzione.
Per eseguirlo, ottieni l'IP esterno di profile-workload
:
# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'
Output comando
{PROFILEWORKLOAD_EXTERNAL_IP}
Ora apri una nuova scheda del browser e posiziona il puntatore del mouse su http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089
. Dovrebbe essere visualizzata una pagina Locust simile a quella precedente.
In questo caso, utilizzerai http://profile
per l'host. Inoltre, non specificherai un runtime nelle opzioni avanzate. Inoltre, specifica un valore per users
, in modo da simulare quattro richieste dell'utente alla volta.
Il test profile-workload
dovrebbe avere il seguente aspetto:
Fai clic su "Inizia a sciamare".
Come in precedenza, inizieranno a essere visualizzate le statistiche per i vari endpoint REST di profile
. Fai clic sui grafici per visualizzare il rendimento di tutti gli elementi.
Riepilogo
In questo passaggio hai generato game_items
e quindi hai eseguito una query sulla tabella game_items
utilizzando l'interfaccia utente di query di Spanner nella console Cloud.
Hai anche consentito ai giocatori di registrarsi al tuo gioco e hai visto in che modo Locust è in grado di creare carichi di lavoro simili a quelli di produzione con i tuoi servizi di backend.
Passaggi successivi
Dopo aver eseguito i carichi di lavoro, vorrai verificare come si comportano il cluster GKE e l'istanza Spanner.
8. Rivedi l'utilizzo di GKE e Spanner
Con il servizio di profilo in esecuzione, è il momento di cogliere l'opportunità di vedere come si comportano il tuo cluster GKE Autopilot e Cloud Spanner.
Controlla il cluster GKE
Accedi al cluster Kubernetes. Tieni presente che, dal momento che hai eseguito il deployment dei carichi di lavoro e dei servizi, nel cluster sono stati aggiunti alcuni dettagli sulle vCPU e sulla memoria totali. Queste informazioni non erano disponibili quando non c'erano carichi di lavoro sul cluster.
Ora, fai clic sul cluster sample-game-gke
e passa alla scheda Osservabilità:
Lo spazio dei nomi Kubernetes default
dovrebbe aver superato lo spazio dei nomi kube-system
per l'utilizzo della CPU, poiché i nostri carichi di lavoro e servizi di backend vengono eseguiti su default
. In caso contrario, assicurati che profile workload
sia ancora in esecuzione e attendi alcuni minuti per l'aggiornamento dei grafici.
Per vedere quali carichi di lavoro utilizzano il maggior numero di risorse, vai alla dashboard Workloads
.
Anziché andare direttamente in ogni carico di lavoro, vai direttamente alla scheda Osservabilità della dashboard. Dovresti vedere che le CPU profile
e profile-workload
sono aumentate.
Ora controlla Cloud Spanner.
Controlla l'istanza Cloud Spanner
Per verificare le prestazioni di Cloud Spanner, vai a Spanner e fai clic sull'istanza sample-instance
e sul database sample-game
.
Da qui, nel menu a sinistra vedrai una scheda Approfondimenti sul sistema:
Qui sono presenti molti grafici per aiutarti a comprendere le prestazioni generali della tua istanza Spanner, tra cui CPU utilization
, transaction latency and locking
e query throughput
.
Oltre ad Insight sul sistema, puoi ottenere informazioni più dettagliate sul carico di lavoro delle query cercando gli altri link nella sezione Osservabilità:
- Query Insights consente di identificare le query principali che utilizzano risorse su Spanner.
- Gli approfondimenti su Transaction e Lock aiutano a identificare le transazioni con latenze elevate.
- Key Visualizer aiuta a visualizzare i pattern di accesso e a rintracciare gli hotspot nei dati.
Riepilogo
In questo passaggio hai imparato a controllare alcune metriche delle prestazioni di base sia per GKE Autopilot che per Spanner.
Ad esempio, con il carico di lavoro del profilo in esecuzione, esegui una query sulla tabella dei player per ottenere ulteriori informazioni sui dati che vengono archiviati al suo interno.
Passaggi successivi
È il momento di pulire.
9. esegui la pulizia
Prima di eseguire la pulizia, esplora liberamente gli altri carichi di lavoro non coperti. Nello specifico, matchmaking-workload
, game-workload
e tradepost-workload
.
Quando hai finito di "giocare" al gioco, puoi ripulire il tuo parco giochi. Per fortuna è abbastanza facile.
Innanzitutto, se il tuo profile-workload
è ancora in esecuzione nel browser, controllalo e interrompilo:
Ripeti l'operazione per ogni carico di lavoro che potresti aver testato.
Quindi, in Cloud Shell, vai alla cartella dell'infrastruttura. Dovrai destroy
usare Terraform:
cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked
Output comando
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.
Nella console Cloud, vai a Spanner
, Kubernetes Cluster
, Artifact Registry
, Cloud Deploy
e IAM
per verificare che tutte le risorse siano state rimosse.
10. Complimenti!
Complimenti, hai eseguito correttamente il deployment delle applicazioni golang di esempio su GKE Autopilot e le hai connesse a Cloud Spanner utilizzando Workload Identity.
Inoltre, questa infrastruttura è stata facilmente configurata e rimossa in modo ripetibile utilizzando Terraform.
Puoi scoprire di più sui servizi Google Cloud con cui hai interagito in questo codelab:
Passaggi successivi
Ora che hai una conoscenza di base di come GKE Autopilot e Cloud Spanner possono funzionare insieme, perché non fare il passo successivo e iniziare a creare la tua applicazione per funzionare con questi servizi?