Informacje o tym ćwiczeniu (w Codelabs)
1. Wprowadzenie
Omówienie
Funkcje Cloud Run to usługa Google Cloud typu funkcje jako usługa oparta na technologii Cloud Run i Eventarc, która zapewnia zaawansowaną kontrolę nad wydajnością i skalowalnością oraz większą kontrolę nad środowiskiem wykonawczym funkcji i aktywatorami z ponad 90 źródeł zdarzeń.
W tym laboratorium programistycznym dowiesz się, jak tworzyć funkcje Cloud Run, które reagują na wywołania HTTP i są uruchamiane przez wiadomości Pub/Sub oraz logi kontrolne Cloud.
Ten warsztat kodowania korzysta też z automatycznych aktualizacji obrazu podstawowego na potrzeby wdrażania funkcji, określając obraz podstawowy za pomocą flagi --base-image
. Automatyczne aktualizacje obrazu podstawowego w Cloud Run umożliwiają Google automatyczne wprowadzanie poprawek zabezpieczeń do systemu operacyjnego i komponentów środowiska wykonawczego języka w obrazie podstawowym. Nie musisz ponownie tworzyć ani wdrażać usługi, aby zaktualizować obraz bazowy. Więcej informacji znajdziesz w artykule Automatyczne aktualizacje obrazu bazowego.
Jeśli wolisz nie używać automatycznych aktualizacji obrazu bazowego, możesz usunąć flagę --base-image
z przykładów pokazanych w tym laboratorium kodu.
Czego się nauczysz
- Omówienie funkcji Cloud Run i sposobu korzystania z automatycznych aktualizacji obrazu bazowego.
- Jak napisać funkcję, która odpowiada na wywołania HTTP.
- Jak napisać funkcję, która odpowiada na wiadomości Pub/Sub.
- Jak napisać funkcję, która reaguje na zdarzenia Cloud Storage.
- Jak podzielić ruch między 2 wersje.
- Jak pozbyć się uruchomień „na zimno” za pomocą minimalnej liczby instancji
2. Konfiguracja i wymagania
Tworzenie folderu głównego
Utwórz folder główny ze wszystkimi przykładami.
mkdir crf-codelab cd crf-codelab
Konfigurowanie zmiennych środowiskowych
Ustaw zmienne środowiskowe, których będziesz używać w trakcie tego ćwiczenia.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
Włącz interfejsy API
Włącz wszystkie niezbędne usługi:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. Funkcja HTTP
W pierwszej kolejności utwórz funkcję Node.js, która odpowiada na żądania HTTP i która jest uwierzytelniana. Użyjemy też 10-minutowego limitu czasu, aby pokazać, że funkcja może mieć więcej czasu na odpowiadanie na żądania HTTP.
Utwórz
Utwórz folder aplikacji i otwórz go:
mkdir hello-http cd hello-http
Utwórz plik index.js
, który odpowiada na żądania HTTP:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
Utwórz plik package.json
, aby określić zależności:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Wdróż
Wdróż funkcję:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
To polecenie używa pakietów kompilacji do przekształcenia kodu źródłowego funkcji w obraz kontenera gotowy do użycia w środowisku produkcyjnym.
Uwaga:
- flaga
--source
służy do informowania Cloud Run o konieczności skompilowania funkcji w celu utworzenia uruchomialnej usługi opartej na kontenerze. - flaga
--function
(nowa) służy do ustawienia punktu wejścia nowej usługi jako sygnatury funkcji, którą chcesz wywołać. - flaga
--base-image
(nowa) określa środowisko obrazu podstawowego dla funkcji, np.nodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
lubphp83
. Więcej informacji o obrazach bazowych i pakietach zawartych w każdym obrazie znajdziesz w artykule Obrazy bazowe Runtimes. - (opcjonalnie) flaga
--timeout
pozwala funkcji na dłuższy limit czasu odpowiedzi na żądania HTTP. W tym przykładzie użyto 600 sekund, aby zademonstrować czas odpowiedzi wynoszący 10 minut. - (opcjonalnie)
--no-allow-unauthenticated
, aby uniemożliwić wywołanie funkcji przez innych użytkowników
Test
Przetestuj funkcję za pomocą tych poleceń:
# get the Service URL SERVICE_URL="$(gcloud run services describe nodejs-run-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
W odpowiedzi powinien wyświetlić się komunikat HTTP with Node.js in Cloud Run functions!
.
4. Funkcja Pub/Sub
Drugą funkcję, którą utworzymy, będzie funkcja w Pythonie, która będzie wywoływana przez wiadomość Pub/Sub opublikowaną w określonym temacie.
Konfigurowanie tokenów uwierzytelniających Pub/Sub
Jeśli konto usługi Pub/Sub zostało włączone 8 kwietnia 2021 r. lub wcześniej, przypisz do niego rolę iam.serviceAccountTokenCreator
:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
Utwórz
Utwórz temat Pub/Sub, który będzie używany w przykładzie:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
Utwórz folder aplikacji i otwórz go:
mkdir ../hello-pubsub cd ../hello-pubsub
Utwórz plik main.py
, który rejestruje wiadomość zawierającą identyfikator CloudEvent:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in Cloud Run functions! Id: ' + cloud_event['id'])
Aby określić zależności, utwórz plik requirements.txt
z podaną niżej treścią:
functions-framework==3.*
Wdróż
Wdróż funkcję:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
Pobierz numer projektu, który będzie używany do identyfikacji konta usługi.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
Tworzenie aktywatora
gcloud eventarc triggers create python-pubsub-function-trigger \ --location=$REGION \ --destination-run-service=python-pubsub-function \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Test
Przetestuj funkcję, wysyłając wiadomość do tematu:
gcloud pubsub topics publish $TOPIC --message="Hello World"
W logach powinien pojawić się otrzymany CloudEvent:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Funkcja Cloud Storage
Następną funkcję utwórz w Node.js, aby reagowała na zdarzenia z zasobinku Cloud Storage.
Skonfiguruj
Aby używać funkcji Cloud Storage, przypisz do konta usługi Cloud Storage rolę uprawnień pubsub.publisher
:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
Utwórz
Utwórz folder aplikacji i otwórz go:
mkdir ../hello-storage cd ../hello-storage
Utwórz plik index.js
, który po prostu reaguje na zdarzenia Cloud Storage:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in Cloud Run functions!'); console.log(cloudevent); });
Utwórz plik package.json
, aby określić zależności:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
Wdróż
Najpierw utwórz zasobnik Cloud Storage (lub użyj istniejącego zasobnika):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
Wdróż funkcję:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
Po wdrożeniu funkcji możesz ją wyświetlić w sekcji Cloud Run w Cloud Console.
Teraz utwórz aktywator Eventarc.
BUCKET_REGION=$REGION gcloud eventarc triggers create nodejs-crf-cloud-storage-trigger \ --location=$BUCKET_REGION \ --destination-run-service=nodejs-crf-cloud-storage \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
Test
Przetestuj funkcję, przesyłając plik do zasobnika:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
W logach powinien pojawić się otrzymany CloudEvent:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. Dzielenie ruchu
Funkcje Cloud Run obsługują wiele wersji funkcji, dzieląc ruch między różne wersje i przywracając funkcję do poprzedniej wersji.
W tym kroku wdroż 2 wersje funkcji, a następnie podziel ruch między nimi w proporcji 50–50.
Utwórz
Utwórz folder aplikacji i otwórz go:
mkdir ../traffic-splitting cd ../traffic-splitting
Utwórz plik main.py
z funkcją Pythona, która odczytuje zmienną środowiskową koloru i odpowie Hello World
w tym kolorze tła:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
Aby określić zależności, utwórz plik requirements.txt
z podaną niżej treścią:
functions-framework==3.*
Wdróż
Wdróż pierwszą wersję funkcji z pomarańczowym tłem:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Jeśli w tym momencie otworzysz w przeglądarce funkcję, aby wyświetlić w niej aktywator HTTP (dane wyjściowe URI z powyższego polecenia wdrożenia), powinna się ona wyświetlić na pomarańczowym tle: Hello World
.
Wdróż drugą wersję z żółtym tłem:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
Ponieważ jest to najnowsza wersja, podczas testowania funkcji powinieneś/powinnaś zobaczyć Hello World
z żółtym tłem:
Podział ruchu na 50–50
Aby podzielić ruch na wersje pomarańczową i żółtą, musisz znaleźć identyfikatory wersji usług Cloud Run. Aby wyświetlić identyfikatory wersji, użyj tego polecenia:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
Dane wyjściowe powinny być podobne do tych:
hello-world-colors-00001-man hello-world-colors-00002-wok
Teraz podziel ruch między te 2 wersje w ten sposób: (zaktualizuj X-XXX
zgodnie z nazwami swoich wersji):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
Test
Przetestuj funkcję, otwierając jej publiczny adres URL. Połowa wersji powinna być pomarańczowa, a druga połowa żółta:
Więcej informacji znajdziesz w artykule Przywracanie, wdrażanie stopniowe i migracja ruchu.
7. Minimalna liczba instancji
W funkcjach Cloud Run możesz określić minimalną liczbę instancji funkcji, które mają być utrzymywane w gotowości do obsługi żądań. Jest to przydatne, ponieważ ogranicza liczbę uruchomień „na zimno”.
W tym kroku wdrożysz funkcję z wolną inicjalizacją. Zaobserwujesz problem z uruchomieniem „na zimno”. Następnie wdróż funkcję z wartością minimalnej liczby instancji ustawioną na 1, aby uniknąć uruchomień „na zimno”.
Utwórz
Utwórz folder aplikacji i otwórz go:
mkdir ../min-instances cd ../min-instances
Utwórz plik main.go
. Ta usługa w Go ma funkcję init
, która czeka 10 sekund, aby symulować długą inicjalizację. Ma też funkcję HelloWorld
, która odpowiada na wywołania HTTP:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in Cloud Run functions!") }
Wdróż
Wdróż pierwszą wersję funkcji z domyślną minimalną wartością instancji równą 0:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
Testowanie funkcji za pomocą tego polecenia:
# get the Service URL SERVICE_URL="$(gcloud run services describe go-slow-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
W przypadku pierwszego wywołania nastąpi 10-sekundowa zwłoka (zimny start), a potem zobaczysz wiadomość. Kolejne wywołania powinny być realizowane natychmiast.
Ustawianie minimalnej liczby instancji
Aby uniknąć uruchamiania „na zimno” przy pierwszym żądaniu, ponownie wdrożyć funkcję z flagą --min-instances
ustawioną na 1 w następujący sposób:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
Test
Ponownie przetestuj funkcję:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
Opóźnienie 10 sekund nie powinno już występować w przypadku pierwszego żądania. Dzięki minimalnej liczbie instancji problem z uruchomieniem „na zimno” podczas pierwszego wywołania (po długim czasie bez wywołania) został rozwiązany.
Więcej informacji znajdziesz w artykule o minimalnej liczbie instancji.
8. Gratulacje!
Gratulujemy ukończenia ćwiczeń.
Omówione zagadnienia
- Omówienie funkcji Cloud Run i sposobu korzystania z automatycznych aktualizacji obrazu bazowego.
- Jak napisać funkcję, która odpowiada na wywołania HTTP.
- Jak napisać funkcję, która odpowiada na wiadomości Pub/Sub.
- Jak napisać funkcję, która reaguje na zdarzenia Cloud Storage.
- Jak podzielić ruch między 2 wersje.
- Jak pozbyć się uruchomień „na zimno” za pomocą minimalnej liczby instancji