1. Wprowadzenie
Cloud Spanner to w pełni zarządzana, skalowalna w poziomie, rozproszona globalnie, relacyjna usługa baz danych, która zapewnia transakcje ACID i semantykę SQL bez utraty wydajności i wysokiej dostępności.
Autopilot GKE to tryb działania w GKE, w którym Google zarządza konfiguracją klastra, w tym węzłami, skalowaniem, zabezpieczeniami i innymi wstępnie skonfigurowanymi ustawieniami zgodnie ze sprawdzonymi metodami. Na przykład Autopilot w GKE umożliwia Workload Identity zarządzanie uprawnieniami usługi.
Z tego modułu dowiesz się, jak połączyć kilka usług backendu działających w trybie Autopilota w GKE z bazą danych Cloud Spanner.
W tym module najpierw skonfigurujesz projekt i uruchomisz Cloud Shell. Potem wdrożysz infrastrukturę za pomocą Terraform.
Po zakończeniu wejdziesz w interakcję z Cloud Build i Cloud Deploy w celu przeprowadzenia początkowej migracji schematu bazy danych gier, wdrożenia usług backendu, a potem wdrożenia zadań.
Usługi w tym ćwiczeniu w Codelabs są takie same jak w wstępnym kroku tworzenia gier w Cloud Spanner. Ukończenie tych ćwiczeń w Codelabs nie jest wymagane do uruchomienia usług w GKE i połączenia się ze Spannerem. Jeśli jednak chcesz dowiedzieć się więcej o tych usługach, które działają w usłudze Spanner, przeczytaj je.
Gdy zbiory zadań i usługi backendu są uruchomione, możesz zacząć generować obciążenie i obserwować, jak usługi ze sobą współpracują.
Na koniec usuniesz zasoby utworzone w tym module.
Co utworzysz
W ramach tego modułu:
- Udostępnianie infrastruktury za pomocą Terraform
- Tworzenie schematu bazy danych przy użyciu procesu migracji schematów w Cloud Build
- Wdróż 4 usługi backendu Golang, które korzystają z Workload Identity do łączenia się z Cloud Spanner
- Wdróż 4 usługi zadań, które służą do symulowania obciążenia usług backendu.
Czego się nauczysz
- Jak udostępnić potoki Autopilota, Cloud Spanner i Cloud Deploy za pomocą Terraform
- Jak Workload Identity umożliwia usługom w GKE przyjmowanie tożsamości kont usługi w celu uzyskania dostępu do uprawnień do pracy z Cloud Spanner
- Jak wygenerować obciążenie produkcyjne w GKE i Cloud Spanner za pomocą Locust.io
Czego potrzebujesz
2. Konfiguracja i wymagania
Utwórz projekt
Jeśli nie masz jeszcze konta Google (w Gmailu lub Google Apps), musisz je utworzyć. Zaloguj się w konsoli Google Cloud Platform ( console.cloud.google.com) i utwórz nowy projekt.
Jeśli masz już projekt, kliknij menu wyboru projektu w lewym górnym rogu konsoli:
i kliknij NOWY PROJEKT. w wyświetlonym oknie, aby utworzyć nowy projekt:
Jeśli nie masz jeszcze projektu, zobaczysz takie okno dialogowe umożliwiające utworzenie pierwszego:
W kolejnym oknie tworzenia projektu możesz wpisać szczegóły nowego projektu:
Zapamiętaj identyfikator projektu, który jest niepowtarzalną nazwą we wszystkich projektach Google Cloud (powyższa nazwa jest już zajęta i nie będzie Ci odpowiadać). W dalszej części tego ćwiczenia w programie będzie ona określana jako PROJECT_ID
.
Następnie musisz włączyć płatności w Developers Console, aby korzystać z zasobów Google Cloud i włączyć interfejs Cloud Spanner API.
Ukończenie tego ćwiczenia w Codelabs nie powinno kosztować więcej niż kilka dolarów, ale może być droższe, jeśli zdecydujesz się użyć więcej zasobów lub nie chcesz ich uruchamiać (patrz sekcja „Czyszczenie” na końcu tego dokumentu). Cennik Google Cloud Spanner znajdziesz tutaj, a Autopilot w GKE jest dostępny tutaj.
Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnego okresu próbnego w wysokości 300 USD, dzięki czemu te ćwiczenia z programowania są całkowicie bezpłatne.
Konfiguracja Cloud Shell
Usługi Google Cloud i Spanner można obsługiwać zdalnie z poziomu laptopa, ale w ramach tego ćwiczenia w programowaniu użyjemy Google Cloud Shell – środowiska wiersza poleceń działającego w chmurze.
Ta maszyna wirtualna oparta na Debianie zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Oznacza to, że do tego ćwiczenia z programowania wystarczy przeglądarka (tak, działa ona na Chromebooku).
- Aby aktywować Cloud Shell z poziomu konsoli Cloud, kliknij Aktywuj Cloud Shell (udostępnienie środowiska i połączenie z nim powinno zająć tylko kilka chwil).
Po nawiązaniu połączenia z Cloud Shell powinno pojawić się potwierdzenie, że użytkownik jest już uwierzytelniony, a projekt jest już ustawiony na PROJECT_ID
.
gcloud auth list
Dane wyjściowe polecenia
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
Dane wyjściowe polecenia
[core]
project = <PROJECT_ID>
Jeśli z jakiegoś powodu projekt nie jest skonfigurowany, uruchom po prostu to polecenie:
gcloud config set project <PROJECT_ID>
Szukasz urządzenia PROJECT_ID
? Sprawdź identyfikator użyty w krokach konfiguracji lub wyszukaj go w panelu Cloud Console:
Cloud Shell ustawia też domyślnie niektóre zmienne środowiskowe, które mogą być przydatne podczas uruchamiania kolejnych poleceń.
echo $GOOGLE_CLOUD_PROJECT
Dane wyjściowe polecenia
<PROJECT_ID>
Pobieranie kodu
W Cloud Shell możesz pobrać kod tego modułu:
git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git
Dane wyjściowe polecenia
Cloning into 'spanner-gaming-sample'...
*snip*
To ćwiczenie z programowania jest oparte na wersji v0.1.3, więc zajrzyj do tego tagu:
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
Dane wyjściowe polecenia
Switched to a new branch 'v0.1.3-branch'
Teraz ustaw bieżący katalog roboczy jako zmienną środowiskową DEMO_HOME. Dzięki temu poruszanie się po poszczególnych częściach ćwiczeń z programowania będzie łatwiejsze.
export DEMO_HOME=$(pwd)
Podsumowanie
W tym kroku skonfigurujesz nowy projekt, aktywujesz Cloud Shell i pobrasz kod tego modułu.
Następny krok
Następnie udostępnisz infrastrukturę za pomocą Terraform.
3. Udostępnianie infrastruktury
Omówienie
Po przygotowaniu projektu możesz uruchomić infrastrukturę. Obejmuje to sieci VPC, Cloud Spanner, Autopilot i Artifact Registry do przechowywania obrazów, które będą działać w GKE, potoki Cloud Deploy dla usług i zadań backendu, a także konta usługi i uprawnienia umożliwiające korzystanie z tych usług.
To dużo. Na szczęście konfiguracja Terraform może być prosta. Terraform to „infrastruktura jako kod” narzędzie, które pozwala nam określić, czego potrzebujemy w projekcie, w pliku „.tf” . Ułatwia to udostępnianie infrastruktury.
Znajomość Terraform nie jest wymagana do ukończenia tego ćwiczenia z programowania. Jeśli jednak chcecie się przekonać, co będzie robić w kolejnych krokach, możecie zobaczyć, co jest tworzone w tych plikach znajdujących się w katalogu infrastructure:
- vpc.tf
- backend_gke.tf
- spanner.tf
- artifact_registry.tf
- pipelines.tf
- iam.tf
Skonfiguruj Terraform
W Cloud Shell przejdziesz do katalogu infrastructure
i zainicjujesz Terraform:
cd $DEMO_HOME/infrastructure
terraform init
Dane wyjściowe polecenia
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.
Następnie skonfiguruj Terraform, kopiując wartość terraform.tfvars.sample
i modyfikując wartość projektu. Pozostałe zmienne również można zmienić, ale trzeba dostosować wyłącznie projekt, aby działał w Twoim środowisku.
cp terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars
Udostępnianie infrastruktury
Czas udostępnić infrastrukturę.
terraform apply
# review the list of things to be created
# type 'yes' when asked
Dane wyjściowe polecenia
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.
Sprawdzanie, co zostało utworzone
Aby sprawdzić, co zostało utworzone, sprawdź usługi w konsoli Cloud.
Cloud Spanner
Najpierw sprawdź usługę Cloud Spanner. W tym celu otwórz menu z 3 kreskami i kliknij Spanner
. Być może trzeba będzie kliknąć „Wyświetl więcej produktów”. aby znaleźć go na liście.
Otworzy się lista instancji Spannera. Gdy klikniesz instancję, wyświetlą się bazy danych. Powinna wyglądać mniej więcej tak:
Autopilot w GKE
Następnie zapoznaj się z GKE. W tym celu otwórz menu z hamburgerami i kliknij Kubernetes Engine => Clusters
. Tutaj zobaczysz klaster sample-games-gke
działający w trybie Autopilota.
Artifact Registry
Teraz sprawdź, gdzie będą przechowywane obrazy. Kliknij menu z hamburgerami i znajdź Artifact Registry=>Repositories
. Artifact Registry znajdziesz w sekcji CI/CD menu.
Zobaczysz tutaj rejestr Dockera o nazwie spanner-game-images
. Na razie to pole będzie puste.
Cloud Deploy
W Cloud Deploy utworzono potoki, tak aby usługa Cloud Build mogła udostępniać kroki umożliwiające utworzenie obrazów, a następnie wdrożenie ich w naszym klastrze GKE.
Przejdź do menu z 3 kreskami i znajdź Cloud Deploy
, który też znajduje się w sekcji CI/CD w menu.
Zobaczysz 2 potoki: jeden dla usług backendu i jeden dla zadań. Oba wdrażają obrazy w tym samym klastrze GKE, ale pozwala to rozdzielić wdrożenia.
Uprawnienia
Na koniec otwórz stronę Uprawnienia w konsoli Cloud, aby sprawdzić utworzone konta usługi. Otwórz menu z hamburgerami i znajdź: IAM and Admin=>Service accounts
. Powinna wyglądać mniej więcej tak:
Terraform jest utworzonych łącznie 6 kont usługi:
- Domyślne konto usługi komputerowej. Nie jest on używany w tym ćwiczeniu z programowania.
- Konto cloudbuild-cicd jest używane do wykonywania kroków Cloud Build i Cloud Deploy.
- Cztery aplikacje używane przez nasze usługi backendu do interakcji z Cloud Spanner.
Następnie musisz skonfigurować usługę kubectl
pod kątem interakcji z klastrem GKE.
Konfigurowanie 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
Dane wyjściowe polecenia
#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
Podsumowanie
Świetnie. Udało Ci się udostępnić instancję Cloud Spanner (klaster z Autopilotem w GKE) w VPC na potrzeby sieci prywatnych.
Dodatkowo zostały utworzone 2 potoki Cloud Deploy dla usług backendu i zadań, a także repozytorium Artifact Registry, w którym będą przechowywane skompilowane obrazy.
Na koniec utworzyliśmy konta usługi i skonfigurowano je pod kątem współpracy z Workspace Identity, dzięki czemu usługi backendu mogą używać Cloud Spanner.
Dodatkowo usługa kubectl
jest skonfigurowana do interakcji z klastrem GKE w Cloud Shell po wdrożeniu usług i zadań backendu.
Następny krok
Aby móc korzystać z usług, musisz zdefiniować schemat bazy danych. Skonfigurujesz ją w następnej kolejności.
4. Tworzenie schematu bazy danych
Omówienie
Zanim uruchomisz usługi backendu, musisz się upewnić, że schemat bazy danych jest dostępny.
Jeśli spojrzysz na pliki w katalogu $DEMO_HOME/schema/migrations
z repozytorium demonstracyjnego, zobaczysz serię plików .sql
definiujących nasz schemat. Naśladuje to cykl programowania, w którym zmiany schematu są śledzone w samym repozytorium i można je powiązać z określonymi funkcjami aplikacji.
W tym przykładowym środowisku narzędzie klucz służy do stosowania migracji schematu za pomocą Cloud Build.
Cloud Build
Plik $DEMO_HOME/schema/cloudbuild.yaml
zawiera opis czynności, które należy wykonać:
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
Musisz wykonać te 2 czynności:
- pobierz klucz do obszaru roboczego Cloud Build
- Uruchom migrację klucza
Zmienne środowiskowe projektu, instancji i bazy danych Spanner są potrzebne, aby klucz mógł połączyć się z punktem końcowym zapisu.
Cloud Build może wprowadzić te zmiany, ponieważ działa jako konto usługi cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
To konto usługi ma przypisaną rolę spanner.databaseUser
przez Terraform, która umożliwia kontu usługi aktualizowanie DDL.
Migracje schematu
Plików w katalogu $DEMO_HOME/schema/migrations
wykonuje się w 5 etapach migracji. Oto przykład pliku 000001.sql
, który tworzy tabelę players
i indeksuje:
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);
Przesyłanie migracji schematu
Aby przesłać kompilację do przeprowadzenia migracji schematu, przejdź do katalogu schema
i uruchom to polecenie gcloud:
cd $DEMO_HOME/schema gcloud builds submit --config=cloudbuild.yaml
Dane wyjściowe polecenia
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
W powyższych danych wyjściowych znajdziesz link do procesu kompilacji w Cloud Build w Created
. Gdy to zrobisz, przejdziesz do kompilacji w Cloud Console, gdzie możesz śledzić jej postęp i wyniki.
Podsumowanie
W tym kroku za pomocą Cloud Build udało Ci się przesłać początkową migrację schematu, która obejmowała 5 różnych operacji DDL. Te operacje pokazują, kiedy dodano funkcje, które wymagały zmian schematu bazy danych.
W normalnym przypadku programowania należy wprowadzić zmiany schematu tak, by były zgodne wstecznie z bieżącą aplikacją, aby uniknąć przerw w działaniu usługi.
W przypadku zmian, które nie są zgodne wstecznie, zmiany należy wprowadzać etapami w aplikacji i schemacie, aby uniknąć przerw w działaniu usługi.
Następny krok
Następnym krokiem po przygotowaniu schematu jest wdrożenie usług backendu.
5. Wdrażanie usług backendu
Omówienie
Usługi backendu w tym ćwiczeniach z programowania to interfejsy API typu REST golang, które reprezentują 4 różne usługi:
- Profil: zapewnia graczom możliwość zarejestrowania się i uwierzytelniania w naszej przykładowej „grze”.
- Dobieranie: korzystaj z danych zawodników, aby pomagać w dobieraniu graczy, śledzić informacje o utworzonych grach i aktualizować statystyki zawodników po ich zamknięciu.
- Przedmiot: umożliwia graczom pozyskiwanie przedmiotów i pieniędzy w trakcie rozgrywki.
- Tradepost: umożliwia graczom kupowanie i sprzedaż przedmiotów na platformie handlowej.
Więcej informacji o tych usługach znajdziesz w ćwiczeniu z programowania Cloud Spanner wprowadzającym do tworzenia gier. Do naszych celów te usługi powinny działać w naszym klastrze z Autopilotem w GKE.
Te usługi muszą mieć możliwość modyfikowania danych Spannera. W tym celu każda usługa ma utworzone konto usługi, które przyznaje do niej identyfikator „databaseUser” rolę użytkownika.
Workload Identity pozwala kontu usługi Kubernetes przyjmować tożsamość usług przez wykonanie tych czynności w Terraform:
- Utwórz zasób konta usługi Google Cloud (
GSA
) dla usługi - Przypisz rolę databaseUser do tego konta usługi.
- Przypisz do tego konta rolę workloadIdentityUser.
- Utwórz konto usługi Kubernetes (
KSA
), które odwołuje się do Modułu Wyszukiwania Google
Przybliżony diagram może wyglądać tak:
Terraform utworzył(a) konta usługi i konta usługi Kubernetes za Ciebie. Konta usługi Kubernetes można też sprawdzać za pomocą usługi 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
Proces kompilacji wygląda tak:
- Terraform wygenerował plik
$DEMO_HOME/backend_services/cloudbuild.yaml
, który wygląda mniej więcej tak:
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
- Polecenie Cloud Build odczytuje ten plik i wykonuje podane czynności. Najpierw tworzy obrazy usługi. Następnie wykonuje polecenie
gcloud deploy create
. Czyta plik$DEMO_HOME/backend_services/skaffold.yaml
, który określa, gdzie znajduje się każdy plik wdrożenia:
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 będzie korzystać z definicji pliku
deployment.yaml
każdej usługi. Plik wdrożeniowy usługi zawiera informacje potrzebne do utworzenia usługi, którą w tym przypadku jest adres clusterIP działający na porcie 80.
ClusterIP uniemożliwia podom usługi backendu korzystanie z zewnętrznych adresów IP. W ten sposób dostęp do usług backendu mają tylko encje, które mogą połączyć się z wewnętrzną siecią GKE. Te usługi nie powinny być bezpośrednio dostępne dla graczy, ponieważ mają oni dostęp do danych Spannera i je modyfikują.
apiVersion: v1
kind: Service
metadata:
name: profile
spec:
type: ClusterIP
selector:
app: profile
ports:
- port: 80
targetPort: 80
Oprócz utworzenia usługi Kubernetes Cloud Deploy tworzy też wdrożenie Kubernetes. Przyjrzyjmy się sekcji wdrażania usługi 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"
Górna część zawiera metadane dotyczące usługi. Najważniejszym z nich jest określenie, ile replik zostanie utworzonych przez to wdrożenie.
replicas: 2 # EDIT: Number of instances of deployment
Następnie określamy, na którym koncie usługi powinna być uruchomiona aplikacja i którego obrazu powinna używać. Są one zgodne z kontem usługi Kubernetes utworzonym z Terraform i obrazem utworzonym w kroku Cloud Build.
spec:
serviceAccountName: profile-app
containers:
- name: profile-service
image: profile
Następnie podaję informacje o zmiennych sieciowych i środowiskowych.
spanner_config
to obiekt ConfigMap Kubernetes określający informacje o projekcie, instancji i bazie danych, które są niezbędne, aby aplikacja mogła połączyć się z usługą 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
i SERVICE_PORT
to dodatkowe zmienne środowiskowe wymagane przez usługę, aby wiedzieć, gdzie utworzyć powiązanie.
Ostatnia sekcja informuje GKE, na ile zasobów zezwolić na każdą replikę w tym wdrożeniu. W ten sposób Autopilot w GKE będzie też skalować klaster odpowiednio do potrzeb.
resources:
requests:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
Po zgromadzeniu tych informacji możesz wdrożyć usługi backendu.
Wdrażanie usług backendu
Jak już wspomnieliśmy, wdrażanie usług backendu odbywa się za pomocą Cloud Build. Tak jak w przypadku migracji schematu, żądanie kompilacji możesz przesłać za pomocą wiersza poleceń gcloud:
cd $DEMO_HOME/backend_services gcloud builds submit --config=cloudbuild.yaml
Dane wyjściowe polecenia
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
W przeciwieństwie do danych wyjściowych kroku schema migration
dane wyjściowe tej kompilacji wskazują, że zostały utworzone obrazy. Zostaną one zapisane w Twoim repozytorium Artifact Registry.
Dane wyjściowe kroku gcloud build
będą miały link do Cloud Console. Spójrzcie na to.
Gdy otrzymasz powiadomienie o powodzeniu z Cloud Build, przejdź do Cloud Deploy, a potem do potoku sample-game-services
, aby monitorować postęp wdrożenia.
Po wdrożeniu usług możesz sprawdzić w kubectl
, aby wyświetlić pody stan:
kubectl get pods
Dane wyjściowe polecenia
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
Następnie sprawdź w usługach, jak działa ClusterIP
:
kubectl get services
Dane wyjściowe polecenia
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
Możesz też przejść do interfejsu GKE w konsoli Cloud, aby zobaczyć Workloads
, Services
i ConfigMaps
.
Zadania
Usługi
Pliki ConfigMap
Podsumowanie
W tym kroku wdrożyłeś(-aś) 4 usługi backendu w Autopilocie w GKE. Udało Ci się uruchomić krok Cloud Build i sprawdzić postęp w Cloud Deploy oraz w Kubernetes w konsoli Cloud.
Wiesz już również, jak usługi te wykorzystują Workload Identity do przyjmowania tożsamości konta usługi z odpowiednimi uprawnieniami do odczytu i zapisu danych w bazie danych Spanner.
Następne kroki
W następnej sekcji wdrożysz zadania.
6. Wdrażanie zadań
Omówienie
Gdy w klastrze działają już usługi backendu, możesz wdrożyć zadania.
Zbiory zadań są dostępne z zewnątrz, a na potrzeby tego ćwiczenia z programowania znajduje się po jednym dla każdej usługi backendu.
Te zbiory zadań to skrypty generowania obciążenia oparte na modelu Locust, które naśladują rzeczywiste wzorce dostępu oczekiwane przez te przykładowe usługi.
Dostępne są pliki procesu Cloud Build:
$DEMO_HOME/workloads/cloudbuild.yaml
(wygenerowany przez Terraform)$DEMO_HOME/workloads/skaffold.yaml
- plik
deployment.yaml
dla każdego zadania
Pliki deployment.yaml
zadań wyglądają nieco inaczej niż pliki wdrożenia usługi backendu.
Oto przykład z tabeli 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"
Górna część pliku definiuje usługę. W tym przypadku tworzony jest zasób LoadBalancer
, a zadanie jest uruchamiane na porcie 8089
.
System równoważenia obciążenia udostępni zewnętrzny adres IP, którego można użyć do połączenia ze zbiorem zadań.
apiVersion: v1
kind: Service
metadata:
name: matchmaking-workload
spec:
type: LoadBalancer
selector:
app: matchmaking-workload
ports:
- port: 8089
targetPort: 8089
Na górze sekcji dotyczącej wdrażania znajdują się metadane dotyczące zadania. W tym przypadku wdrażana jest tylko 1 replika:
replicas: 1
Specyfikacja kontenera jest jednak inna. Po pierwsze używamy konta usługi Kubernetes default
. To konto nie ma żadnych specjalnych uprawnień, ponieważ zbiór zadań nie musi łączyć się z żadnymi zasobami Google Cloud z wyjątkiem usług backendu działających w klastrze GKE.
Druga różnica polega na tym, że dla tych zbiorów zadań nie są potrzebne żadne zmienne środowiskowe. W efekcie powstaje krótsza specyfikacja wdrożenia.
spec:
serviceAccountName: default
containers:
- name: matchmaking-workload
image: matchmaking-workload
ports:
- containerPort: 8089
Ustawienia zasobów są podobne do ustawień usług backendu. Pamiętaj, że dzięki temu Autopilot w GKE wie, ile zasobów jest potrzebnych do spełnienia żądań wszystkich podów działających w klastrze.
Możesz przejść do wdrożenia zadań.
Wdrażanie zadań
Tak jak poprzednio, żądanie kompilacji możesz przesłać za pomocą wiersza poleceń gcloud:
cd $DEMO_HOME/workloads gcloud builds submit --config=cloudbuild.yaml
Dane wyjściowe polecenia
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
Sprawdź stan w logach Cloud Build i potok Cloud Deploy w konsoli Cloud. W przypadku zadań potok Cloud Deploy to sample-game-workloads
:
Po zakończeniu wdrażania sprawdź w Cloud Shell stan elementu kubectl
:
kubectl get pods
Dane wyjściowe polecenia
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
Następnie sprawdź usługi zadań, aby zobaczyć, jak działa LoadBalancer
:
kubectl get services
Dane wyjściowe polecenia
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
Podsumowanie
Zadania zostały wdrożone w klastrze GKE. Te zbiory zadań nie wymagają dodatkowych uprawnień i są dostępne zewnętrznie na porcie 8089 przy użyciu usługi LoadBalancer.
Następne kroki
Pora zagrać, gdy uruchomione są usługi i zadania backendu. grę!
7. Zacznij grać
Omówienie
Usługi backendu w przykładowej „grze” w toku. Masz również możliwość generowania „graczy”, wchodzą w interakcje z tymi usługami za pomocą zbiorów zadań.
Każdy zbiór zadań używa parametru Locust do symulowania rzeczywistego obciążenia w odniesieniu do naszych interfejsów API usługi. W tym kroku uruchomisz kilka zadań, aby wygenerować obciążenie w klastrze GKE i usłudze Spanner, a także przechowywać dane w usłudze Spanner.
Oto opis każdego zadania:
- Zbiór zadań
item-generator
to szybkie zadanie do wygenerowania listy elementów game_items, które gracze mogą zdobyć w trakcie gry w całej grze. profile-workload
symuluje rejestrowanie się i logowanie graczy.matchmaking-workload
symuluje dodawanie graczy do kolejki w celu przypisania ich do gier.game-workload
symuluje pozyskiwanie elementów game_item i pieniędzy w trakcie gry.tradepost-workload
symuluje graczy, którzy mogą sprzedawać i kupować przedmioty na giełdzie.
W tym ćwiczeniu w Codelabs znajdziesz informacje o uruchamianiu tych modułów: item-generator
i profile-workload
.
Uruchom generator produktów
item-generator
używa punktu końcowego usługi backendu item
, aby dodać game_items
do usługi Spanner. Te elementy są niezbędne do prawidłowego działania usług game-workload
i tradepost-workload
.
Pierwszym krokiem jest uzyskanie zewnętrznego adresu IP usługi item-generator
. W Cloud Shell uruchom to polecenie:
# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'
Dane wyjściowe polecenia
{ITEMGENERATOR_EXTERNAL_IP}
Teraz otwórz nową kartę przeglądarki i wskaż http://{ITEMGENERATOR_EXTERNAL_IP}:8089
. Powinna wyświetlić się strona podobna do tej:
Wartości users
i spawn
pozostawisz domyślne 1. W polu host
, wpisz http://item
. Kliknij opcje zaawansowane i wpisz 10s
jako czas trwania.
Konfiguracja powinna wyglądać tak:
Kliknij „Zacznij roju”.
W przypadku żądań wysyłanych do punktu końcowego POST /items
zaczną pojawiać się statystyki. Po 10 sekundach ładowanie się zatrzyma.
Kliknij Charts
, by zobaczyć wykresy pokazujące skuteczność żądań.
Chcesz sprawdzić, czy dane zostały wprowadzone do bazy danych Spanner.
Aby to zrobić, kliknij menu z 3 kreskami i wybierz „Spanner”. Przejdź z tej strony do sample-instance
i sample-database
. Następnie kliknij „Query
”.
Chcemy wybrać liczbę game_items
:
SELECT COUNT(*) FROM game_items;
Na dole zobaczysz wynik.
Nie potrzebujemy wielu danych z game_items
. Teraz jednak gracze mogą je zdobywać!
Uruchamianie zadania profilu
Po roztworzeniu pakietu game_items
musisz zarejestrować graczy, aby mogli grać w gry.
profile-workload
będzie używać Locust do symulowania tworzenia kont, logowania się, pobierania informacji o profilu i wylogowywania się. Wszystkie te testy służą do testowania punktów końcowych usługi backendu profile
w typowym zbiorze zadań przypominającym środowisko produkcyjne.
Aby to uruchomić, uzyskaj zewnętrzny adres IP profile-workload
:
# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'
Dane wyjściowe polecenia
{PROFILEWORKLOAD_EXTERNAL_IP}
Teraz otwórz nową kartę przeglądarki i wskaż http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089
. Powinna wyświetlić się strona Locust podobna do poprzedniej.
W takim przypadku jako hosta będzie używana nazwa http://profile
. W opcjach zaawansowanych nie musisz też określać środowiska wykonawczego. Ustaw też users
na 4, co spowoduje symulację 4 żądań użytkowników naraz.
Test profile-workload
powinien wyglądać tak:
Kliknij „Zacznij roju”.
Tak jak wcześniej, zaczną pojawiać się statystyki różnych punktów końcowych REST profile
. Kliknij, aby przejść do wykresów, aby zobaczyć skuteczność wszystkich elementów.
Podsumowanie
W tym kroku udało Ci się wygenerować game_items
i wysłać zapytanie do tabeli game_items
za pomocą interfejsu zapytań usługi Spanner w konsoli Cloud.
Pozwoliliśmy graczom zarejestrować się w grze i dzięki nim przekonaliśmy się, jak Locust jest w stanie tworzyć zadania produkcyjne z wykorzystaniem usług backendu.
Następne kroki
Po uruchomieniu zadań warto sprawdzić zachowanie klastra GKE i instancji Spannera.
8. Sprawdź wykorzystanie GKE i Spannera
Po uruchomieniu usługi profilu możesz sprawdzić, jak zachowują się Twój klaster z Autopilotem w GKE i Cloud Spanner.
Sprawdzanie klastra GKE
Przejdź do klastra Kubernetes. Zwróć uwagę, że po wdrożeniu zadań i usług w klastrze dodano teraz pewne informacje dotyczące łącznej liczby procesorów wirtualnych i pamięci. Te informacje nie były dostępne, gdy w klastrze nie było żadnych zadań.
Kliknij klaster sample-game-gke
i przełącz się na kartę dostrzegalności:
W przypadku wykorzystania procesora przestrzeń nazw Kubernetes default
powinna przekraczać przestrzeń nazw kube-system
, ponieważ nasze zbiory zadań i usługi backendu działają w systemie default
. Jeśli nie, sprawdź, czy profile workload
jest nadal uruchomiony, i zaczekaj kilka minut, aż wykresy się zaktualizują.
Aby sprawdzić, które zadania zajmują najwięcej zasobów, otwórz panel usługi Workloads
.
Zamiast przechodzić do każdego zadania oddzielnie, przejdź bezpośrednio do karty Dostrzegalność w panelu. Powinno być widać wzrost liczby procesorów profile
i profile-workload
.
Sprawdźmy teraz Cloud Spanner.
Sprawdzanie instancji Cloud Spanner
Aby sprawdzić wydajność Cloud Spanner, przejdź do usługi Spanner i kliknij instancję sample-instance
oraz bazę danych sample-game
.
W menu po lewej stronie zobaczysz kartę Statystyki systemu:
Znajdziesz tu wiele wykresów, które pomogą Ci poznać ogólną wydajność instancji Spannera, w tym CPU utilization
, transaction latency and locking
i query throughput
.
Oprócz statystyk systemowych możesz uzyskać bardziej szczegółowe informacje o zbiorze zadań związanych z zapytaniami, przeglądając inne linki w sekcji Dostrzegalność:
- Statystyki zapytań pomagają zidentyfikować N najczęstszych zapytań korzystających z zasobów usługi Spanner.
- Statystyki transakcji i blokad pomagają identyfikować transakcje o dużych opóźnieniach.
- Narzędzie Key Visualizer pomaga wizualizować wzorce dostępu i ułatwia wykrywanie hotspotów w danych.
Podsumowanie
W tym kroku omówiliśmy, jak sprawdzić niektóre podstawowe wskaźniki wydajności zarówno w przypadku Autopilota w GKE, jak i usługi Spanner.
Na przykład po uruchomieniu zadania profilu wykonaj zapytanie do tabeli players, aby uzyskać więcej informacji na temat przechowywanych w niej danych.
Następne kroki
Czas posprzątać!
9. Czyszczenie
Zanim zaczniesz porządki, przejrzyj inne zadania, które nie zostały uwzględnione. W szczególności chodzi o matchmaking-workload
, game-workload
i tradepost-workload
.
Gdy skończysz grać podczas gry, posprzątaj swój plac zabaw. Na szczęście to całkiem proste.
Najpierw, jeśli usługa profile-workload
nadal działa w przeglądarce, zatrzymaj ją i ją zatrzymaj:
Wykonaj te same czynności w przypadku każdego przetestowanego zadania.
Następnie w Cloud Shell przejdź do folderu infrastruktury. destroy
infrastrukturę za pomocą Terraform:
cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked
Dane wyjściowe polecenia
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.
W konsoli Cloud otwórz Spanner
, Kubernetes Cluster
, Artifact Registry
, Cloud Deploy
i IAM
, aby sprawdzić, czy wszystkie zasoby zostały usunięte.
10. Gratulacje!
Gratulujemy! Udało Ci się wdrożyć przykładowe aplikacje golang w Autopilocie w GKE i połączyć je z Cloud Spanner za pomocą Workload Identity.
Dodatkową zaletą tej infrastruktury było łatwe skonfigurowanie i usunięcie jej w powtarzalny sposób za pomocą Terraform.
Więcej informacji o usługach Google Cloud, z którymi wchodzisz w interakcje, znajdziesz w tym ćwiczeniu z programowania:
Co dalej?
Skoro wiesz już, jak mogą współdziałać Autopilot w GKE i Cloud Spanner, możesz wykonać kolejny krok i zacząć tworzyć własną aplikację do pracy z tymi usługami.