Введение в бессерверную оркестровку с помощью рабочих процессов

1. Введение

c9b0cc839df0bb8f.png

Вы можете использовать рабочие процессы для создания бессерверных рабочих процессов, которые связывают ряд бессерверных задач в заданном вами порядке. Вы можете объединить возможности API Google Cloud, бессерверных продуктов, таких как Cloud Functions и Cloud Run, и вызовов внешних API для создания гибких бессерверных приложений.

Рабочие процессы не требуют управления инфраструктурой и легко масштабируются в зависимости от спроса, включая масштабирование до нуля. Благодаря модели ценообразования с оплатой по факту использования вы платите только за время выполнения.

В этой лаборатории кода вы узнаете, как подключать различные сервисы Google Cloud и внешние API-интерфейсы HTTP к рабочим процессам. В частности, вы подключите к рабочему процессу две общедоступные службы Cloud Functions, одну частную службу Cloud Run и внешний общедоступный HTTP API.

Что вы узнаете

  • Основы рабочих процессов.
  • Как связать функции общедоступного облака с рабочими процессами.
  • Как подключить частные службы Cloud Run к рабочим процессам.
  • Как подключить внешние HTTP API к рабочим процессам.

2. Настройка и требования

Самостоятельная настройка среды

  1. Войдите в Cloud Console и создайте новый проект или повторно используйте существующий. (Если у вас еще нет учетной записи Gmail или G Suite, вам необходимо ее создать .)

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

Запомните идентификатор проекта — уникальное имя для всех проектов Google Cloud (имя, указанное выше, уже занято и не подойдет вам, извините!). Позже в этой лаборатории он будет называться PROJECT_ID .

  1. Далее вам необходимо включить биллинг в Cloud Console, чтобы использовать ресурсы Google Cloud.

Прохождение этой лаборатории кода не должно стоить много, если вообще стоит. Обязательно следуйте всем инструкциям в разделе «Очистка», в которых рассказывается, как отключить ресурсы, чтобы вам не приходилось нести расходы, выходящие за рамки этого руководства. Новые пользователи Google Cloud имеют право на участие в программе бесплатной пробной версии стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лаборатории вы будете использовать Google Cloud Shell , среду командной строки, работающую в облаке.

В консоли GCP щелкните значок Cloud Shell на верхней правой панели инструментов:

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

Подготовка и подключение к среде займет всего несколько минут. Когда все будет готово, вы должны увидеть что-то вроде этого:

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

Эта виртуальная машина оснащена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лабораторной работе можно выполнять с помощью простого браузера.

3. Обзор рабочих процессов

Основы

Рабочий процесс состоит из ряда шагов, описанных с использованием синтаксиса рабочих процессов на основе YAML. Это определение рабочего процесса. Подробное объяснение синтаксиса YAML рабочих процессов см. на странице справки по синтаксису .

Когда рабочий процесс создан, он развертывается, что делает рабочий процесс готовым к выполнению. Выполнение — это одиночный запуск логики, содержащейся в определении рабочего процесса. Все выполнения рабочих процессов независимы, и продукт поддерживает большое количество одновременных выполнения.

Включить службы

В этой лаборатории кода вы будете подключать облачные функции, службы Cloud Run с рабочими процессами. Вы также будете использовать Cloud Build и Cloud Storage при создании сервисов.

Включите все необходимые службы:

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

На следующем шаге вы соедините две облачные функции в рабочий процесс.

4. Разверните первую облачную функцию

Первая функция — это генератор случайных чисел в Python.

Создайте и перейдите в каталог для кода функции:

mkdir ~/randomgen
cd ~/randomgen

Создайте в каталоге файл main.py со следующим содержимым:

import random, json
from flask import jsonify

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

Когда она получает HTTP-запрос, эта функция генерирует случайное число от 1 до 100 и возвращает его в формате JSON обратно вызывающей стороне.

Функция использует Flask для обработки HTTP, и нам нужно добавить это как зависимость. Зависимости в Python управляются с помощью pip и выражаются в файле метаданных с именем requirements.txt .

Создайте файл requirements.txt в том же каталоге со следующим содержимым:

flask>=1.0.2

Разверните функцию с помощью HTTP-триггера и разрешив неаутентифицированные запросы с помощью этой команды:

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

После развертывания функции вы можете увидеть URL-адрес функции в свойстве httpsTrigger.url , отображаемом в консоли или отображаемом с помощью команды gcloud functions describe .

Вы также можете посетить этот URL-адрес функции с помощью следующей команды curl :

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

Функция готова к рабочему процессу.

5. Развертывание второй облачной функции

Вторая функция — множитель. Он умножает полученный ввод на 2.

Создайте и перейдите в каталог для кода функции:

mkdir ~/multiply
cd ~/multiply

Создайте в каталоге файл main.py со следующим содержимым:

import random, json
from flask import jsonify

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

Когда она получает HTTP-запрос, эта функция извлекает input из тела JSON, умножает их на 2 и возвращает в формате JSON обратно вызывающей стороне.

Создайте тот же файл requirements.txt в том же каталоге со следующим содержимым:

flask>=1.0.2

Разверните функцию с помощью HTTP-триггера и разрешив неаутентифицированные запросы с помощью этой команды:

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

После развертывания функции вы также можете посетить этот URL-адрес функции с помощью следующей команды curl :

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

Функция готова к рабочему процессу.

6. Подключите две облачные функции

В первом рабочем процессе соедините две функции вместе.

Создайте файл workflow.yaml со следующим содержимым.

- 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}

В этом рабочем процессе вы получаете случайное число из первой функции и передаете его второй функции. Результатом является умноженное случайное число.

Разверните первый рабочий процесс:

gcloud workflows deploy workflow --source=workflow.yaml

Выполните первый рабочий процесс:

gcloud workflows execute workflow

После выполнения рабочего процесса вы можете увидеть результат, передав идентификатор выполнения, указанный на предыдущем шаге:

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

Вывод будет включать result и state :

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

...
state: SUCCEEDED

7. Подключите внешний HTTP API

Далее вы подключите math.js как внешний сервис в рабочем процессе.

В math.js вы можете вычислять математические выражения следующим образом:

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

На этот раз вы будете использовать Cloud Console для обновления нашего рабочего процесса. Найдите Workflows в Google Cloud Console:

7608a7991b33bbb0.png

Найдите свой рабочий процесс и нажмите вкладку Definition :

f3c8c4d3ffa49b1b.png

Отредактируйте определение рабочего процесса и включите вызов 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}

Рабочий процесс теперь передает выходные данные функции умножения в вызов функции журнала в math.js

Пользовательский интерфейс поможет вам отредактировать и развернуть рабочий процесс. После развертывания нажмите Execute , чтобы выполнить рабочий процесс. Вы увидите детали выполнения:

b40c76ee43a1ce65.png

Обратите внимание на код состояния 200 и body с выводом функции журнала.

Вы только что интегрировали внешний сервис в наш рабочий процесс, супер круто!

8. Развертывание службы Cloud Run

В последней части завершите рабочий процесс вызовом частной службы Cloud Run. Это означает, что рабочий процесс должен пройти аутентификацию для вызова службы Cloud Run.

Служба Cloud Run возвращает math.floor переданного числа.

Создайте и перейдите в каталог для кода службы:

mkdir ~/floor
cd ~/floor

Создайте в каталоге файл app.py со следующим содержимым:

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 развертывает контейнеры, поэтому вам нужен Dockerfile , и ваш контейнер должен быть привязан к 0.0.0.0 и переменной env PORT , отсюда и приведенный выше код.

Когда она получает HTTP-запрос, эта функция извлекает input из тела JSON, вызывает math.floor и возвращает результат обратно вызывающей стороне.

В том же каталоге создайте следующий 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

Создайте контейнер:

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

После создания контейнера разверните его в Cloud Run. Обратите внимание на флаг no-allow-unauthenticated . Это гарантирует, что служба принимает только аутентифицированные вызовы:

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

После развертывания служба готова к рабочему процессу.

9. Подключите сервис Cloud Run.

Прежде чем вы сможете настроить рабочие процессы для вызова частной службы Cloud Run, вам необходимо создать учетную запись службы, которую рабочие процессы смогут использовать:

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

Предоставьте роль run.invoker учетной записи службы. Это позволит сервисному аккаунту вызывать проверенные службы 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"

Обновите определение рабочего процесса в workflow.yaml , чтобы включить службу Cloud Run. Обратите внимание, что вы также включаете поле auth , чтобы рабочие процессы передавали токен аутентификации при вызовах службы 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}

Обновите рабочий процесс. На этот раз перейдя в сервис-аккаунт:

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

Выполните рабочий процесс:

gcloud workflows execute workflow

Через несколько секунд вы сможете взглянуть на выполнение рабочего процесса и увидеть результат:

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

Вывод будет включать в себя целочисленный result и state :

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

...
state: SUCCEEDED

10. Поздравляем!

Поздравляем с завершением работы над кодом.

Что мы рассмотрели

  • Основы рабочих процессов.
  • Как связать функции общедоступного облака с рабочими процессами.
  • Как подключить частные службы Cloud Run к рабочим процессам.
  • Как подключить внешние API HTTP к рабочим процессам.