Google Cloud Runで手軽にはじめる Webアプリ

2022/10/30に公開

CloudRunが使いやすい

LismisではCloud Runを使っています。
App EngineCloud Functionsと比較検討した点を交えて紹介いたしますので、参考になれば幸いです。
なお2022年10月29日時点での情報になるため、最新の情報でない可能性がありますのでご了承ください。

各サービスの違い

https://cloud.google.com/blog/ja/products/gcp/choosing-the-right-compute-option-in-gcp-a-decision-tree

こちらで紹介されている通り、どの程度自由にしたいかによって選択肢が変化します。
自由度が高いということは、その分自分で管理する箇所も増えるということなので、ある程度任せられる方が楽です。(特に個人でやる場合などは。)

個人的見解を加えると以下のとおりです。上から順に自由度が高く、管理コストがかかるイメージ。

サービス 個人的見解
Compute Engine (GCE) GCPのEC2。ほぼすべて自由(全て自前で管理)
Container Engine (GKE) Kubernetesで管理したいとき。kubernetes自体はおまかせできる
Cloud Run コンテナ内容だけ管理したいとき。portだけ開けておけば良い
App Engine (GAE) プロダクトコードだけ管理したいとき。コンテナ管理はおまかせ
Cloud Functions プロダクトの一部分だけ動かしたいとき。リクエストドリブン。

Cloud Run がおすすめできるポイント

実際に使ってみて本当に便利だなと感じるので、特に良いなと思ったポイントがこちらです。

  1. 従量課金・無料枠がある
  2. コンテナをそのまま配布できる
  3. CPUやメモリ割り当て量、並列数を比較的自由に設定できる
  4. 死活監視がほぼ不要
  5. 関連サービスとの連携が簡単

従量課金・無料枠がある

https://cloud.google.com/free/docs/free-cloud-features?hl=ja#cloud-run

Cloud Run は GAEのインスタンス起動時間課金と違い従量課金だったことが大きいです。
毎月下記の無料枠を超えた時に、それぞれ課金されます。

  1. 200万リクエスト
  2. 360,000GB秒のメモリ、180,000 vCPU 秒のコンピューティング時間
  3. 1GBの北米からの下り(外向き)ネットワーク

よほどバズったりしないかぎり、開始間もない個人運営のサイトに200万リクエストはなかなかないですし、メモリ/CPU、ネットワークも同様に割と無料枠内でまかなえます。

ある程度のリクエストが来て初めて課金されるので、これが常時見込めるまでは十分です。
ただしリクエストごとに起動処理が必要になり初回のレスポンスタイムが多少かかるので注意は必要です。これについては常時起動オプションもあるので必要に応じて対応可能です。

コンテナをそのまま配布できる

GKE/GAEでも同じですが、やはりDockerイメージを作ってローカル開発環境を構築でき、イメージをそのまま配布できるので、GCEのVMとローカル環境の違い等を考慮しなくて済むのが大きいです。

リソースを比較的自由に設定できる

設定がほぼKubernetesのPodと同様の設定ができます。(というか、特に明言されてなかったと思いますが、おそらくKubernetes上で動いているのでしょう)
そのため1コンテナあたりのCPU/メモリ、並列数、環境変数等を自由に設定できます。

下記はLismisでの設定YAMLファイルです(一部変更/省略/マスキングしています)
CloudSQLやSecretManagerと連携する設定も入っていますので、需要があれば導入方法などもご紹介したいと思います。

config.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
    client.knative.dev/user-image: asia.gcr.io/[project]/server:latest
    run.googleapis.com/ingress: all
    run.googleapis.com/ingress-status: all
  labels:
    cloud.googleapis.com/location: asia-northeast1
  name: server
  namespace: 'NNNNNNNNNNNN'
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/maxScale: '100'
        client.knative.dev/user-image: asia.gcr.io/[project]/server:latest
        run.googleapis.com/cloudsql-instances: [project]:asia-northeast1:[db_name]
    spec:
      containerConcurrency: 10
      containers:
        - image: asia.gcr.io/[project]/server:latest
          resources:
            limits:
              cpu: 1000m
              memory: 512Mi
          ports:
            - containerPort: 8080
              name: http1
          env:
            - name: APP_ENV
              value: production
            - name: APP_ROLE
              value: api
            - name: YOUTUBE_DATA_API_KEY
              valueFrom:
                secretKeyRef:
                  key: latest
                  name: youtube_data_api_key
      serviceAccountName: [service_account]
      timeoutSeconds: 300
  traffic:
    - latestRevision: true
      percent: 100

死活監視がほぼ不要

前述の通りリクエストを受け取ってから起動します。常時起動ではなく常時スタンバイ状態とも言えるので、死活監視する意味がほとんどありません。(もちろんリクエストを受けてもアプリケーションのコードにバグが有って不具合を起こす、などのケースを除きますが)

GAE同様にサービス急激な負荷にも自動スケールしてくれますし、その最大数も設定できます。

関連サービスとの連携が簡単

たいていは何らかのデータストアが必要になりますが、CloudSQLとの連携も非常に簡単です。
yamlファイルを見ていただくとわかると思いますが、適切なサービスアカウントを用意すればVPCなしでCloudSQLと連携できます。

またSecretMangerを使うことでSecretを環境変数としてInjectできるので、コンテナイメージやコードにSecretが入ってしまい外部流出することもありません。
ドメインのマッピングも設定1つで済むので非常に簡単です。

ドメインマッピング

その他のサービス

今回はCloud Runを選択しましたが、他のサービスも検討したので私が調査した限りの内容と判断基準もご紹介します。

Compute Engine (GCE)

Compute Engine (GCE) は死活監視含め自前で考える必要があるので、個人ではなかなかつらいです。

そこまでやるなら、むしろGKEのほうがKubernetesで全体管理できるので、トータルでは楽だと思い選択肢から外しました。(Kubernetesの習熟コストは必要ですが。)
現状AWS/EC2のサービスをGCPに移動したい場合はよい選択肢になりそうです。

Container Engine (GKE)

Kubernetesの自由度が必要ならこちらを選ぶのが良いです。
そこまでの細かい設定管理は不要だったので選択肢から外しましたが、マネージドKubernetesなので「Kubenetesは使いたいがKubernetes自体の管理はお任せしたい」場合は最適です。

App Engine (GAE)

App Engine (GAE) はインスタンスの管理は不要で、コードに集中できるので良い選択肢でした。(最後まで迷いました。)
スタンダード環境は利用できる言語/バージョンに制約がありますが、フレキシブル環境ならDockerを用意すれば自由な言語を使えます。どちらもインスタンスを常時起動し時間に応じて課金されます。

スタンダード環境の「28インスタンス時間/日」の無料枠内なら問題ないですが、フレキシブル環境には無料枠もありません。無料枠もスケールして2インスタンス起動したなら、当然48インスタンス時間/日かかるので、料金がかかってきます。

スタンダード環境は言語/バージョンに制約がありますが、そこが問題がなく、常時起動しても問題ない程度のアクセスが見込めるならば、これも良い選択肢かなと思います。
逆に自由に言語/バージョンを選びたいならフレキシブル環境ですが、無料枠がないですし、独自コンテナで自由にしたいが管理は任せたいという点ではCloud Runとほぼ同条件になります。

このためどちらが有利か、は運営するサイトによると思います。常時起動で時間課金のため月額の見積もりが非常に簡単です。

  1. GKEの常時起動・起動時間課金 (無料枠なし)
  2. Cloud RunのCPU処理時間課金 (無料枠あり)

Cloud Functions

これでアプリの全てを管理するというのも夢があっていいなと思うのですが、できる限りバックエンド管理コストを最小化したいアプリに向いているなと感じました。
小さくシンプルな実装、言い換えれば特化した処理向けであり、アプリケーション全体を乗せるというよりもマイクロサービスの一部(またはこれのみで全体を構成するなど)として活用するのが良さそうです。

うまくマイクロサービスを使いこなせるなら素晴らしい選択肢だと思いますが、開始間もないサイトではそこまでの柔軟性は不要だったのと、Kubernetesのような「インフラ・技術的な管理」というよりも「アプリケーション全体の処理の流れを把握・管理する」というより抽象的な管理を求められると感じたので、これも個人ではまだ早いなと判断した理由の一つです。

あとはコードの管理をどうするのか悩みました。CloudRunと併用するにしろリポジトリはどういう単位で運用すべきか、分けるなら共通する処理はまた別リポジトリに切り出すのか。(それこそマイクロサービス的な運用になりそうな気もします)
いずれにせよ、序盤の個人サイトには管理コストに見合わないと判断しました。面白そうなんですけどね。

まとめ

いろいろなマネージドサービスを比較検討しましたが、特に個人サイトなど最初期にできるだけ費用・手間のコストを抑えたい時にはCloud RunやGAEは良い選択肢だと思っています。
今回は軽い紹介だけでしたが、ドメインマッピングやDB、Secret管理も合わせて非常に簡単なのでぜひおすすめです。

今回ご紹介したCloud Runで実際に動いているサイトがこちらです。

配信者の推し活が捗る - Lismis
みなさんの推し活を応援するための、推し配信者の配信やスケジュールを共有できるサイトです。
是非ユーザー登録して使ってみてください。

https://lismis.live/ja-jp

Discussion