1. Introdução
O Cloud Spanner é um serviço de banco de dados relacional totalmente gerenciado, escalonável e distribuído globalmente que oferece transações ACID e semântica de SQL sem abrir mão do desempenho e da alta disponibilidade.
O GKE Autopilot é um modo de operação em que o Google gerencia a configuração do cluster, incluindo nós, escalonamento, segurança e outras configurações predefinidas para seguir as práticas recomendadas. Por exemplo, o GKE Autopilot permite que a Identidade da carga de trabalho gerencie permissões de serviço.
O objetivo deste laboratório é orientar você no processo de conexão de vários serviços de back-end em execução no Autopilot do GKE a um banco de dados do Cloud Spanner.
Neste laboratório, primeiro você vai configurar um projeto e iniciar o Cloud Shell. Depois você vai implantar a infraestrutura usando o Terraform.
Quando terminar, você vai interagir com o Cloud Build e o Cloud Deploy para realizar uma migração de esquema inicial para o banco de dados de jogos, implantar os serviços de back-end e implantar as cargas de trabalho.
Os serviços deste codelab são os mesmos do codelab Introdução ao desenvolvimento de jogos no Cloud Spanner. Realizar esse codelab não é um requisito para executar os serviços no GKE e se conectar ao Spanner. Mas se você tiver interesse em mais detalhes específicos desses serviços que funcionam no Spanner, confira.
Com as cargas de trabalho e os serviços de back-end em execução, é possível começar a gerar carga e observar como os serviços funcionam juntos.
Por fim, você vai limpar os recursos criados neste laboratório.
O que você vai criar
Como parte deste laboratório, você vai:
- Provisionar a infraestrutura usando o Terraform
- Criar o esquema do banco de dados usando um processo de migração de esquema no Cloud Build
- Implante os quatro serviços de back-end do Golang que usam a Identidade da carga de trabalho para se conectar ao Cloud Spanner
- Implantar os quatro serviços de carga de trabalho usados para simular a carga dos serviços de back-end.
O que você vai aprender
- Como provisionar pipelines do Autopilot do GKE, do Cloud Spanner e do Cloud Deploy usando o Terraform
- Como a Identidade da carga de trabalho permite que os serviços no GKE representem contas de serviço para acessar as permissões do IAM para funcionar com o Cloud Spanner
- Como gerar uma carga semelhante à de produção no GKE e no Cloud Spanner usando o Locust.io
O que é necessário
2. Configuração e requisitos
Criar um projeto
Se você ainda não tem uma Conta do Google (Gmail ou Google Apps), crie uma. Faça login no console do Google Cloud Platform ( console.cloud.google.com) e crie um novo projeto.
Se você já tiver um projeto, clique no menu suspenso de seleção no canto superior esquerdo do console:
e clique no botão NOVO PROJETO na caixa de diálogo para criar um novo projeto:
Se você ainda não tiver um projeto, uma caixa de diálogo como esta será exibida para criar seu primeiro:
A caixa de diálogo de criação de projeto subsequente permite que você insira os detalhes do novo projeto:
Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID
.
Em seguida, será preciso ativar o faturamento no Developers Console para usar os recursos do Google Cloud e ativar a API Cloud Spanner, caso ainda não tenha feito isso.
A execução por meio deste codelab terá um custo baixo, mas poderá ser mais se você decidir usar mais recursos ou se deixá-los em execução. Consulte a seção "limpeza" no final deste documento. Os preços do Google Cloud Spanner estão documentados aqui e do Autopilot do GKE estão documentados aqui.
Novos usuários do Google Cloud Platform estão qualificados para uma avaliação gratuita de US$ 300, o que torna este codelab totalmente gratuito.
Configuração do Cloud Shell
Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
O Cloud Shell é uma máquina virtual com base em Debian que contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Isso significa que tudo que você precisa para este codelab é um navegador (sim, funciona em um Chromebook).
- Para ativar o Cloud Shell no Console do Cloud, basta clicar em Ativar o Cloud Shell . O provisionamento e a conexão ao ambiente devem levar apenas alguns instantes.
Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto estará configurado com seu PROJECT_ID
.
gcloud auth list
Resposta ao comando
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
Resposta ao comando
[core]
project = <PROJECT_ID>
Se, por algum motivo, o projeto não estiver definido, basta emitir o seguinte comando:
gcloud config set project <PROJECT_ID>
Quer encontrar seu PROJECT_ID
? Veja qual ID você usou nas etapas de configuração ou procure-o no painel do Console do Cloud:
O Cloud Shell também define algumas variáveis de ambiente por padrão, o que pode ser útil ao executar comandos futuros.
echo $GOOGLE_CLOUD_PROJECT
Resposta ao comando
<PROJECT_ID>
Fazer o download do código
No Cloud Shell, faça o download do código para este laboratório:
git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git
Resposta ao comando
Cloning into 'spanner-gaming-sample'...
*snip*
Este codelab é baseado na versão v0.1.3, então confira esta 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
Resposta ao comando
Switched to a new branch 'v0.1.3-branch'
Agora defina o diretório de trabalho atual como a variável de ambiente DEMO_HOME. Isso facilita a navegação enquanto você trabalha nas diferentes partes do codelab.
export DEMO_HOME=$(pwd)
Resumo
Nesta etapa, você configurou um novo projeto, ativou o Cloud Shell e fez o download do código para este laboratório.
A seguir
Em seguida, você vai provisionar a infraestrutura usando o Terraform.
3. Provisionar infraestrutura
Visão geral
Com o projeto pronto, é hora de colocar a infraestrutura em execução. Isso inclui redes VPC, Cloud Spanner, GKE Autopilot, Artifact Registry para armazenar as imagens que serão executadas no GKE, os pipelines do Cloud Deploy para serviços e cargas de trabalho de back-end e, por fim, as contas de serviço e os privilégios do IAM para usar esses serviços.
É muita coisa. Felizmente, o Terraform pode simplificar essa configuração. O Terraform é uma ferramenta de "infraestrutura como código" que nos permite especificar o que precisamos para este projeto em uma série de arquivos . Isso simplifica o provisionamento da infraestrutura.
Ter familiaridade com o Terraform não é um requisito para concluir este codelab. Mas se você quiser saber o que as próximas etapas estão fazendo, confira o que tudo é criado nestes arquivos localizados no diretório infrastructure:
- vpc.tf
- backend_gke.tf
- spanner.tf
- artifact_registry.tf
- pipelines.tf
- iam.tf
Configurar o Terraform
No Cloud Shell, mude para o diretório infrastructure
e inicialize o Terraform:
cd $DEMO_HOME/infrastructure
terraform init
Resposta ao 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.
Em seguida, configure o Terraform copiando o terraform.tfvars.sample
e modificando o valor do projeto. As outras variáveis também podem ser alteradas, mas o projeto é a única que precisa ser alterada para funcionar com seu ambiente.
cp terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars
Provisionar a infraestrutura
Agora é hora de provisionar a infraestrutura.
terraform apply
# review the list of things to be created
# type 'yes' when asked
Resposta ao 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.
Verificar o que foi criado
Para confirmar o que foi criado, confira os produtos no console do Cloud.
Cloud Spanner
Primeiro, verifique o Cloud Spanner navegando até o menu de navegação e clicando em Spanner
. Talvez você precise clicar em "Ver mais produtos" para encontrá-lo na lista.
Isso vai levar você à lista de instâncias do Spanner. Clique na instância para acessar os bancos de dados. O código será semelhante a este:
Autopilot do GKE
Em seguida, acesse o GKE navegando até o menu de navegação e clicando em Kubernetes Engine => Clusters
. Aqui você vai conferir o cluster sample-games-gke
em execução no modo Autopilot.
Artifact Registry
Agora você vai querer ver onde as imagens serão armazenadas. Clique no menu de navegação e encontre Artifact Registry=>Repositories
. O Artifact Registry está na seção de CI/CD do menu.
Aqui, você verá um registro do Docker chamado spanner-game-images
. Ele ficará vazio por enquanto.
Cloud Deploy
O Cloud Deploy é onde os pipelines foram criados para que o Cloud Build possa fornecer etapas para criar as imagens e implantá-las no cluster do GKE.
Navegue até o menu de navegação e encontre Cloud Deploy
, que também está na seção CI/CD do menu.
Você vai notar dois pipelines: um para serviços de back-end e outro para cargas de trabalho. Ambas implantam as imagens no mesmo cluster do GKE, mas isso permite separar as implantações.
IAM
Por fim, confira a página do IAM no console do Cloud para verificar as contas de serviço que foram criadas. Navegue até o menu de navegação e encontre IAM and Admin=>Service accounts
. O código será semelhante a este:
Há seis contas de serviço no total criadas pelo Terraform:
- a conta padrão de serviço do computador. Isso não é usado neste codelab.
- A conta cloudbuild-cicd é usada nas etapas de Cloud Build e Cloud Deploy.
- Quatro "app" contas que são usadas pelos nossos serviços de back-end para interagir com o Cloud Spanner.
Em seguida, configure o kubectl
para interagir com o cluster do GKE.
Configurar o 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
Resposta ao 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
Resumo
Ótimo! Você provisionaru uma instância do Cloud Spanner e um cluster do Autopilot do GKE, tudo em uma VPC para rede particular.
Além disso, dois pipelines do Cloud Deploy foram criados para os serviços de back-end e as cargas de trabalho, além de um repositório do Artifact Registry para armazenar as imagens criadas.
Por fim, as contas de serviço foram criadas e configuradas para funcionar com a Identidade da carga de trabalho. Assim, os serviços de back-end podem usar o Cloud Spanner.
Você também configurou o kubectl
para interagir com o cluster do GKE no Cloud Shell depois de implantar os serviços de back-end e as cargas de trabalho.
A seguir
Antes de usar os serviços, o esquema do banco de dados precisa ser definido. Você vai configurar isso a seguir.
4. Criar o esquema do banco de dados
Visão geral
Antes de executar os serviços de back-end, você precisa verificar se o esquema do banco de dados está em vigor.
Nos arquivos do diretório $DEMO_HOME/schema/migrations
do repositório de demonstração, você vai encontrar uma série de arquivos .sql
que definem o esquema. Isso imita um ciclo de desenvolvimento em que as alterações de esquema são rastreadas no próprio repositório e podem ser vinculadas a determinados recursos dos aplicativos.
Neste ambiente de exemplo, a chave é a ferramenta que aplica nossas migrações de esquema usando o Cloud Build.
Cloud Build
O arquivo $DEMO_HOME/schema/cloudbuild.yaml
descreve as etapas que serão realizadas:
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
Basicamente, há duas etapas:
- fazer o download da chave inglesa para o espaço de trabalho do Cloud Build
- executar a migração da chave inglesa
As variáveis de ambiente do banco de dados, da instância e do projeto do Spanner são necessárias para a chave se conectar ao endpoint de gravação.
O Cloud Build pode fazer essas alterações porque está sendo executado como a conta de serviço cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
E essa conta de serviço tem o papel spanner.databaseUser
adicionado pelo Terraform, que permite que a conta de serviço atualize DDL.
Migrações de esquema
Há cinco etapas de migração que são realizadas com base nos arquivos do diretório $DEMO_HOME/schema/migrations
. Confira um exemplo do arquivo 000001.sql
que cria uma tabela players
e os índices:
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);
Enviar a migração do esquema
Para enviar o build para a migração do esquema, alterne para o diretório schema
e execute o seguinte comando gcloud:
cd $DEMO_HOME/schema gcloud builds submit --config=cloudbuild.yaml
Resposta ao 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
Na saída acima, você verá um link para o processo de build do Cloud Created
. Se clicar nele, você será direcionado ao build no console do Cloud para monitorar o progresso e conferir o que está acontecendo.
Resumo
Nesta etapa, você usou o Cloud Build para enviar a migração de esquema inicial que aplicou cinco operações DDL diferentes. Essas operações representam quando foram adicionados recursos que precisavam de alterações no esquema do banco de dados.
Em um cenário de desenvolvimento normal, é recomendado fazer alterações de esquema compatíveis com o aplicativo atual para evitar interrupções.
Para alterações que não são compatíveis com versões anteriores, implante as alterações no aplicativo e no esquema em etapas para garantir que não haja interrupções.
A seguir
Com o esquema implementado, a próxima etapa é implantar os serviços de back-end.
5. Implantar os serviços de back-end
Visão geral
Os serviços de back-end deste codelab são APIs REST do golang que representam quatro serviços diferentes:
- Perfil:permite que os jogadores se inscrevam e autentiquem no nosso "jogo" de exemplo.
- Criação de combinações:interaja com os dados dos jogadores para ajudar com uma função de combinação, acompanhar informações sobre jogos criados e atualizar as estatísticas quando os jogos são encerrados.
- Item:permite que os usuários adquiram itens e dinheiro ao longo do jogo.
- Tradepost::permita que os jogadores comprem e vendam itens em uma loja
Saiba mais sobre esses serviços no codelab Introdução ao desenvolvimento de jogos com o Cloud Spanner. Para nossos objetivos, queremos que esses serviços sejam executados no nosso cluster do Autopilot do GKE.
Esses serviços precisam ser capazes de modificar os dados do Spanner. Para isso, cada serviço tem uma conta criada que concede a ele o papel "databaseUser" de rede.
A Identidade da carga de trabalho permite que uma conta de serviço do Kubernetes personifique conta de serviço do Google Cloud seguindo as etapas abaixo no Terraform:
- Criar o recurso da conta de serviço do Google Cloud (
GSA
) do serviço - Atribua o papel databaseUser a essa conta de serviço.
- Atribua o papel workloadIdentityUser a essa conta de serviço.
- Crie uma conta de serviço do Kubernetes (
KSA
) que faça referência ao GSA
Um diagrama aproximado seria semelhante a este:
O Terraform criou as contas de serviço e as contas de serviço do Kubernetes para você. E é possível verificar as contas de serviço do Kubernetes usando 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
O build funciona da seguinte maneira:
- O Terraform gerou um arquivo
$DEMO_HOME/backend_services/cloudbuild.yaml
parecido com este:
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
- O comando do Cloud Build lê esse arquivo e segue as etapas listadas. Primeiro, ele cria as imagens de serviço. Em seguida, ele executa um comando
gcloud deploy create
. Isso lê o arquivo$DEMO_HOME/backend_services/skaffold.yaml
, que define onde cada arquivo de implantação está localizado:
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
manifests:
- spanner_config.yaml
- profile/deployment.yaml
- matchmaking/deployment.yaml
- item/deployment.yaml
- tradepost/deployment.yaml
- O Cloud Deploy seguirá as definições do arquivo
deployment.yaml
de cada serviço. O arquivo de implantação do serviço contém as informações para criar um serviço, que neste caso é um clusterIP em execução na porta 80.
O evento " O tipo ClusterIP" impede que os pods de serviço de back-end tenham um IP externo. Assim, apenas entidades que podem se conectar à rede interna do GKE podem acessar os serviços de back-end. Esses serviços não podem ser diretamente acessíveis aos jogadores porque eles acessam e modificam os dados do Spanner.
apiVersion: v1
kind: Service
metadata:
name: profile
spec:
type: ClusterIP
selector:
app: profile
ports:
- port: 80
targetPort: 80
Além de criar um serviço do Kubernetes, o Cloud Deploy também cria uma implantação do Kubernetes. Vamos examinar a seção de implantação do serviço 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"
A parte de cima contém alguns metadados sobre o serviço. O mais importante aqui é definir quantas réplicas serão criadas por esta implantação.
replicas: 2 # EDIT: Number of instances of deployment
Em seguida, vamos conferir qual conta de serviço executa o app e qual imagem ele precisa usar. Elas correspondem à conta de serviço do Kubernetes criada no Terraform e à imagem criada durante a etapa do Cloud Build.
spec:
serviceAccountName: profile-app
containers:
- name: profile-service
image: profile
Depois, especificamos algumas informações sobre a rede e as variáveis de ambiente.
O spanner_config
é um ConfigMap do Kubernetes que especifica as informações do projeto, da instância e do banco de dados necessárias para que o aplicativo se conecte ao 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
são variáveis de ambiente extras necessárias para que o serviço saiba onde se vincular.
A seção final informa ao GKE quantos recursos são permitidos para cada réplica na implantação. O GKE Autopilot também usa isso para escalonar o cluster conforme necessário.
resources:
requests:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
Com essas informações, é hora de implantar os serviços de back-end.
Implantar os serviços de back-end
Como mencionado, a implantação dos serviços de back-end usa o Cloud Build. Assim como nas migrações de esquema, é possível enviar a solicitação de build usando a linha de comando gcloud:
cd $DEMO_HOME/backend_services gcloud builds submit --config=cloudbuild.yaml
Resposta ao 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
Ao contrário da saída da etapa schema migration
, a saída desse build indica que algumas imagens foram criadas. Eles serão armazenados no repositório do Artifact Registry.
A saída da etapa gcloud build
terá um link para o console do Cloud. Dá uma olhada nisso.
Quando você tiver a notificação de êxito do Cloud Build, acesse o Cloud Deploy e, em seguida, o pipeline sample-game-services
para monitorar o progresso da implantação.
Depois que os serviços forem implantados, verifique o kubectl
para verificar Status:
kubectl get pods
Resposta ao 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
Em seguida, verifique os serviços para ver o ClusterIP
em ação:
kubectl get services
Resposta ao 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
Também é possível navegar até a interface do GKE no Console do Cloud para ver Workloads
, Services
e ConfigMaps
.
Cargas de trabalho
Serviços
ConfigMaps
Resumo
Nesta etapa, você implantou os quatro serviços de back-end no Autopilot do GKE. Você conseguiu executar a etapa do Cloud Build e verificar o progresso no Cloud Deploy e no Kubernetes no console do Cloud.
Você também aprendeu como esses serviços usam a Identidade da carga de trabalho para representar uma conta de serviço com as permissões certas para ler e gravar dados no banco de dados do Spanner.
Próximas etapas
Na próxima seção, você vai implantar as cargas de trabalho.
6. Implantar as cargas de trabalho
Visão geral
Agora que os serviços de back-end estão em execução no cluster, você implantará as cargas de trabalho.
As cargas de trabalho podem ser acessadas externamente, e há uma para cada serviço de back-end neste codelab.
Essas cargas de trabalho são scripts de geração de carga baseados no Locust que imitam os padrões de acesso reais esperados por esses serviços de amostra.
Há arquivos para o processo do Cloud Build:
$DEMO_HOME/workloads/cloudbuild.yaml
(gerado pelo Terraform)$DEMO_HOME/workloads/skaffold.yaml
- um arquivo
deployment.yaml
para cada carga de trabalho
Os arquivos deployment.yaml
da carga de trabalho são um pouco diferentes dos arquivos de implantação do serviço de back-end.
Veja um exemplo do 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"
A parte superior do arquivo define o serviço. Nesse caso, um LoadBalancer
é criado e a carga de trabalho é executada na porta 8089
.
O LoadBalancer fornecerá um IP externo que pode ser usado para se conectar à carga de trabalho.
apiVersion: v1
kind: Service
metadata:
name: matchmaking-workload
spec:
type: LoadBalancer
selector:
app: matchmaking-workload
ports:
- port: 8089
targetPort: 8089
A parte de cima da seção de implantação são os metadados sobre a carga de trabalho. Neste caso, apenas uma réplica está sendo implantada:
replicas: 1
No entanto, a especificação do contêiner é diferente. Por um lado, estamos usando uma conta de serviço default
do Kubernetes. Essa conta não tem privilégios especiais, já que a carga de trabalho não precisa se conectar a nenhum recurso do Google Cloud, exceto aos serviços de back-end em execução no cluster do GKE.
A outra diferença é que não são necessárias variáveis de ambiente para essas cargas de trabalho. O resultado é uma especificação de implantação mais curta.
spec:
serviceAccountName: default
containers:
- name: matchmaking-workload
image: matchmaking-workload
ports:
- containerPort: 8089
As configurações de recursos são semelhantes às dos serviços de back-end. É assim que o Autopilot do GKE sabe quantos recursos são necessários para atender às solicitações de todos os pods em execução no cluster.
Implante as cargas de trabalho.
Implantar as cargas de trabalho
Assim como antes, você pode enviar a solicitação de build usando a linha de comando gcloud:
cd $DEMO_HOME/workloads gcloud builds submit --config=cloudbuild.yaml
Resposta ao 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
Verifique os registros do Cloud Build e o pipeline do Cloud Deploy no console do Cloud para verificar o status. Para as cargas de trabalho, o pipeline do Cloud Deploy é sample-game-workloads
:
Quando a implantação for concluída, verifique o status com kubectl
no Cloud Shell:
kubectl get pods
Resposta ao 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
Em seguida, verifique os serviços de carga de trabalho para ver o LoadBalancer
em ação:
kubectl get services
Resposta ao 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
Resumo
Você implantou as cargas de trabalho no cluster do GKE. Essas cargas de trabalho não exigem outras permissões do IAM e podem ser acessadas externamente na porta 8089 com o serviço LoadBalancer.
Próximas etapas
Com serviços de back-end e cargas de trabalho em execução, é hora de jogar o jogo!
7. Começar a jogar
Visão geral
Os serviços de back-end para o "jogo" de amostra estão em execução e você também pode gerar "jogadores" que interagem com esses serviços usando as cargas de trabalho.
Cada carga de trabalho usa o Locust para simular uma carga real com base nas nossas APIs de serviço. Nesta etapa, você vai executar várias cargas de trabalho para gerar carga no cluster do GKE e no Spanner, além de armazenar dados nele.
Veja a seguir uma descrição de cada carga de trabalho:
- A carga de trabalho
item-generator
é rápida para gerar uma lista de game_items que os jogadores podem adquirir ao "jogar" o jogo. - O
profile-workload
simula a inscrição e o login dos jogadores. - O
matchmaking-workload
simula os jogadores na fila para serem atribuídos a jogos. - O
game-workload
simula a aquisição de itens de jogo e dinheiro pelos jogadores. - O
tradepost-workload
simula a venda e compra de itens dos jogadores na postagem de negociação.
Este codelab destacará a execução específica de item-generator
e profile-workload
.
Executar o gerador de itens
O item-generator
usa o endpoint do serviço de back-end item
para adicionar game_items
ao Spanner. Esses itens são necessários para que game-workload
e tradepost-workload
funcionem corretamente.
A primeira etapa é conseguir o IP externo do serviço item-generator
. No Cloud Shell, execute o seguinte:
# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'
Resposta ao comando
{ITEMGENERATOR_EXTERNAL_IP}
Agora, abra uma nova guia do navegador e aponte-a para http://{ITEMGENERATOR_EXTERNAL_IP}:8089
. Você verá uma página como esta:
Deixe users
e spawn
com o padrão 1. Para host
, insira http://item
. Clique nas opções avançadas e insira 10s
para o tempo de execução.
A configuração vai ficar assim:
Clique em "Start swarming"!
Estatísticas serão exibidas para solicitações emitidas no endpoint POST /items
. Após 10 segundos, o carregamento é interrompido.
Clique no Charts
para ver alguns gráficos sobre o desempenho dessas solicitações.
Agora você quer verificar se os dados são inseridos no banco de dados do Spanner.
Para fazer isso, clique no menu de navegação e acesse "Spanner". Nessa página, navegue até o sample-instance
e o sample-database
. Depois, clique em "Query
".
Queremos selecionar o número de game_items
:
SELECT COUNT(*) FROM game_items;
Você receberá seu resultado na parte inferior.
Não precisamos de muitas sugestões de game_items
. Mas agora eles estão disponíveis para os jogadores adquirirem!
Executar a carga de trabalho do perfil
Com seu número de origem do game_items
, a próxima etapa é inscrever os jogadores para poder jogar.
O profile-workload
vai usar o Locust para simular os jogadores criando contas, fazendo login, recuperando informações de perfil e saindo. Todos eles testam os endpoints do serviço de back-end profile
em uma carga de trabalho típica semelhante à de produção.
Para executar, consulte o IP externo profile-workload
:
# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'
Resposta ao comando
{PROFILEWORKLOAD_EXTERNAL_IP}
Agora, abra uma nova guia do navegador e aponte-a para http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089
. Será exibida uma página do Locust parecida com a anterior.
Neste caso, você vai usar http://profile
para o host. Além disso, você não especificará um ambiente de execução nas opções avançadas. Além disso, especifique o users
como 4, o que vai simular quatro solicitações do usuário por vez.
O teste profile-workload
ficará assim:
Clique em "Start swarming"!
Assim como antes, as estatísticas dos vários endpoints REST profile
vão começar a aparecer. Clique nos gráficos para visualizar o desempenho de tudo.
Resumo
Nesta etapa, você gerou game_items
e consultou a tabela game_items
usando a interface de consulta do Spanner no Console do Cloud.
Você também permitiu que os jogadores se inscrevessem no jogo e viu como o Locust cria cargas de trabalho semelhantes às de produção nos serviços de back-end.
Próximas etapas
Depois de executar as cargas de trabalho, verifique como o cluster do GKE e a instância do Spanner estão se comportando.
8. Analisar o uso do GKE e do Spanner
Com o serviço de perfil em execução, é hora de aproveitar a oportunidade para conferir como o cluster do Autopilot do GKE e o Cloud Spanner estão se comportando.
Verificar o cluster do GKE
Navegue até o cluster do Kubernetes. Observe que, como você implantou as cargas de trabalho e os serviços, o cluster agora tem alguns detalhes sobre o total de vCPUs e a memória. Essas informações não estavam disponíveis quando não havia cargas de trabalho no cluster.
Agora, clique no cluster sample-game-gke
e alterne para a guia de observabilidade:
O namespace do Kubernetes default
deveria ter ultrapassado o namespace kube-system
para utilização de CPU, já que nossas cargas de trabalho e serviços de back-end são executados em default
. Caso contrário, verifique se o profile workload
ainda está em execução e aguarde alguns minutos para que os gráficos sejam atualizados.
Para ver quais cargas de trabalho estão usando mais recursos, acesse o painel Workloads
.
Em vez de analisar cada carga de trabalho individualmente, vá direto para a guia "Observabilidade" do painel. A CPU de profile
e profile-workload
aumentou.
Agora, verifique o Cloud Spanner.
Verificação na instância do Cloud Spanner
Para verificar o desempenho do Cloud Spanner, navegue até o Spanner e clique na instância sample-instance
e no banco de dados sample-game
.
Você verá uma guia Insights do sistema no menu à esquerda:
Há muitos gráficos para ajudar você a entender o desempenho geral da sua instância do Spanner, incluindo CPU utilization
, transaction latency and locking
e query throughput
.
Além dos Insights do sistema, você pode conferir informações mais detalhadas sobre a carga de trabalho de consultas nos outros links da seção "Observabilidade":
- Os insights de consulta ajudam a identificar as principais consultas que utilizam recursos no Spanner.
- Os insights de transação e bloqueio ajudam a identificar transações com altas latências.
- O Key Visualizer ajuda a visualizar padrões de acesso e a rastrear pontos de acesso nos dados.
Resumo
Nesta etapa, você aprendeu a verificar algumas métricas básicas de desempenho do Autopilot do GKE e do Spanner.
Por exemplo, com a carga de trabalho do seu perfil em execução, consulte a tabela players para mais informações sobre os dados que estão sendo armazenados.
Próximas etapas
A seguir, é hora de fazer a limpeza!
9. Limpar
Antes da limpeza, fique à vontade para conhecer as outras cargas de trabalho que não foram abordadas. Especificamente, matchmaking-workload
, game-workload
e tradepost-workload
.
Quando terminar de "tocar", pode limpar o playground. Felizmente, isso é muito fácil.
Primeiro, se o profile-workload
ainda estiver em execução no navegador, interrompa-o:
Faça o mesmo para cada carga de trabalho que você possa ter testado.
Em seguida, no Cloud Shell, navegue até a pasta de infraestrutura. Você vai destroy
a infraestrutura usando o Terraform:
cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked
Resposta ao 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.
No console do Cloud, acesse Spanner
, Kubernetes Cluster
, Artifact Registry
, Cloud Deploy
e IAM
para confirmar que todos os recursos foram removidos.
10. Parabéns!
Parabéns, você implantou aplicativos de amostra golang no GKE Autopilot e os conectou ao Cloud Spanner usando a Identidade da carga de trabalho.
Como bônus, essa infraestrutura foi facilmente configurada e removida de maneira repetível usando o Terraform.
Leia mais sobre os serviços do Google Cloud com que você interagiu neste codelab:
- GKE Autopilot e Identidade da carga de trabalho
- Cloud Spanner
- Artifact Registry
- Cloud Build e Cloud Deploy
A seguir
Agora que você tem um entendimento básico de como o Autopilot do GKE e o Cloud Spanner podem funcionar juntos, que tal começar a criar seu próprio aplicativo para trabalhar com esses serviços?