🔰

GCPで学ぶMLOps #1 – GCPへのデプロイを体感する(Cloud Run × Flaskアプリ)

に公開

GCPで学ぶMLOps #1 – CI/CDを体感する(Cloud Run × Flaskアプリ)

今回は CI/CDの基本をCloud Runで体感 してみます。

まずはCI/CDの前段として、Flaskで作ったシンプルなアプリをコンテナ化し、Artifact Registryにpush → Cloud Runにデプロイして動かし、GCPにサービスをデプロイする流れを体感します。

わかりやすかった記事
https://zenn.dev/google_cloud_jp/articles/cloudrun-deploy-pattern


1. CI/CDとは?

  • CI (Continuous Integration)
    頻繁に自動的にソースコードを共有リポジトリへマージすること。

    • コードプッシュ → 自動ビルド → 自動テスト
  • CD (Continuous Deployment)
    統合されテストされたソースコードを本番環境へ自動デプロイすること。

    • デプロイ → ロギング → モニタリング

CI/CD を導入することで、
「小さな変更をすぐに試せる」→「開発の高速化と品質担保」が実現できます。


2. GCPのコンテナ関連サービス

  • GAR (Google Artifact Registry)
    Dockerイメージを含むアーティファクトを管理するサービス(新規利用はこちらが推奨)。

  • GCR (Google Container Registry)
    旧来のコンテナイメージ管理サービス。今後はGARに統合される方向。

  • Cloud Run
    GCPが提供するフルマネージドのコンテナ実行サービス。

    • コンテナをデプロイすれば勝手にスケール
    • APIやML推論サービスを簡単に公開可能
    • サーバーレスでメンテ不要

3. 今回のハンズオン概要

まずはCI/CDの前段として、コンテナライズされた手法でGCPにAPIサーバーを立てるハンズオン

  • Flaskアプリを用意
  • GCSに置いた CSV を BigQuery にロードする処理を実装
  • Docker でコンテナ化
  • Artifact Registry に push
  • Cloud Run にデプロイ
  • HTTPS経由でAPIを叩いて動作確認

4. Flask アプリケーション

このアプリは以下を行います。

  • / にアクセスがあると処理が実行される
  • GCS上のCSV (us-states.csv) を BigQuery にロード
  • ロード後のテーブル行数を返す API
main.py
from google.cloud import bigquery
from flask import Flask
import os 

app = Flask(__name__)
client = bigquery.Client()

@app.route('/')
def main(big_query_client=client):
    table_id = "udemy-mlops-472003.test_schema.us_states"
    job_config = bigquery.LoadJobConfig(
        write_disposition=bigquery.WriteDisposition.WRITE_TRUNCATE,
        source_format=bigquery.SourceFormat.CSV,
        skip_leading_rows=1,
    )
    uri = "gs://sidd-ml-ops-yoshihara/us-states.csv"
    load_job = big_query_client.load_table_from_uri(uri, table_id, job_config=job_config)

    load_job.result()  
    destination_table = big_query_client.get_table(table_id)
    return {"data": destination_table.num_rows}

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 5052)))

5. Dockerfile

FROM python:3.10-slim

ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

RUN pip install --no-cache-dir -r requirements.txt

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

6. デプロイ手順

実行コマンド群
#プロジェクト設定とリポジトリ作成

#プロジェクトを統一
gcloud config set project udemy-mlops-472003
gcloud config get-value project

#Cloud Run のデフォルトリージョン
gcloud config set run/region us-central1

#Artifact Registry API(未有効なら有効化)
gcloud services enable artifactregistry.googleapis.com

#リポジトリ作成(初回のみ)
gcloud artifacts repositories create python-apps \
  --location=us-central1 \
  --repository-format=docker \
  --description="python apps in Iowa"

#Docker 認証
gcloud auth configure-docker us-central1-docker.pkg.dev


#Apple Silicon対策(amd64でビルド&push)

docker buildx create --use   # 初回のみ

docker buildx build \
  --platform linux/amd64 \
  -t us-central1-docker.pkg.dev/udemy-mlops-472003/python-apps/demo-flask-app:latest \
  --push .


#Cloud Run へデプロイ

#1つ目のサービス
gcloud run deploy demo-flask-app \
  --project udemy-mlops-472003 \
  --region us-central1 \
  --image us-central1-docker.pkg.dev/udemy-mlops-472003/python-apps/demo-flask-app:latest \
  --timeout=300 \
  --allow-unauthenticated

#(任意)2つ目のサービス
gcloud run deploy demo-flask-app2 \
  --project udemy-mlops-472003 \
  --region us-central1 \
  --image us-central1-docker.pkg.dev/udemy-mlops-472003/python-apps/demo-flask-app:latest \
  --timeout=300 \
  --allow-unauthenticated

実行後にGCPのCloud Runを確認
[Cloud Run 管理画面の例]

7. 動作確認

APIのエンドポイント

デプロイ後、Cloud Run から発行される URL を確認します。

例:こんなやつ

https://demo-flask-app-xxxxxx-uc.a.run.app/

動作確認(行数の返却)

GCS に us-states.csv をアップロードしておき、以下を実行します。

curl https://demo-flask-app-xxxxxx-uc.a.run.app/

[画面でのAPI実行確認の例]

参考:テストに関するわかりやすい記事

https://zenn.dev/ryoryo34/articles/4f67b534402db2

まとめ

  • CI/CDの基本概念を整理
  • FlaskアプリをDocker化し、Artifact Registryにpush
  • Cloud RunにデプロイしてAPIを実行
  • GCS→BigQueryへのロード処理をサーバーレスで公開

Discussion