ローカルやterminalなどで作成しcmdでレジストリに入れるが、~/unco で下記作成
Dockerfile
.dockerignore
main.py
コンテナイメージにパッケージ化し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不要らしい
コンソールでデプロイ(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がいい
runのデフォルトのSAは別のrunでも同じSA実行として使い回されるので、別途作成したものを指定したい
デプロイをコンソールで実行するとサービスアカウントを指定できる(runのPermissonでそのSAにinvokerを付ける)
ブラウザ+IAMをrunで使うにはIAP
global ip、ドメイン、DNS、証明書、設定allow all traficとrequire auth(IAM)、権限各メールidにinvoker
LBはバックエンドにserverless network end groupを選べばいい
/// IAP
(古い方法)
IAPを使う場合はトリガーをAllow unauthenticated invocationsにする
現行だけだそうだが、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で付与すること
IAP で保護されたリソースへのアクセスの管理 | Identity-Aware Proxy | Google Cloud↓
(新しい方法)
特定のユーザだけ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の権限を与える
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 と入れてしまう
===
設定したrunのサービスのトリガー項目に
google.cloud.scheduler.v1.CloudScheduler.Run.Jobを設定(スケジューラ手動実行ならこれでも連携する)
google.cloud.pubsub.topic.v1.messagePublishedを設定 (Pubsub経由のEventArcなら)
色んなAPI有効が必要
クイックスタート: Pub/Sub メッセージを使用してイベントを受信する(Google Cloud CLI) | EventarcSchedulerとの連携に使う場合、手動実行で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ロールが必要
===
■Run jobs
runはジョブならFlask不要で簡易。だがEventarc-Schedule連携がまだGAでなくできないので単発手動実行用。
Procfile作成
web: python3 main.py
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
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
============
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フォルダを作り静的ファイルを入れる
ブラウザ表示
============
■functions
functionsもhttpで初めに実行される関数はFlaskのflask.Requestオブジェクトを受取る
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がないから
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の方が安定かも