Wprowadzenie do bezserwerowej administracji w Workflows

1. Wprowadzenie

c9b0cc839df0bb8f.png

Przepływy pracy umożliwiają tworzenie bezserwerowych przepływów pracy, które łączą serię bezserwerowych zadań w określonej przez Ciebie kolejności. Możesz połączyć możliwości interfejsów API Google Cloud, usług bezserwerowych, takich jak Cloud Functions i Cloud Run, oraz wywołań zewnętrznych interfejsów API, aby tworzyć elastyczne aplikacje bezserwerowe.

Przepływy pracy nie wymagają zarządzania infrastrukturą i sprawnie skalują się wraz z zapotrzebowaniem, w tym skalowanie do zera. W przypadku modelu płatności tylko za wykorzystanie zasoby płacisz jedynie za czas wykonywania.

Z tego ćwiczenia w Codelabs dowiesz się, jak łączyć różne usługi Google Cloud i zewnętrzne interfejsy API HTTP przy użyciu Workflows. Dokładniej rzecz ujmując, w przepływie pracy połączysz 2 publiczne usługi Cloud Functions – 1 prywatną usługę Cloud Run i zewnętrzny publiczny interfejs API HTTP.

Czego się nauczysz

  • Podstawy Workflows.
  • Jak połączyć publiczne funkcje w Cloud Functions z Workflows.
  • Łączenie prywatnych usług Cloud Run z Workflows.
  • Łączenie zewnętrznych interfejsów API HTTP z Workflows.

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail lub G Suite, musisz je utworzyć.

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

Zapamiętaj identyfikator projektu, unikalną 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 Codelabs będzie ona określana jako PROJECT_ID.

  1. Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Google Cloud.

Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Postępuj zgodnie z instrukcjami podanymi w sekcji „Czyszczenie” W tym samouczku znajdziesz wskazówki, jak wyłączyć zasoby, aby uniknąć naliczania opłat. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Uruchamianie Cloud Shell

Google Cloud można obsługiwać zdalnie z laptopa, ale w ramach tego ćwiczenia z programowania wykorzystasz Google Cloud Shell – środowisko wiersza poleceń działające w chmurze.

W konsoli GCP kliknij ikonę Cloud Shell na górnym pasku narzędzi:

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

Uzyskanie dostępu do środowiska i połączenie się z nim powinno zająć tylko kilka chwil. Po zakończeniu powinno pojawić się coś takiego:

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, znacząco zwiększając wydajność sieci i uwierzytelnianie. Wszystkie zadania w tym module możesz wykonać w przeglądarce.

3. Omówienie przepływów pracy

Podstawy

Przepływ pracy składa się z serii kroków opisanych za pomocą składni YAML Workflows. To jest definicja przepływu pracy. Szczegółowe omówienie składni YAML Workflows znajdziesz na stronie z informacjami o składni.

Podczas tworzenia przepływu pracy jest on wdrażany, dzięki czemu jest on gotowy do wykonania. Wykonanie to jednorazowe uruchomienie logiki zawartej w definicji przepływu pracy. Wszystkie wykonania przepływu pracy są niezależne, a usługa obsługuje dużą liczbę jednoczesnych wykonań.

Włączanie usług

W tym ćwiczeniu w Codelabs połączysz usługi Cloud Functions i Cloud Run z Workflows. Podczas tworzenia usług będziesz też używać Cloud Build i Cloud Storage.

Włącz wszystkie niezbędne usługi:

gcloud services enable \
  cloudfunctions.googleapis.com \
  run.googleapis.com \
  workflows.googleapis.com \
  cloudbuild.googleapis.com \
  storage.googleapis.com

W następnym kroku połączysz 2 funkcje w Cloud Functions w ramach przepływu pracy.

4. Wdróż pierwszą funkcję w Cloud Functions

Pierwszą funkcją jest generator liczb losowych w Pythonie.

Utwórz katalog i przejdź do katalogu z kodem funkcji:

mkdir ~/randomgen
cd ~/randomgen

Utwórz w katalogu plik main.py o następującej treści:

import random, json
from flask import jsonify

def randomgen(request):
    randomNum = random.randint(1,100)
    output = {"random":randomNum}
    return jsonify(output)

Po otrzymaniu żądania HTTP ta funkcja generuje losową liczbę od 1 do 100 i zwraca w formacie JSON z powrotem do elementu wywołującego.

Funkcja ta korzysta z platformy Flask do przetwarzania HTTP i trzeba ją dodać jako zależność. Zależnościami w Pythonie zarządza się za pomocą pip i są wyrażane w pliku metadanych o nazwie requirements.txt.

W tym samym katalogu utwórz plik requirements.txt z tą zawartością:

flask>=1.0.2

Wdróż funkcję za pomocą aktywatora HTTP, przy czym żądania nieuwierzytelnione są dozwolone za pomocą tego polecenia:

gcloud functions deploy randomgen \
    --runtime python37 \
    --trigger-http \
    --allow-unauthenticated

Po wdrożeniu funkcji adres URL funkcji we właściwości httpsTrigger.url możesz zobaczyć w konsoli lub za pomocą polecenia gcloud functions describe.

Możesz też otworzyć adres URL funkcji za pomocą tego polecenia curl:

curl $(gcloud functions describe randomgen --format='value(httpsTrigger.url)')

Funkcja jest gotowa do wykonania przepływu pracy.

5. Wdróż drugą funkcję w Cloud Functions

Druga funkcja jest mnożnikiem. Mnoży ona odebrane dane wejściowe przez 2.

Utwórz katalog i przejdź do katalogu z kodem funkcji:

mkdir ~/multiply
cd ~/multiply

Utwórz w katalogu plik main.py o następującej treści:

import random, json
from flask import jsonify

def multiply(request):
    request_json = request.get_json()
    output = {"multiplied":2*request_json['input']}
    return jsonify(output)

Po otrzymaniu żądania HTTP ta funkcja wyodrębnia input z treści JSON, mnoży ją przez 2 i zwraca w formacie JSON z powrotem do elementu wywołującego.

W tym samym katalogu utwórz ten sam plik requirements.txt z następującą zawartością:

flask>=1.0.2

Wdróż funkcję za pomocą aktywatora HTTP, przy czym żądania nieuwierzytelnione są dozwolone za pomocą tego polecenia:

gcloud functions deploy multiply \
    --runtime python37 \
    --trigger-http \
    --allow-unauthenticated

Po wdrożeniu funkcji możesz też otworzyć jej adres URL za pomocą tego polecenia curl:

curl $(gcloud functions describe multiply --format='value(httpsTrigger.url)') \
-X POST \
-H "content-type: application/json" \
-d '{"input": 5}'

Funkcja jest gotowa do wykonania przepływu pracy.

6. Połącz 2 funkcje w Cloud Functions

W pierwszym przepływie pracy połącz obie funkcje.

Utwórz plik workflow.yaml o następującej zawartości.

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- returnResult:
    return: ${multiplyResult}

W tym przepływie pracy z pierwszej funkcji otrzymujesz liczbę losową i przekazujesz ją do drugiej. Wynik to pomnożona liczba losowa.

Wdróż pierwszy przepływ pracy:

gcloud workflows deploy workflow --source=workflow.yaml

Wykonaj pierwszy przepływ pracy:

gcloud workflows execute workflow

Po wykonaniu przepływu pracy możesz zobaczyć wynik, przekazując identyfikator wykonania podany w poprzednim kroku:

gcloud workflows executions describe <your-execution-id> --workflow workflow

Dane wyjściowe obejmują wartości result i state:

result: '{"body":{"multiplied":108},"code":200 ... } 

...
state: SUCCEEDED

7. Połącz zewnętrzny interfejs API HTTP

Następnie połącz w przepływie pracy math.js jako usługę zewnętrzną.

W pliku math.js możesz oceniać wyrażenia matematyczne w ten sposób:

curl https://api.mathjs.org/v4/?'expr=log(56)'

Tym razem do aktualizacji przepływu pracy użyjesz Cloud Console. Znajdź Workflows w konsoli Google Cloud:

7608a7991b33bbb0.png

Odszukaj odpowiedni przepływ pracy i kliknij kartę Definition:

f3c8c4d3ffa49b1b.png

Edytuj definicję przepływu pracy i dodaj wywołanie math.js.

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- returnResult:
    return: ${logResult}

Przepływ pracy przekazuje teraz dane wyjściowe funkcji mnożenia do wywołania funkcji logu w math.js.

Interfejs zawiera instrukcje edytowania i wdrażania przepływu pracy. Po wdrożeniu kliknij Execute, aby wykonać przepływ pracy. Zobaczysz szczegóły wykonania kodu:

b40c76ee43a1ce65.png

Zwróć uwagę na kod stanu 200 i body z danymi wyjściowymi funkcji logu.

Właśnie udało Ci się zintegrować usługę zewnętrzną z naszym przepływem pracy. Super!

8. Wdrażanie usługi Cloud Run

W ostatniej części dokończ przepływ pracy, wywołując prywatną usługę Cloud Run. Oznacza to, że aby wywołać usługę Cloud Run, przepływ pracy musi być uwierzytelniony.

Usługa Cloud Run zwraca math.floor z przekazanej liczby.

Utwórz katalog z kodem usługi i przejdź do niego:

mkdir ~/floor
cd ~/floor

Utwórz w katalogu plik app.py o następującej treści:

import json
import logging
import os
import math

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['POST'])
def handle_post():
    content = json.loads(request.data)
    input = float(content['input'])
    return f"{math.floor(input)}", 200

if __name__ != '__main__':
    # Redirect Flask logs to Gunicorn logs
    gunicorn_logger = logging.getLogger('gunicorn.error')
    app.logger.handlers = gunicorn_logger.handlers
    app.logger.setLevel(gunicorn_logger.level)
    app.logger.info('Service started...')
else:
    app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

Cloud Run wdraża kontenery, więc potrzebujesz Dockerfile, a kontener musi być powiązany ze zmienną środowiskową 0.0.0.0 i PORT, więc kod jest opisany powyżej.

Po otrzymaniu żądania HTTP ta funkcja wyodrębnia input z treści JSON, wywołuje funkcję math.floor i zwraca wynik z powrotem do elementu wywołującego.

W tym samym katalogu utwórz taki plik Dockerfile:

# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.7-slim

# Install production dependencies.
RUN pip install Flask gunicorn

# Copy local code to the container image.
WORKDIR /app
COPY . .

# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

Utwórz kontener:

export SERVICE_NAME=floor
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}

Po skompilowaniu kontenera wdróż go w Cloud Run. Zwróć uwagę na flagę no-allow-unauthenticated. Dzięki temu usługa będzie akceptować tylko uwierzytelnione połączenia:

gcloud run deploy ${SERVICE_NAME} \
  --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
  --platform managed \
  --no-allow-unauthenticated

Po wdrożeniu usługa jest gotowa do pracy.

9. Łączenie usługi Cloud Run

Zanim skonfigurujesz Workflows pod kątem wywoływania prywatnej usługi Cloud Run, musisz utworzyć konto usługi do wykorzystania przez Workflows:

export SERVICE_ACCOUNT=workflows-sa
gcloud iam service-accounts create ${SERVICE_ACCOUNT}

Przypisz do konta usługi rolę run.invoker. Pozwoli to kontu usługi na wywoływanie uwierzytelnionych usług Cloud Run:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
    --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
    --role "roles/run.invoker"

Zaktualizuj definicję przepływu pracy w workflow.yaml, aby uwzględnić usługę Cloud Run. Zwróć uwagę, że uwzględniasz również pole auth, aby usługa Workflows przekazywał token uwierzytelniania w wywołaniach usługi Cloud Run:

- randomgenFunction:
    call: http.get
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/randomgen
    result: randomgenResult
- multiplyFunction:
    call: http.post
    args:
        url: https://<region>-<project-id>.cloudfunctions.net/multiply
        body:
            input: ${randomgenResult.body.random}
    result: multiplyResult
- logFunction:
    call: http.get
    args:
        url: https://api.mathjs.org/v4/
        query:
            expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"}
    result: logResult
- floorFunction:
    call: http.post
    args:
        url: https://floor-<random-hash>.run.app
        auth:
            type: OIDC
        body:
            input: ${logResult.body}
    result: floorResult
- returnResult:
    return: ${floorResult}

Zaktualizuj przepływ pracy. Tym razem na koncie usługi:

gcloud workflows deploy workflow \
    --source=workflow.yaml \
    --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Wykonaj przepływ pracy:

gcloud workflows execute workflow

Już za kilka sekund możesz przyjrzeć się wykonaniu przepływu pracy, by poznać efekt:

gcloud workflows executions describe <your-execution-id> --workflow workflow

Dane wyjściowe będą zawierać liczby całkowitą result i state:

result: '{"body":"5","code":200 ... } 

...
state: SUCCEEDED

10. Gratulacje!

Gratulujemy ukończenia ćwiczeń z programowania.

Omówione zagadnienia

  • Podstawy Workflows.
  • Jak połączyć publiczne funkcje w Cloud Functions z Workflows.
  • Łączenie prywatnych usług Cloud Run z Workflows.
  • Łączenie zewnętrznych interfejsów API HTTP z Workflows.