run:言語自由、リクエストタイム60分
functions:リクエスト9分、関数をデプロイ
gke auto pilot mode:制限がなくなる
Cloud Run で作るサーバーレス アーキテクチャ 23 連発 - これのときはこう! (zenn.dev)
gke auto pilot mode:制限がなくなる
Cloud Run で作るサーバーレス アーキテクチャ 23 連発 - これのときはこう! (zenn.dev)
■RUN
httpリクエストでコンテナを呼び出す
Google Cloud Run を使うまで - Qiita
■ハンズオン(run)
クイックスタート: ビルドとデプロイ | Cloud Run のドキュメント | Google Cloud
クイックスタート: Cloud Run に Python サービスをデプロイする | Cloud Run のドキュメント | Google Cloud
基本はFlaskのhttp responseを返すコードである必要があるみたいだ
Scheduler手動 > Pubsub > Eventarc > Cloud runのでキックで実行がいい
■ハンズオン(run)
クイックスタート: ビルドとデプロイ | Cloud Run のドキュメント | Google Cloud
クイックスタート: Cloud Run に Python サービスをデプロイする | Cloud Run のドキュメント | Google Cloud
基本はFlaskのhttp responseを返すコードである必要があるみたいだ
Scheduler手動 > Pubsub > Eventarc > Cloud runのでキックで実行がいい
ローカルやterminalなどで作成しcmdでレジストリに入れるが、~/unco で下記作成
Dockerfile
.dockerignore
main.py
コンテナイメージにパッケージ化しContainer Registry にアップロード
コンテナイメージにパッケージ化しContainer Registry にアップロード
gcloud auth application-default login
gcloud run deploy (対話型でデプロイまでできるが、SAはデフォルトになる)
gcloud builds submit --tag gcr.io/bangboo-run/unco (ビルドのみ、手動でコンソールでSAを指定しデプロイする)
gcloud builds submit --pack image=gcr.io/bangboo-run/unco ならDockerfile不要らしい
gcloud run deploy (対話型でデプロイまでできるが、SAはデフォルトになる)
gcloud builds submit --tag gcr.io/bangboo-run/unco (ビルドのみ、手動でコンソールでSAを指定しデプロイする)
gcloud builds submit --pack image=gcr.io/bangboo-run/unco ならDockerfile不要らしい
コンソールでデプロイ(trigger/permission)-新ver更新のときTagを付けなおす?
設定allow all traficとAllow unauthenticated invocations、権限allUsersにCloud Run Invokerではブラウザでも上手行く
設定allow all traficとrequire auth(IAM)、権限allAuthenticatedUsersにCloud Run Invokerのとき
IAMが要るのでターミナルから
curl https://unco-zp2aehj5rq-an.a.run.app/ ではIAM要求の場合は駄目
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://unco-zp2aehj5rq-an.a.run.app/ で上手行く
設定allow internal traffic onlyとrequire auth(IAM)、権限allAuthenticatedUsersにCloud Run Invokerのとき
ターミナルはinternal trafficでないから
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" https://unco-zp2aehj5rq-an.a.run.app/ でも駄目
インターナルでIAMを使うにはどうする?(同セグメントvpcからcurl bearer、vpc scかpubsubかEventarcだけ、terminalやschdulerは駄目)
→IAMを使うならallow all traficでいいのでは、allusersにinvokerを付与しなければいいし
→怖ければ同セグメントにVMを立ててそこからキック、あるいはScheduler手動 > Pubsub > Eventarc > Cloud runがいい
→怖ければ同セグメントにVMを立ててそこからキック、あるいはScheduler手動 > Pubsub > Eventarc > Cloud runがいい
runのデフォルトのSAは別のrunでも同じSA実行として使い回されるので、別途作成したものを指定したい
デプロイをコンソールで実行するとサービスアカウントを指定できる(runのPermissonでそのSAにinvokerを付ける)
ブラウザ+IAMをrunで使うにはIAP
global ip、ドメイン、DNS、証明書、設定allow all traficとrequire auth(IAM)、権限各メールidにinvoker
global ip、ドメイン、DNS、証明書、設定allow all traficとrequire auth(IAM)、権限各メールidにinvoker
LBはバックエンドにserverless network end groupを選べばいい
/// IAP
(古い方法)
/// IAP
(古い方法)
IAPを使う場合はトリガーをAllow unauthenticated invocationsにする
現行だけだそうだが、IAPに全委任するために必要となっている
つまりIAPはLBが必要なため、Allow internal taraffic and from cloud load balancingとのコンビでトリガー設定をする
現行だけだそうだが、IAPに全委任するために必要となっている
つまりIAPはLBが必要なため、Allow internal taraffic and from cloud load balancingとのコンビでトリガー設定をする
権限はCloud runのallusersが付き個別のinvokerは不要となり、必要なものはIAP上で付与をする
IAP上のWeb app userに Allautheticatedusersを入れると、識別できる誰でも入れてしまう
アクセスを許可したいユーザのみ個別でweb app userをIAPで付与すること
アクセスを許可したいユーザのみ個別でweb app userをIAPで付与すること
IAP で保護されたリソースへのアクセスの管理 | Identity-Aware Proxy | Google Cloud
↓
(新しい方法)
特定のユーザだけCloudRunを利用させてたいなら:
(run)認証ユーザ+(run)内部トラフィックとLB経由+IAPのwebuserの設定
↓
(新しい方法)
特定のユーザだけCloudRunを利用させてたいなら:
(run)認証ユーザ+(run)内部トラフィックとLB経由+IAPのwebuserの設定
Cloud runでIAPを使用するIAP用隠れSAの権限:
プリンシパル: service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com
ロール: Cloud Run invoker
AllUsersでなく、上記のIAP用隠れSAに権限を振ればIAPがrunを起動する
利用ユーザはIAPでwebuserの権限を与える
利用ユーザはIAPでwebuserの権限を与える
===
dockerfileに記載
FROM google/cloud-sdk:latest
PythonモジュールでなくOS側にインストールする必要がありコンテナ化のDockerfileに記載できる
/// BANGBOO BLOG /// - k8s にDocker記載がある
PythonモジュールでなくOS側にインストールする必要がありコンテナ化のDockerfileに記載できる
/// BANGBOO BLOG /// - k8s にDocker記載がある
FROM python:3.9-slim
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
#RUN pip install --no-cache-dir -r requirements.txt
RUN pip install Flask gunicorn
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
python requirements.txtでは google-cloud-bigqueryはインスコできるがsdkは無理
main.pyに from google.cloud import bigquery
Dockerfileでイメージでgoogle-cloud-sdkが入ればPythonのsubprocessでgcloud cmdが打てる
Dockerのベースイメージを FROM google/cloud-sdk:latest にして
RUN apt-get update && apt-get install -y \
python3-pip
RUN pip install --no-chache-dir -r requirements.txt
Cloud API client library for pythonを使うにはrequirements.txtに
google-api-python-client
Dockerfileの動作はCloud buildのhistoryで見れる
RUN which gcloud
RUN echo $PATH
RUN who
Cloud runのpython動作はloggingで見る
OSの実行ユーザとコンテナ内のユーザを合わせないとファイル読み込み等ができない
permission deniedになる
Cloud runのそれぞれのユーザが誰なのか分からない(上記でわかるが)
Dockerfileに RUN chmod -R 777 /app と入れてしまう
===
Cloud Run のトリガーを作成する | Eventarc | Google Cloud
runとscheduler/pubsubの連携は eventarc triggerの設定が良さそう
これはAudit logに既定のものが記載されると発火されるというもの
runとscheduler/pubsubの連携は eventarc triggerの設定が良さそう
これはAudit logに既定のものが記載されると発火されるというもの
設定したrunのサービスのトリガー項目に
google.cloud.scheduler.v1.CloudScheduler.Run.Jobを設定(スケジューラ手動実行ならこれでも連携する)
google.cloud.pubsub.topic.v1.messagePublishedを設定 (Pubsub経由のEventArcなら)
色んなAPI有効が必要 クイックスタート: Pub/Sub メッセージを使用してイベントを受信する(Google Cloud CLI) | Eventarc
Schedulerとの連携に使う場合、手動実行でAudit logに記載され動くが、cron定期実行ならAudit logがなく動作しない事が分かった
internal trafficなら Scheduler > Pubsub > Eventarc > Cloud run
■Scheduler
■Run jobsgoogle.cloud.pubsub.topic.v1.messagePublishedを設定 (Pubsub経由のEventArcなら)
色んなAPI有効が必要 クイックスタート: Pub/Sub メッセージを使用してイベントを受信する(Google Cloud CLI) | Eventarc
Schedulerとの連携に使う場合、手動実行でAudit logに記載され動くが、cron定期実行ならAudit logがなく動作しない事が分かった
internal trafficなら Scheduler > Pubsub > Eventarc > Cloud run
■Scheduler
get で https://run-service-name-.kuso.run.app
0 7 * * 1 毎週月曜の6時
Auth headerに add OIDC token
runのサービスにinvokerを付けたSAを指定
5回リトライ/最大リトライ0sで制限なし/バックオフ最小180s最大1h/期間倍5回
サービスアカウントにCloud service agentロールが必要
===
サービスアカウントにCloud service agentロールが必要
===
runはジョブならFlask不要で簡易。だがEventarc-Schedule連携がまだGAでなくできないので単発手動実行用。
Procfile作成
web: python3 main.py
pipしたいものは requirements.txtに書く
バージョンは google-cloud-bigquery · PyPIで調べる
バージョンは google-cloud-bigquery · PyPIで調べる
google-cloud-bigquery==3.3.2
main.py作成
コードを書く from google.cloud import bigquery
gcloud auth application-default login
run job実行とコンテナのプロジェクトを合わすなら
gcloud config set project bangboo-runs
下記は通常不要なようだ
gcloud auth configure-docker
gcloud auth configure-docker
Buildpackを使用してコンテナをビルド
Cloud buildデフォルトサービスアカウントにGCSバケット権限必要 123456@cloudbuild.gserviceaccount.com
gcloud builds submit --pack image=gcr.io/bangboo-runs/run_data_to_bq
bangboo-runsのコンテナレジストリにrun_data_to_bqができている
Cloud runでジョブを作成
gcloud beta run jobs create job-run-data-to-bq \
--image gcr.io/bangboo-runs/run_data_to_bq \
--task 1 \
--set-env-vars SLEEP_MS=10000 \
--set-env-vars FAIL_RATE=0.5 \
--max-retries 0 \
--region asia-northeast1
(gcloud beta run jobs create --helpで見るとenv-varのハンドルは何もないのでコードでエラースローする必要がありそう、そこでスリープとか使ってエラーを吐くと、リトライはしてくれそう。taskを複数にすると同時に何個も動く)
ローカルでテスト
docker run --rm -e FAIL_RATE=0.9 -e SLEEP_MS=1000 gcr.io/bangboo-runs/run_data_to_bq
Cloud runでジョブを実行
gcloud beta run jobs execute job-run-data-to-bq
============■Flask
Flaskへようこそ — Flask Documentation (2.0.x) (msiz07-flask-docs-ja.readthedocs.io)
とほほのFlask入門 - とほほのWWW入門 (tohoho-web.com)
Flaskの基礎 - 闘うITエンジニアの覚え書き (magata.net)
Flaskへようこそ — Flask Documentation (2.0.x) (msiz07-flask-docs-ja.readthedocs.io)
とほほのFlask入門 - とほほのWWW入門 (tohoho-web.com)
Flaskの基礎 - 闘うITエンジニアの覚え書き (magata.net)
from flask import Flask #モジュール読み込み
app = Flask(__name__) #Webアプリ作成
@app.route("/", methods=["GET","POST"]) #エンドポイント設定(ルーティング)
def index():
if __name__ == '__main__': #Webアプリ起動
app.run(debug=True)
request.form.get('name', None) 第2引数にデフォルト値入れられるらしい
■Flask LBでパスを分ける場合
LB
sub.domain.com /* backend-1
sub.domain.com /dir/* backend-2
Flask
@app.route("/dir/index", methods=["GET","POST"])
ドメインがこの場合:https://sub.domain.com/dir/index
Flaskには元のルートパスから指定する
●外部ファイルのstaticフォルダはカスタムルートが必要
Flaskルートの指定になるので/static/等になりLBで振り分けた場合は都合が悪い
Cloud runルートからの指定として/dir/static/style.css等にするにはカスタムルートが必要
Python flask
from flask import Flask, send_from_directory
@app.route('/dir/static/<path:filename>')
def custom_static(filename):
return send_from_directory('static', filename)
Python flask html
<link rel="stylesheet" href="{{ url_for('custom_static', filename='style.css') }}">
トップレベルにstaticフォルダを作り静的ファイルを入れる
ブラウザ表示
<link rel="stylesheet" type="text/css" href="/dir/static/style index.css">
■Flask jinja2
{# comment #} テンプレートのコメント
Template Designer Documentation — Jinja Documentation (3.1.x) (palletsprojects.com)
============■Flask jinja2
{# comment #} テンプレートのコメント
Template Designer Documentation — Jinja Documentation (3.1.x) (palletsprojects.com)
■functions
コンソールでコード書いてもデプロイエラーになると入力分が消える糞
テキストで書いてコンソールにペーストしてやった
開発環境はローカルにすべきだろうな
【Python】Cloud Functions ローカル環境で開発 デプロイ | のい太ろぐ (noitalog.tokyo)
Cloud Functionsのローカル開発環境にFunction Frameworkを使用する (rhythm-corp.com)
テキストで書いてコンソールにペーストしてやった
開発環境はローカルにすべきだろうな
【Python】Cloud Functions ローカル環境で開発 デプロイ | のい太ろぐ (noitalog.tokyo)
Cloud Functionsのローカル開発環境にFunction Frameworkを使用する (rhythm-corp.com)
functionsもhttpで初めに実行される関数はFlaskのflask.Requestオブジェクトを受取る
PubsubトリガーとかEventarcトリガーもあるようだ
pubsubトリガーならinetrnal traffic onlyでOKだが、httpsはall traffic必要
PubsubトリガーとかEventarcトリガーもあるようだ
pubsubトリガーならinetrnal traffic onlyでOKだが、httpsはall traffic必要
requirementsは必要?標準ライブラリならimport文を本体に書いていれば良い
pprint.pprintでエラー、requirementsの場合PyPIで調べてバージョンも書こう
一時ファイルは/tmpというDIRであるがメモリーに保持される
テストでJSONを書く場合はキッチリ書く(文字はダブルクォート等)
{
"test" : "aaa"
}
functions invoker等のIAMはプロジェクトレベルではなく各functionsに対しての設定が必要そう
functionsのデプロイ時にinternal traffic や allow all trafic等の変更ができる名前の変更や連携変更はfunctions再作成が必要で面倒
functions では gcloud cmdが打てない、SDKがないから
クライアントライブラリでは? > 非力そう、、cloud runならSDKでDockerしgcloud cmd打てる
Cloud クライアント ライブラリ | Cloud APIs | Google Cloud
Cloud クライアント ライブラリ | Cloud APIs | Google Cloud
Functionsはデフォルトで環境変数を持っていてimport os > os.getenv()で取得できる
ENTRY_POINT 実行される関数、GCP_PROJECT 現在のGCPプロジェクトIDとかtopicという入れ物
メッセージがpublish投入される(コンソールでも作れるのでinternal trafficのトリガーにできる)
subscriptionでTopicのデータ取得状況を管理
subscriptionからsubscribeでメッセージの取得
メッセージは重複する仕様
Topicにメッセージを入れると勝手に紐づけられたアプリが動く
フィルターがあり条件を設定をできるがTopicを沢山作ればいいのでは
サブスクのpullはメールボックスみたいな入るだけ
functionsのpubsubで作った指定のTopicにメッセージが入れば動く
サブスクのpushも送信メールボックスみたいで送る
functionsのhttpで作ったエンドポイントに送られる
pullは謎に上手く行かなくなる?pushの方が安定かも
pullは謎に上手く行かなくなる?pushの方が安定かも
でもトラフィックの種類でpullならinternal traffic OK
pubsub pull -> functions:pull なら internal traficでもOK
pubsub push -> functions:push は http なので internal traficダメ
functionsのデプロイ時にinternal traffic や all等の変更もできる
例えばRunのTriggerでEventarcをPubsubで設定すれば指定のTopicに勝手にサブスクを作ってくれる
pubsubを使うときはrunとかfunctionsとかインスタンス1つの方がいい
べき等性の構成がなければバッチが勝手にリトライされ同時処理が起こる等で面倒
pubsubのリトライ無しで、returnで何とかhttp200レスポンスを返す
pythonだとmain()でエラーでもtry-exceptで投げてreturnを返すとhttp200になる
ackを返す時間デフォ10sであり処理が長いと駄目、-600sと長くするといい
pubsubはbase64ででコードするのにimport base64
pubsubはjsonでデータを持っていてimport json