このドキュメントでは、マイクロサービスを Pub/Sub および GKE と統合するで説明されているリファレンス アーキテクチャの実装方法について説明します。このアーキテクチャは、コンテナと非同期メッセージングを使用して、長時間実行プロセスを処理するように設計されています。
このドキュメントでは、写真のサムネイルを生成する写真共有アプリのサンプルを使用します。Google Kubernetes Engine(GKE)を使用してアプリケーションをデプロイし、Pub/Sub を使用して長時間実行プロセスを非同期で呼び出します。また、Cloud Storage の Pub/Sub 通知を使用して、アプリケーションのコードを変更せずにサイドジョブを追加することもできます。
アプリケーションは Cloud Build によってコンテナ化され、Artifact Registry に保存されます。Cloud Vision を使用して不適切な画像を検出します。
アーキテクチャ
次の図は、リファレンス アーキテクチャを実装するフォトアルバム アプリケーションのサンプル設計を示しています。
図 1. コンテナと非同期メッセージングの使用に基づく画像処理のアーキテクチャ。
上の図はサムネイルの生成方法を示しています。
- クライアントがアプリケーションに画像をアップロードします。
- アプリケーションは、Cloud Storage に画像を保存します。
- サムネイルに対してリクエストが生成されます。
- サムネイル生成ツールでサムネイルが生成されます。
- フォトアルバム アプリケーションに正常なレスポンスが送信されます。
- 正常なレスポンスがクライアントに送信されます。サムネイルは Cloud Storage で確認できます。
次の図は、アプリケーションがサムネイル生成を別のサービスとして非同期で実装する方法を示しています。
図 2. サムネイル抽出プロセスのアーキテクチャ。
Pub/Sub を使用してサービス リクエストをサムネイル生成サービスに送信します。この新しいアーキテクチャではサービスを非同期で呼び出すため、アプリケーションがクライアントにレスポンスを返した後に、サムネイルがバックグラウンドで作成されます。また、この設計では複数のジョブを並行して実行できるように、サムネイル生成サービスのスケールができます。
目標
- GKE にサンプルのフォトアルバム アプリケーションをデプロイします。
- アプリケーションから非同期のサービス呼び出しを行います。
- Cloud Storage の Pub/Sub 通知を使用して、新しいファイルが Cloud Storage バケットにアップロードされたときにアプリケーションをトリガーします。
- Pub/Sub を使用して、アプリケーションを変更することなく、より多くのタスクを実行できます。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
- Cloud Storage
- Cloud SQL
- Pub/Sub
- Compute Engine instances used by GKE
- Cluster-management fee for GKE
- Cloud Load Balancing
- Cloud Build
- Artifact Registry
- Vision
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
サンプル アプリケーションの構築の完了後は、作成したリソースを削除すれば、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE, Cloud SQL, Cloud Build, Artifact Registry, and Cloud Vision APIs.
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
環境を設定する
このセクションでは、ドキュメント全体で使用されるデフォルトの設定値を割り当てます。Cloud Shell セッションを閉じると、これらの環境設定は失われます。
Cloud Shell で、デフォルトの Google Cloud プロジェクトを設定します。
gcloud config set project PROJECT_ID
PROJECT_ID
は、実際の Google Cloud プロジェクト ID に置き換えます。デフォルトの Compute Engine リージョンを設定します。
gcloud config set compute/region REGION export REGION=REGION
REGION
は、近くのリージョンに置き換えます。詳細については、リージョンとゾーンをご覧ください。デフォルトの Compute Engine ゾーンを設定します。
gcloud config set compute/zone ZONE export ZONE=ZONE
ZONE
は、近くのゾーンに置き換えます。サンプル アプリケーション ファイルをダウンロードし、現在のディレクトリを設定します。
git clone https://github.com/GoogleCloudPlatform/gke-photoalbum-example cd gke-photoalbum-example
Cloud Storage バケットを作成し、デフォルトのサムネイル画像をアップロードする
Cloud Shell で、元の画像とサムネイルを保存する Cloud Storage バケットを作成します。
export PROJECT_ID=$(gcloud config get-value project) gcloud storage buckets create gs://${PROJECT_ID}-photostore --location=${REGION}
デフォルトのサムネイル ファイルをアップロードします。
gcloud storage cp ./application/photoalbum/images/default.png \ gs://${PROJECT_ID}-photostore/thumbnails/default.png
- アップロードされた画像は
gs://PROJECT_ID-photostore/FILENAME
の形式で保存されます。ここで、FILENAME
は、アップロードする画像ファイルの名前を表します。 - 生成されたサムネイルは
gs://PROJECT_ID-photostore/thumbnails/FILENAME
の形式で保存されます。 - 元の画像と対応するサムネイルの
FILENAME
は同じですが、サムネイルはthumbnails
バケットに保存されます。 サムネイルの作成中は、次の
default.png
プレースホルダ サムネイル画像がフォトアルバム アプリケーションに表示されます。
- アップロードされた画像は
サムネイル ファイルを公開します。
gcloud storage buckets add-iam-policy-binding gs://${PROJECT_ID}-photostore \ --member=allUsers --role=roles/storage.objectViewer
Cloud SQL インスタンスと MySQL データベースを作成する
Cloud Shell で、Cloud SQL インスタンスを作成します。
gcloud sql instances create photoalbum-db --region=${REGION} \ --database-version=MYSQL_8_0
接続名を取得します。
gcloud sql instances describe photoalbum-db \ --format="value(connectionName)"
後で使用するため、この名前をメモしておきます。
MySQL ユーザー
root@%
のパスワードを設定します。gcloud sql users set-password root --host=% --instance=photoalbum-db \ --password=PASSWORD
PASSWORD
をroot@%
ユーザーの安全なパスワードに置き換えます。Cloud SQL インスタンスに接続します。
gcloud sql connect photoalbum-db --user=root --quiet
プロンプトが表示されたら、前の手順で設定したパスワードを入力します。
photo_db
という名前のデータベースを作成します。ここで、ユーザーはappuser
で、パスワードはpas4appuser
です。create database photo_db; create user 'appuser'@'%' identified by 'pas4appuser'; grant all on photo_db.* to 'appuser'@'%' with grant option; flush privileges;
結果を確認して MySQL を終了します。
show databases; select user from mysql.user; exit
出力で、
photo_db
データベースとappuser
ユーザーが作成されたことを確認します。mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | photo_db | | sys | +--------------------+ 5 rows in set (0.16 sec) mysql> \t Outfile disabled. mysql> select user from mysql.user; +-------------------+ | user | +-------------------+ | appuser | | cloudsqlreplica | | cloudsqlsuperuser | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlexport | | cloudsqlimport | | cloudsqloneshot | | root | | cloudsqlapplier | | cloudsqlimport | | mysql.infoschema | | mysql.session | | mysql.sys | | root | +-------------------+ 18 rows in set (0.16 sec) mysql> exit Bye
Pub/Sub トピックとサブスクリプションを作成する
Cloud Shell で、
thumbnail-service
という Pub/Sub トピックを作成します。gcloud pubsub topics create thumbnail-service
フォトアルバム アプリケーションは、
thumbnail-service
トピックでメッセージを公開して、サムネイル生成サービスにリクエストを送信します。thumbnail-workers
という Pub/Sub サブスクリプションを作成します。gcloud pubsub subscriptions create --topic thumbnail-service thumbnail-workers
サムネイル生成サービスは、
thumbnail-workers
サブスクリプションからリクエストを受け取ります。
GKE クラスタを作成する
Cloud Shell で、API を呼び出す権限を持つ GKE クラスタを作成します。
gcloud container clusters create "photoalbum-cluster" \ --scopes "https://www.googleapis.com/auth/cloud-platform" \ --num-nodes "5"
後の手順で
kubectl
コマンドを使用してクラスタを管理できるように、アクセス認証情報を構成します。gcloud container clusters get-credentials photoalbum-cluster
ノードのリストを表示します。
kubectl get nodes
出力で、
STATUS
値がReady
のノードが 5 つあることを確認します。NAME STATUS ROLES AGE VERSION gke-photoalbum-cluster-default-pool-d637570a-2pfh Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-3rm4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-f7l4 Ready <none> 2m55s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-qb2z Ready <none> 2m53s v1.24.10-gke.2300 gke-photoalbum-cluster-default-pool-d637570a-rvnp Ready <none> 2m54s v1.24.10-gke.2300
Artifact Registry リポジトリを作成する
Cloud Shell で、コンテナ イメージを保存するリポジトリを作成します。
gcloud artifacts repositories create photoalbum-repo \ --repository-format=docker \ --location=us-central1 \ --description="Docker repository"
アプリケーションの画像をビルドする
テキスト エディタで
application/photoalbum/src/auth_decorator.py
ファイルを開き、ユーザー名とパスワードを更新します。USERNAME = 'username' PASSWORD = 'passw0rd'
Cloud Shell で、Cloud Build サービスを使用してフォトアルバム アプリケーションの画像をビルドします。
gcloud builds submit ./application/photoalbum -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app
Cloud Build サービスを使用して、
thumbnail-worker
サムネイル生成サービスの画像をビルドします。gcloud builds submit ./application/thumbnail -t \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker
フォトアルバム アプリケーションをデプロイする
Cloud Shell で、フォトアルバムとサムネイル生成ツールの Kubernetes Deployment マニフェストを実際の環境に応じた値で更新します。
connection_name=$(gcloud sql instances describe photoalbum-db \ --format "value(connectionName)") digest_photoalbum=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/photoalbum-app:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_photoalbum}/" \ config/photoalbum-deployment.yaml digest_thumbnail=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/thumbnail-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_thumbnail}/" \ config/thumbnail-deployment.yaml
Deployment リソースを作成して、フォトアルバム アプリケーションとサムネイル生成サービスを起動します。
kubectl create -f config/photoalbum-deployment.yaml kubectl create -f config/thumbnail-deployment.yaml
アプリケーションに外部 IP アドレスを割り当てる Service リソースを作成します。
kubectl create -f config/photoalbum-service.yaml
Pod の結果を確認します。
kubectl get pods
出力で、
photoalbum-app
Pod とthumbail-worker
Pod がそれぞれ 3 つあり、そのSTATUS
値がRunning
であることを確認します。NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 2m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 2m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 0 2m thumbnail-worker-86bd95cd68-728k5 2/2 Running 0 2m thumbnail-worker-86bd95cd68-hqxqr 2/2 Running 0 2m thumbnail-worker-86bd95cd68-xnxhc 2/2 Running 0 2m
thumbnail-worker
Pod は、thumbnail-workers
サブスクリプションからのサムネイル生成リクエストをサブスクライブします。詳細については、ソースコードでのcallback
関数の使用方法をご覧ください。Service の結果を確認します。
kubectl get services
出力で、
photoalbum-service
Service のEXTERNAL-IP
列に外部 IP アドレスがあることを確認します。Service がすべて実行されるまで数分かかることがあります。NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 20m photoalbum-service LoadBalancer 10.23.253.241 146.148.111.115 80:32657/TCP 2m
後で使用するために、外部 IP アドレスはメモしておきます。この例では
146.148.111.115
です。
フォトアルバム アプリケーションをテストする
デプロイされたアプリケーションにウェブブラウザでアクセスするには、次の URL に移動して、前の手順で設定したユーザー名とパスワードを入力します。
http://EXTERNAL_IP
EXTERNAL_IP
は、前の手順でコピーした IP アドレスに置き換えます。画像ファイルをアップロードするには、[アップロード] をクリックします。
サムネイル プレースホルダが画面に表示されます。
バックグラウンドで、サムネイル生成サービスがアップロードされた画像のサムネイルを作成します。生成されたサムネイルを表示するには、[Refresh] をクリックします。Cloud Vision API が、検出した画像ラベルを追加します。
元の画像を表示するには、サムネイルをクリックします。
不適切な画像の検出機能を追加する
次の図は、Cloud Storage の Pub/Sub 通知を使用して、不適切なコンテンツを検出するサービスをトリガーする方法を示しています。不適切なコンテンツを含む新しいファイルが Cloud Storage バケットに保存されると、この機能が画像をぼかします。
上の図のように、サービスは Vision API のセーフサーチ検出機能を使用して、画像内の不適切なコンテンツを検出します。
フォト アプリケーションは、サムネイル生成ツールと画像チェッカーを非同期でトリガーします。したがって、特定の順序で実行される保証はありません。画像にぼかしを入れる前にサムネイル生成が行われると、しばらく間、不適切なサムネイルが表示されることがあります。ただし、画像チェッカーは最終的に、不適切な画像と不適切なサムネイルの両方にぼかしを入れます。
Pub/Sub トピック、サブスクリプション、通知を作成する
Cloud Shell で、
safeimage-service
という Pub/Sub トピックを作成します。gcloud pubsub topics create safeimage-service
safeimage-workers
という Pub/Sub サブスクリプションを作成します。gcloud pubsub subscriptions create --topic safeimage-service \ safeimage-workers
Pub/Sub 通知を構成して、新しいファイルが Cloud Storage バケットにアップロードされたときに
safeimage-service
トピックにメッセージが送信されるようにします。gcloud storage buckets notifications create gs://${PROJECT_ID}-photostore \ --topic=safeimage-service --payload-format=json
ワーカー イメージをビルドし、デプロイする
Cloud Shell で、Cloud Build を使用して
safeimage-workers
サブスクリプションのコンテナ イメージをビルドします。gcloud builds submit ./application/safeimage \ -t us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker
セーフイメージ サービスの Kubernetes Deployment マニフェストを、実際の Google Cloud プロジェクト ID、Cloud SQL 接続名、コンテナ イメージのダイジェストで更新します。
digest_safeimage=$(gcloud container images describe \ us-central1-docker.pkg.dev/${PROJECT_ID}/photoalbum-repo/safeimage-worker:latest --format \ "value(image_summary.digest)") sed -i.bak -e "s/\[PROJECT_ID\]/${PROJECT_ID}/" \ -e "s/\[CONNECTION_NAME\]/${connection_name}/" \ -e "s/\[DIGEST\]/${digest_safeimage}/" \ config/safeimage-deployment.yaml
Deployment リソースを作成する
safeimage-service
トピックをデプロイするため、safeimage-deployment
という Deployment リソースを作成します。kubectl create -f config/safeimage-deployment.yaml
結果を確認します。
kubectl get pods
出力で、
STATUS
値がRunning
のsafeimage-worker
Pod が 3 つあることを確認します。NAME READY STATUS RESTARTS AGE photoalbum-app-555f7cbdb7-cp8nw 2/2 Running 0 30m photoalbum-app-555f7cbdb7-ftlc6 2/2 Running 0 30m photoalbum-app-555f7cbdb7-xsr4b 2/2 Running 8 30m safeimage-worker-7dc8c84f54-6sqzs 1/1 Running 0 2m safeimage-worker-7dc8c84f54-9bskw 1/1 Running 0 2m safeimage-worker-7dc8c84f54-b7gtp 1/1 Running 0 2m thumbnail-worker-86bd95cd68-9wrpv 2/2 Running 0 30m thumbnail-worker-86bd95cd68-kbhsn 2/2 Running 2 30m thumbnail-worker-86bd95cd68-n4rj7 2/2 Running 0 30m
safeimage-worker
Pod は、safeimage-workers
サブスクリプションから不適切な画像の検出リクエストをサブスクライブします。詳細については、ソースコードでのcallback
関数の使用方法をご覧ください。
不適切な画像の検出機能をテストする
このセクションでは、テスト画像をアップロードし、セーフサーチ検出不適切な画像が機能によってぼかし処理されることを確認します。テスト画像は、ゾンビ姿の少女の画像です(Pixaby CC0 ライセンス取得済み)。
- テスト画像をダウンロードします。
- 画像をアップロードするには、
http://EXTERNAL_IP
に移動して [Upload] をクリックします。 [Refresh] をクリックします。ぼかし処理が施されたサムネイルがアプリケーションに表示されます。
アップロードした画像にもぼかし処理が施されていることを確認するには、サムネイルをクリックします。
クリーンアップ
サンプル アプリケーション用に作成した Google Cloud リソースを保持しない場合は、今後料金が発生しないように削除できます。プロジェクトを完全に削除するか、クラスタ リソースを削除してからクラスタを削除できます。
プロジェクトを削除する
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
個々のリソースを削除する
プロジェクトを削除する代わりに、作成した個々のリソースを削除できます。
GKE からリソースを削除します。
kubectl delete -f config/safeimage-deployment.yaml kubectl delete -f config/photoalbum-service.yaml kubectl delete -f config/thumbnail-deployment.yaml kubectl delete -f config/photoalbum-deployment.yaml
GKE からクラスタを削除します。
gcloud container clusters delete photoalbum-cluster --quiet
Artifact Registry からリポジトリを削除します。
gcloud artifacts repositories delete photoalbum-repo --location us-central1 --quiet
Pub/Sub からサブスクリプションとトピックを削除します。
gcloud pubsub subscriptions delete safeimage-workers gcloud pubsub topics delete safeimage-service gcloud pubsub subscriptions delete thumbnail-workers gcloud pubsub topics delete thumbnail-service
Cloud SQL インスタンスを削除します。
gcloud sql instances delete photoalbum-db --quiet
Cloud Storage バケットを削除します。
gcloud storage rm gs://${PROJECT_ID}-photostore --recursive gcloud storage rm gs://${PROJECT_ID}_cloudbuild --recursive
ファイルを削除します。
cd .. rm -rf gke-photoalbum-example
次のステップ
- DevOps について読む。また、このリファレンス アーキテクチャに関連するアーキテクチャ機能の詳細を確認する。
- DevOps のクイック チェックで、業界における立ち位置を把握する。
- Cloud アーキテクチャ センターで、リファレンス アーキテクチャ、図、ベスト プラクティスを確認する。