Posted at

Cloud Runを使うならこれだけ知ってると得した気分になる


結論


  • Quick Startに出てくるCloud Buildも少し知ってた方がいい

  • Cloud SQL使うならCloud SQL Proxy対応してるので、そのオプションを使う

  • インフラにコスト払いたくない、手抜きしたい人には最高のサービス


実際のアプリケーションを使う場合を想定して使う

Cloud RunのQuickStart的な記事や内容をよく見ますが、バックエンドで使うならCloud SQLは当たり前に出てくると思う。

なんでCloud SQL(Proxy)と繋ぐ方法は知ってると吉なので書いておきます。


アプリケーションの作成

今回はRailsでサクッと作ってみるということで

$ rails new rails_on_cloud_run -T -d postgresql

でまずはサクッとRailsプロジェクトを作ります。


Dockerfileおよびstartファイル作成

Cloud RunはDockerコンテナで動くので、Dockerfileが必須です。そのDockerコンテナの起動に使うstartファイルを一緒に作ります。

FROM ruby:2.6.3-alpine

RUN apk add --no-cache tzdata postgresql-dev && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN mkdir /app
WORKDIR /app

ARG BUNDLE_OPTIONS

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN apk add --no-cache --virtual .rails-builddeps alpine-sdk && \
bundle install -j4 ${BUNDLE_OPTIONS} && \
apk del .rails-builddeps

COPY . /app

CMD ["bin/start"]

手抜きのようで必要最低限のDockerfile。かくゆう私は基本このDockerfileから始めます。

で最後のCMDに書いてるstartファイルを作ります。

#!/bin/sh

RAILS_PORT=3000
if [ -n "$PORT" ]; then
RAILS_PORT=$PORT
fi

# db migrate
# TODO 後でJobに切り出したい
bin/rails db:create
bin/rails db:migrate

bin/rails s -p $RAILS_PORT -b 0.0.0.0

ここで大事なのはPORTという環境変数があったら、そのポートでRailsを起動していること。

Cloud RunではPORTという環境変数が渡ってきて、そのポートで起動してるかのチェックが行われます。なので指定されたポートで起動する必要があるため、このような記載になっています。


Cloud SQLへの接続設定

ここまでで確かにビルドはできるのですが、もう1つ大切なことがあります。

それはCloud SQLへ繋ぐための設定です。Cloud SQLへの接続はCloud SQL Proxyを介して接続することが推奨されています。(もちろんなくてもできますが)

そこでそのCloud SQL Proxyを使うためにDatabase接続の定義を修正します。Railsの場合はdatabase.ymlなので例として

default: &default

adapter: postgresql
encoding: utf-8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV['DB_HOST'] || 'localhost' %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
port: <%= ENV['DB_PORT'] %>
# socket: <socket path> # for MySQL

production:
<<: *default
database: <your database name>

単に環境変数から取得しているのですが、大事なのは接続先です。Cloud SQL Proxy対応のCloud Runコンテナはコンテナ内の/cloudsql/<Cloud SQL instance> にsocketがあるのでそこに向けて接続する必要があります。PostgreSQLの場合は上記のyamlファイルのhost部分をそれに指定し、MySQLの場合はsocket部分を指定できるようになればいいです。

ちなみにそのDB_HOSTの指定は/cloudsql/<Project ID>:<region>:<Cloud SQL Instance name>になると思います。

もしCloud SQLへの接続名がわからないならConsoleからはこんな感じで見えるはずです。

image.png


Cloud Build(Docker build)の設定

上記に記載したリンクのQuick Startにgcloud builds submitというコマンドが出てくるが、これがDockerイメージをビルドするためのサービスを起動するコマンドです。

そのコマンドを使うと確かにビルドできるのですが、Production等で使用する場合にビルド時間の短縮とかを考える必要あります。そこでCloud Buildではkanikoが使えます。kanikoはビルドする時に前回のビルド時キャッシュを使用してビルドすることでビルド時間を短縮します。(詳しくは説明しませんので、ググって下さい)

kanikoを使うで最低限必要なyamlファイル

steps:

- name: 'gcr.io/kaniko-project/executor:latest'
args:
- --build-arg=BUNDLE_OPTIONS=--without development test
- --destination=gcr.io/<Project ID>/<image name>:latest
- --cache=true

nameにkanikoを使うイメージ名を指定することで使用することが可能です。使える引数とかはkanikoのドキュメントを見れば大体わかると思います。必要なのはcachedestinationcacheは前回ビルドのキャッシュを使うかどうか、destinationはビルドしたイメージをどのリポジトリに登録するかの指定です。

build-argについては上記のDockerfileでARGを指定していた部分があります。Railsの場合はProductionでは不要なgemのインストールを避けるためにこんな感じで逃げることができます。

このyamlファイルを指定して実行するには

$ gcloud builds submit --project <Project ID> --config ./cloudbuild.yml

で実行すればOKです。projectを付けてるのは自分の場合は複数プロジェクトを使用する場合があるので、ほぼほぼ必死なので付けてるだけです。

ちなみにこのkanikoを使うなら以下のコマンドを叩いてkanikoの使用を有効化する必要があります。

$ gcloud config set builds/use_kaniko True


Cloud Runのデプロイ

ここまで来たら最後はデプロイです。

デプロイの時に大切なのは、Cloud SQL Proxyを使用するオプションを付けることが大事です。

サクッとデプロイコマンドを貼ると

$ gcloud beta run deploy <Cloud run service name> \

--project <Project ID> \
--image gcr.io/<Project ID>/<image name> \
--region us-central1 \
--add-cloudsql-instances <Project ID>:<region>:<Cloud SQL Instance name> \
--set-env-vars RAILS_ENV=production \
--set-env-vars RAILS_MASTER_KEY=<Rails master key> \
--set-env-vars DB_USERNAME=<database user name> \
--set-env-vars DB_PASSWORD=<database password> \
--set-env-vars DB_HOST=/cloudsql/<Project ID>:<region>:<Cloud SQL Instance name>

add-cloudsql-instancesというオプションがCloud Runで実行するコンテナにCloud SQL Proxyを使用するようにしています。これで先程指定したunix socketのファイルが生成されるので、Cloud SQLへ接続できるようになるはずです。


最後に

アプリケーションを使用する上で最低限必要なものを想定して使用すると課題も出てきます。

Cloud Runのbetaリリース当初はCloud SQL Proxyの設定はなく、泣く泣くDockerイメージの中にCloud SQL Proxyをインストールして使っていたのですが、対応されたことにより上記のよう設定だけで完了できるようになりました。

AWSも素晴らしいですが、GCPもこういった素晴らしいサービスが多々あるので、必要なものを取捨選択できるような状態になるのが好ましいですね。


参考URL

https://cloud.google.com/run/docs/quickstarts/build-and-deploy

https://cloud.google.com/run/docs/configuring/connect-cloudsql

https://cloud.google.com/cloud-build/docs/kaniko-cache