はじめに
Cloud Functions を python で使ってみるための調査をしました。いまどき、サーバレスでなくてはね、ということで、老体に鞭を打ち、休日に作業しています。戦いの証をこちらに掲げています。
Quick Start から CDまで
まずはQuick Start
Quick start は、コンソールだけでdeploy するところまでできます。テストも楽にできるんだなーというのが、印象的です。
その後、gcloud による操作をここを読んでざっと理解しました。
これらをもとに、Cloudbuild でCI/CDできるように頑張りました。
作業内容
準備
準備します。Python3.9 にしているのは、使ってみたいからです。
$ virtualenv -p python3.9 venv
$ source ./venv/bin/activate
(venv) $ $ python -V
Python 3.9.5
ローカルで動かすために必要なものを入れます。
$ python -m pip install functions-framework
...
# python -m pip list
$ python -m pip list
Package Version
------------------------------ ---------
...
Flask 2.0.2
functions-framework 3.0.0
google-api-core 2.4.0
google-auth 2.3.3
grpc-google-iam-v1 0.12.3
grpcio 1.43.0
...
という感じでした。
ローカルで動かす
関数 my_hello_http が実装してあるフォルダで、function-framework を実行します。
実装はサンプルにあるもののコピペです。
from flask import escape
import functions_framework
@functions_framework.http
def my_hello_http(request):
request_json = request.get_json(silent=True)
request_args = request.args
if request_json and 'name' in request_json:
name = request_json['name']
elif request_args and 'name' in request_args:
name = request_args['name']
else:
name = 'World'
return 'Hello {}!'.format(escape(name))
これを functions-framework で実行します。
$ functions-framework --target my_hello_http --signature-type=http --port=8080 --debug
* Serving Flask app 'hello_http' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://172.25.125.68:8080/ (Press CTRL+C to quit)
* Restarting with watchdog (inotify)
* Debugger is active!
* Debugger PIN: 111-222-666
別のターミナルで接続してみる。
$ curl -H "accept: application/json" -H "Content-Type: application/json" -d '{"name": "baby."}' http://172.25.125.68:8080/my_hello_sample
Hello baby.!
動いた。よしよし。
手動で Deploy
deploy は gcloud functions deploy で行ける。覚えられるかな。
$ gcloud functions deploy my_hello_http --runtime python39 --trigger-http --allow-unauthenticated
Deploying function (may take a while - up to 2 minutes)...⠛
For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=us-central1/xxxxxxxxxxxxxxxxxxxxx?project=1234567890123
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
buildId: xxxxxxxxxxxxxxxxxxxxxxxxxxx
buildName: projects/1234567890123/locations/us-central1/builds/xxxxxxxxxxxxxxxxxxxxxxxxxxx
entryPoint: my_hello_http
httpsTrigger:
securityLevel: SECURE_ALWAYS
url: https://us-central1-myproject.cloudfunctions.net/my_hello_http
ingressSettings: ALLOW_ALL
labels:
deployment-tool: cli-gcloud
name: projects/myproject/locations/us-central1/functions/my_hello_http
runtime: python39
serviceAccountEmail: ambmonitordev@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-yyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzzzzzzzzz.zip
status: ACTIVE
timeout: 60s
updateTime: '2022-01-16T11:16:18.258Z'
versionId: '1'
内部ではどのように動いているのかな。build したり、storage の設定が出てきたり、entryPoint の文字が見えたり。
この情報は、以下でも表示できる。
$ gcloud functions describe my_hello_http
deploy しているserverless application を忘れたら、list する。
$ gcloud functions list
NAME STATUS TRIGGER REGION
my_hello_http ACTIVE HTTP Trigger us-central1
CloudBuild でDeploy
今のコマンドをcloudbuild.yaml に書いてみる。
steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
args:
- gcloud
- functions
- deploy
- my_hello_http
- --region=asia-northeast1
- --source=.
- --trigger-http
- --runtime=python39
とりあえずローカルで実行してみる。今、main.py と同じディレクトリで下記を実行することを想定していますが、そうでなければ"source=..."の値を書き換えてください。
$ gcloud builds submit --config cloudbuild.yml .
がエラーになってしまった。
- '@type': type.googleapis.com/google.rpc.ErrorInfo
domain: googleapis.com
metadata:
consumer: projects/12345678901234
service: cloudresourcemanager.googleapis.com
reason: SERVICE_DISABLED
ERROR
と言われたので、Cloud Resouce Manager API を有効にしました。そうしたら成功はしたのですが、
Deploying function (may take a while - up to 2 minutes)...
WARNING: Setting IAM policy failed, try `gcloud alpha functions add-iam-policy-binding my_hello_http --region=asia-northeast1 --member=allUsers --role=roles/cloudfunctions.invoker`
と言われたので、素直にコマンドを叩いておきました。
$ gcloud alpha functions add-iam-policy-binding my_hello_http --region=asia-northeast1 --member=allUsers --role=roles/cloudfunctions.invoker
bindings:
- members:
- allUsers
role: roles/cloudfunctions.invoker
etag: BwXVssdV2mE=
version: 1
いよいよCloud Build にtrigger を作ります。いろいろエラーが出たのですが、
- CloudBuild のサービスアカウントに CloudFunctions 開発者のロールが無効だった。これはコンソールのCloudBuild の設定から変更できます。
- build trigger を実行するサービスアカウントの権限がLogging になかった。これはせってしない方が良かったのかもしれない。
で最後は無事にdeploy できました!! (^^)/
まとめ
GCPのサーバレスをpython で利用するために、Cloud Functions を python 使い方を調査し、動作確認をとった。
- ローカルで動かすことも可能。(functions-)
- CloudBuild から deploy 可能
いろいろ作っていくのか。location(region?) が違うと別のものとして扱われているようだった。
来週も生き延びれるかな。。。
メモ
- 参考にさせていただきました。PubSubもさくっと動作確認されている。
- ローカルに作ったパッケージを呼び出す。
- google 様のサンプル: python-doc-samples/functions/ 以下に全部ある。
- gcloud の使い方入門