oinume journal

Scratchpad of what I learned

GCPのCloud Runを使って簡単なリダイレクタを作った話

今年5月にbetaとしてリリースされたGCPのCloud Runを使って、もともとGAEで運用していたリダイレクタを移植してみたのでその紹介。

Cloud Runとは

HTTPリクエストを処理するためのFull ManagedなステートレスのContainerの実行環境。公式サイトには以下のように説明されている。

Cloud Run is a managed compute platform that enables you to run stateless containers that are invocable via HTTP requests

GCPでは、Full Managedな実行環境(PaaS)として

  • Google App Engine(Standard Edition)
  • Cloud Functions

が存在しているが、完全にContainerベースのCloud Runが新しく追加されたよ、という風に自分は認識している。

リダイレクタの詳細

というだけのもの。実際にはURLごとにリダイレクト先が異なるのでプログラムを書いている。もともとはGAE Standard Editionで動かしていた。

準備

  • GCPのプロジェクトを作る
  • gcloud components update を実施する
  • gcloud components beta を実施する
  • Cloud RunのRegionを設定する
    • gcloud config set run/region us-central1
  • Cloud Buildを有効にする
  • Container Registryを有効にする

Cloud Runで実行するコード

実際にCloud Runで実行するコードは以下のような感じ

Dockerfile

Cloud RunはContainerを実行するので、Dockerfileを用意する。やっていることは ./cmd/server/main.go をコンパイルして server というバイナリを生成しているだけ。

Cloud BuildでContainer Imageをdeployする

自動化も加味して、CircleCIからContainer Imageを生成してGCRにdeployするようにしてみる。CircleCIのconfig.ymlはこんな感じ。

実際は Makefile で実行しているのは以下のコマンドになる。

$ gcloud builds submit --project ${GCP_PROJECT_ID} \
  --tag gcr.io/$(GCP_PROJECT_ID)/server:${IMAGE_TAG}
  • GCP_PROJECT_ID: あなたのGCPのプロジェクトID
  • IMAGE_TAG: master-123 のような値になっている。CircleCI上でビルドするので IMAGE_TAG=$(echo "${CIRCLE_BRANCH}" | tr '._/' '-' | tr '[:upper:]' '[:lower:]')-"${CIRCLE_BUILD_NUM}" としている。ただこれはもっと良い生成方法があるかもしれない。

なお、CircleCIからgcloud buildsでGCRにimageをpushするときに以下のエラーが発生してハマった。

Uploading tarball of [.] to [gs://blog-lampetty-net-redirector_cloudbuild/source/1557916060.04-0e599d9522c1400ebb47e942a96cb9b2.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/blog-lampetty-net-redirector/builds/ec22748d-e4c6-4e10-ba89-f4e108cac0d8].
Logs are available at [https://console.cloud.google.com/gcr/builds/ec22748d-e4c6-4e10-ba89-f4e108cac0d8?project=310764868638].
ERROR: (gcloud.builds.submit) HTTPError 403: <?xml version='1.0' encoding='UTF-8'?><Error><Code>AccessDenied</Code><Message>Access denied.</Message><Details>circle-ci@blog-lampetty-net-redirector.iam.gserviceaccount.com does not have storage.objects.get access to 310764868638.cloudbuild-logs.googleusercontent.com/log-ec22748d-e4c6-4e10-ba89-f4e108cac0d8.txt.</Details></Error>

解決方法としてはここにあるように、Project ViewerのRoleをService Accountに対して付与しないといけない。もしくは、cloudbuild.yamlの設定で logsBucket を指定してここへのロールを追加すれば良い。

CircleCIからgcloudコマンドで最新のcontainer imageをCloud Runに反映する

これはまだ自動化していない。以下のコマンドで自分のマシンからCloud Runに反映している。

$ gcloud beta run deploy --project ${GCP_PROJECT_ID} --image gcr.io/${GCP_PROJECT_ID}/server:${IMAGE_TAG}

Service name (server):
Deploying container to Cloud Run service [server] in project [${GCP_PROJECT_ID}] region [us-central1]
✓ Deploying... Done.
  ✓ Creating Revision...
  ✓ Routing traffic...
Done.
Service [server] revision [server-00005] has been deployed and is serving traffic at https://xyz.a.run.app

コマンドを実行すると最後に表示される https://xyz.a.run.app がアプリケーションが動いているURLである。

独自ドメインの割り当て

Cloud Runによって自分のアプリケーションに割り当てられたURLを独自ドメインに変更することができる。以下のコマンドを使うか、Consoleから設定ができる。

$ gcloud beta run domain-mappings create

プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで

プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで

参考リンク