chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

GCPのCloud Run上でdocker コンテナを走らせる

背景:IoT Platformの評価として、ThinsBardを使いたい。ThinsBoardを無料で使うには、自分でサーバを仕立てる必要あり。ちょっと試すだけならGCPの無料サービス枠があり、Cloud Runを使えばDockerコンテナも走らせられる
課題:Cloud Runを使ったことがないので、python+flaskの組み合わせでDockerイメージを作って Cloud Run上で走らせてみる
結論:python+flaskによるWebServer用コンテナは稼働できた

詳細:

(前提)
Regionはasia-northeast1を使います。また、Ubuntu環境にgcloud CLIがインストール済み、GCP上の評価用プロジェクトとして、aaa-demoを設定済み


CloudRunで実行するコンテナはGCPのArtifact Repository(以降GAR)に登録されているイメージが基本となる(他から取ってくるのも可能らしいが)
まず GAR上にリポジトリを作成する。
リポジトリ名は仮にmyrepoとする

gcloud artifacts repositories create myrepo  --location=asia-northeast1 --repository-format=docker

ローカル環境でDockerビルドする。テストで使ったdockerfileとapp.py(flask用サンプルコード)は以下
file: dockerfile

FROM alpine
RUN apk update; apk add python3;  apk add py3-flask
COPY . /app
WORKDIR /app
CMD ["/usr/bin/python3", "app.py"]

file:app.py

#!/usr/bin/python3
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=False, port=8080)

portは8080でないとどうも正常に起動されない。host="0.0.0.0"を指定することで自サーバ外からの接続を受け付け可にする
dockerでpushする前に認証関連を設定する

gcloud auth configure-docker asia-northeast1-docker.pkg.dev

docker imageをビルド、レポジトリにPUSHする
file: build.sh

#!/bin/sh
REGION=asia-northeast1
PROJECT_ID=aaa-demo
DOCKER_IMAGE=flask_image01
GAR_REPO=myrepo
IMAGE=${REGION}-docker.pkg.dev/${PROJECT_ID}/${GAR_REPO}/${DOCKER_IMAGE}

echo "docker build ./ -t ${IMAGE}"
docker build ./ -t ${IMAGE}

echo "docker push ${IMAGE}"
docker push ${IMAGE}

レポジトリに登録されたimage を使ってコンテナを起動する
file: run.sh

#!/bin/sh
PROJECT_ID=aaa-demo
DOCKER_IMAGE=flask_image01
SERVICE_NAME=flask02try
GAR_REPO=myrepo
REGION=asia-northeast1

IMAGE=asia-northeast1-docker.pkg.dev/${PROJECT_ID}/${GAR_REPO}/${DOCKER_IMAGE}

echo "gcloud run deploy ${SERVICE_NAME} --image ${IMAGE} --platform=managed --project=${PROJECT_ID} --region ${REGION}"
gcloud run deploy ${SERVICE_NAME} --image ${IMAGE} --platform=managed --project=${PROJECT_ID} --region ${REGION}

GCPコンソールを参照するとコンテナが起動されている。


アクセス用URLも書かれているのでそれにアクセスする。

Hello Wold!と表示された。これにより、GCPのコンテナ上でPython+Flaskが動いていることが分かる

FireWallを設定しなくてもincoming:443はすでに許可されているのか??コンソールで再確認すると、 ingress incoming ANYが設定されているので、443 全通しと思われる。

現在稼働中のコンテナ(サービス)を確認

$ gcloud run services list
   SERVICE     REGION           URL                                                      LAST DEPLOYED BY     LAST DEPLOYED AT
✔  flask02try  asia-northeast1  https://flask02try-441441441877.asia-northeast1.run.app  hoge@gmail.com  2024-10-27T05:10:54.367925Z

(gcloud run の run とは実行コマンドのrunではなく、サービス名(Cloud Run)のrunであった)
コンテナ情報を表示

$ gcloud run services describe  flask02try --region asia-northeast1
✔ Service flask02try in region asia-northeast1

URL:     https://flask02try-441441441877.asia-northeast1.run.app
Ingress: all
Traffic:
  100% LATEST (currently flask02try-00001-pgn)

Last updated on 2024-10-27T05:10:54.367925Z by hoge@gmail.com:
  Revision flask02try-00001-pgn
  Container None
    Image:           asia-northeast1-docker.pkg.dev/aaa-demo/myrepo/flask01
    Port:            8080
    Memory:          512Mi
    CPU:             1000m
    Startup Probe:
      TCP every 240s
      Port:          8080
      Initial delay: 0s
      Timeout:       240s
      Failure threshold: 1
      Type:          Default
  Service account:   441441441877-compute@developer.gserviceaccount.com
  Concurrency:       80
  Max Instances:     100
  Timeout:           300s

動作確認を終えたのでコンテナ削除

$ gcloud run services delete  flask02try --region asia-northeast1
Service [flask02try] will be deleted.
Do you want to continue (Y/n)?  y
Deleting [flask02try]...done.
Deleted service [flask02try].

■課題
・ FWの設定によるのか、全通し状態なので、適切な制限がかかるようにする
・ThinsBoardをコンテナ上で走らせる場合、サーバとDBが別のコンテナになる。コンテナ間通信をどうやったら実現できるのか調査必要(内部DNAにDBサーバを登録してFQDN経由でアクセスすることになるのではなかろうか)
→同一VM(?)上で複数のDockerコンテナが同居することになるので、localhost:の形式でアクセス可能らしい。次の課題はデータ永続化のため、GCPが提供するいずれかのRDBを使わないといけないという点。あるいは永続化可能なストレージをマウントさせてもらう??
→永続化のために、Cloud SQLとか、Cloud Strageが提供されているようだ。これらは基本料金高そうだ。正しい手順の永続化はやめて、コンテナを落とす前にDB内データをダンプして、データをS3に転送するとか。。(素人根性の運用)
CloudStrageの月額費用
東京(asia-northeast1) $0.023 (GB 単位/月)

■関連資料
ThingsBoardのインストール手順
Installing ThingsBoard using Docker (Linux or Mac OS) | ThingsBoard Community Edition