ข้อมูลเบื้องต้นเกี่ยวกับการจัดการเป็นกลุ่มแบบ Serverless ด้วยเวิร์กโฟลว์

ข้อมูลเบื้องต้นเกี่ยวกับการจัดการเป็นกลุ่มแบบ Serverless ด้วยเวิร์กโฟลว์

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ เม.ย. 15, 2021
account_circleเขียนโดย atamel

1 บทนำ

c9b0cc839df0bb8f.png

คุณสามารถใช้เวิร์กโฟลว์เพื่อสร้างเวิร์กโฟลว์แบบ Serverless ที่จะลิงก์งานแบบ Serverless ต่างๆ เข้าด้วยกันตามลำดับที่คุณกำหนด คุณสามารถผสานรวมประสิทธิภาพของ API ของ Google Cloud, ผลิตภัณฑ์แบบ Serverless เช่น Cloud Functions และ Cloud Run และการเรียก API ภายนอกเพื่อสร้างแอปพลิเคชันแบบ Serverless ที่ยืดหยุ่นได้

เวิร์กโฟลว์ไม่จำเป็นต้องใช้การจัดการโครงสร้างพื้นฐานและปรับขนาดได้อย่างราบรื่นตามดีมานด์ ซึ่งรวมถึงการลดทรัพยากรลงเป็น 0 ด้วยรูปแบบการกำหนดราคาแบบจ่ายต่อการใช้งาน คุณจะจ่ายเฉพาะเวลาในการดำเนินการเท่านั้น

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีเชื่อมต่อบริการต่างๆ ของ Google Cloud และ HTTP API ภายนอกด้วย Workflows กล่าวอย่างเจาะจงก็คือ คุณจะเชื่อมต่อบริการ Cloud Functions สาธารณะ 2 บริการ ได้แก่ บริการ Cloud Run ส่วนตัว 1 บริการและ HTTP API สาธารณะภายนอกเข้ากับเวิร์กโฟลว์

สิ่งที่คุณจะได้เรียนรู้

  • ข้อมูลพื้นฐานของเวิร์กโฟลว์
  • วิธีเชื่อมต่อ Cloud Functions สาธารณะกับเวิร์กโฟลว์
  • วิธีเชื่อมต่อบริการ 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 ทั้งหมด (ชื่อด้านบนมีคนใช้แล้ว และจะใช้ไม่ได้ ขออภัย) และจะมีการอ้างอิงใน Codelab ว่า PROJECT_ID ในภายหลัง

  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร Google Cloud

การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี ตรวจสอบว่าคุณได้ทำตามวิธีการใน "การล้างข้อมูล" ซึ่งจะแนะนำคุณเกี่ยวกับวิธีปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD

เริ่มต้น Cloud Shell

แม้ว่าคุณจะดำเนินการ Google Cloud จากระยะไกลได้จากแล็ปท็อป แต่คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์ใน Codelab นี้

จากคอนโซล GCP ให้คลิกไอคอน Cloud Shell บนแถบเครื่องมือด้านขวาบนดังนี้

STgwiN06Y0s_gL7i9bTed8duc9tWOIaFw0z_4QOjc-jeOmuH2TBK8l4udei56CKPLoM_i1yEF6pn5Ga88eniJQoEh8cAiTH79gWUHJdKOw0oiBZfBpOdcEOl6p29i4mvPe_A6UMJBQ

การจัดสรรและเชื่อมต่อกับสภาพแวดล้อมนี้ควรใช้เวลาเพียงครู่เดียว เมื่อเสร็จแล้ว คุณจะเห็นข้อมูลต่อไปนี้

r6WRHJDzL-GdB5VDxMWa67_cQxRR_x_xCG5xdt9Nilfuwe9fTGAwM9XSZbNPWvDSFtrZ7DDecKqR5_pIq2IJJ9puAMkC3Kt4JbN9jfMX3gAwTNHNqFmqOJ-3iIX5HSePO4dNVZUkNA

เครื่องเสมือนนี้เต็มไปด้วยเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักขนาด 5 GB ที่ใช้งานได้ต่อเนื่องและทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานทั้งหมดใน Lab นี้สามารถทำได้โดยใช้เบราว์เซอร์

3 ภาพรวมเวิร์กโฟลว์

พื้นฐาน

เวิร์กโฟลว์ประกอบด้วยชุดขั้นตอนที่อธิบายไว้โดยใช้ไวยากรณ์ที่ใช้ YAML ของ Workflows นี่คือคำจำกัดความของเวิร์กโฟลว์ โปรดดูคำอธิบายโดยละเอียดเกี่ยวกับไวยากรณ์ YAML ของเวิร์กโฟลว์ โปรดดูหน้าข้อมูลอ้างอิงไวยากรณ์

เมื่อสร้างเวิร์กโฟลว์แล้ว ระบบจะติดตั้งใช้งานเวิร์กโฟลว์ดังกล่าว ทำให้เวิร์กโฟลว์พร้อมดำเนินการ การดำเนินการคือการเรียกใช้ตรรกะ 1 ครั้งที่อยู่ในคำจำกัดความของเวิร์กโฟลว์ การดำเนินการในเวิร์กโฟลว์ทั้งหมดเป็นอิสระจากกันและผลิตภัณฑ์นี้รองรับการดำเนินการพร้อมกันจำนวนมาก

เปิดใช้บริการ

ใน Codelab นี้ คุณจะเชื่อมต่อ Cloud Functions, บริการ Cloud Run กับเวิร์กโฟลว์ รวมถึงใช้ Cloud Build และ Cloud Storage ระหว่างการสร้างบริการด้วย

เปิดใช้บริการที่จำเป็นทั้งหมด

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

ในขั้นตอนถัดไป คุณจะต้องเชื่อมต่อ Cloud Functions 2 ตัวเข้าด้วยกันในเวิร์กโฟลว์

4 ทำให้ Cloud Function แรกใช้งานได้

ฟังก์ชันแรกคือโปรแกรมสร้างตัวเลขสุ่มใน 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 เราจึงต้องเพิ่มดังกล่าวเป็นทรัพยากร Dependency การขึ้นต่อกันใน 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 ทำให้ Cloud Function ที่ 2 ใช้งานได้

ฟังก์ชันที่ 2 คือตัวคูณ จะนำอินพุตที่ได้รับมาคูณด้วย 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 เชื่อมต่อ Cloud Functions 2 รายการ

ในเวิร์กโฟลว์แรก ให้เชื่อมต่อทั้ง 2 ฟังก์ชันเข้าด้วยกัน

สร้างไฟล์ 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}

ในเวิร์กโฟลว์นี้ คุณจะได้รับหมายเลขสุ่มจากฟังก์ชันแรกและส่งต่อไปยังฟังก์ชันที่ 2 ผลที่ได้คือตัวเลขสุ่มคูณ

ทำให้เวิร์กโฟลว์แรกใช้งานได้

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

UI จะแนะนำให้คุณแก้ไขและทำให้เวิร์กโฟลว์ใช้งานได้ เมื่อทำให้ใช้งานได้แล้ว ให้คลิก 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 และคอนเทนเนอร์ต้องเชื่อมโยงกับตัวแปร env 0.0.0.0 และ 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

คุณจะดูการดำเนินการเวิร์กโฟลว์เพื่อดูผลลัพธ์ได้ใน 2-3 วินาที ดังนี้

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

ผลลัพธ์จะมีจำนวนเต็ม result และ state:

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

...
state: SUCCEEDED

10 ยินดีด้วย

ขอแสดงความยินดีที่เรียน Codelab จนจบ

หัวข้อที่ครอบคลุม

  • ข้อมูลพื้นฐานของเวิร์กโฟลว์
  • วิธีเชื่อมต่อ Cloud Functions สาธารณะกับเวิร์กโฟลว์
  • วิธีเชื่อมต่อบริการ Cloud Run ส่วนตัวกับเวิร์กโฟลว์
  • วิธีเชื่อมต่อ HTTP API ภายนอกกับเวิร์กโฟลว์