はじめに
先日 Google Cloud Next で発表された Cloud Run を動かしてみました。実際にやってみて、想像と違ったところもあるのでまとめておきます。
参考にしたサイト
Cloud Run とは
Cloud Run は自分で作ったコンテナを、Googleが用意したサーバー環境上で動かすことができます。http(s) の口を持ったWebサイト/Web APIサーバーを手軽に作れて、スケーリングも勝手に面倒見てくれます。
一方、コンテナを使っているからと言っても何でもできるのでなく、Webサーバー以外のサービス(RDBや、ストレージサービスなど)を動かすのには適していません。
Cloud Run を使うには、次のステップを踏む必要があります。
- 準備
- コンテナのビルド
- コンテナのデプロイ
準備
Cloud SDKのインストール(と更新)
初めて Google Cloud を使う場合は、こちらの手順に従って、自分の環境にあった SDK をインストールします。
- Cloud SDK のインストール(Google Cloud のドキュメント)
インストール後(あるいはインストール済の場合)、コンポーネントのアップデート、β版コンポーネントの追加インストールを行います。
$ sudo gcloud components update
$ sudo gcloud components install beta
GCPのサインアップ
Cloud Run は Google Cloud Platform (GCP)のサービスなので、まずGCPにサインアップしてください。
さらに利用量に応じて費用が発生するため、請求先(クレジットカード情報)を登録しておく必要があります。初めて利用する場合は、今なら$300の無料クレジットが付くようです。そちら使えば当面は費用発生せずに利用できます。
GCP上のプロジェクトの準備
Google Cloud Console から、新しくプロジェクトを作成します。作成方法は「プロジェクトの作成と管理 」を参照ください。またプロジェクトを、先ほど用意した請求先に紐づけておきます。
ここで今回作ったプロジェクトIDを、 仮に cloud-run-0001 とします。
Cloud Build を有効化
Google Cloud Console の左のメニューから「Cloud Build」を選択して、APIを有効にします。
(この先でAPIを有効化)
Cloud Run を有効化
同じくGoogle Cloud Console の左のメニューから、「Cloud Run」を選択して、APIを有効にします。
(この先でAPIを有効化)
デフォルトのプロジェクトとリージョンの設定
今後 Cloud Run をコマンドラインツールから使うにあたって、デフォルトのプロジェクトとリージョンを指定します。ここで cloud-run-0001 はプロジェクトIDです。自分のものに適宜置き換えてください。
$ gcloud config set project cloud-run-0001
$ gcloud config set run/region us-central1
今のところ Cloud Run は us-central1 でしか使えないので、そこを選択しておきます。
また初めて gcloud を利用する場合には、認証が必要になる場合があります。こちらもやっておきましょう。
$ gcloud auth login
ブラウザが起動するので、認証しておきます。
コンテナのビルド
実行対象の準備
Cloud Run は httpサーバーのための仕組になります。Webサーバーや自分のプログラムを、httpリクエストに対して応答するように準備します。通信に使うポートは自分では選べず、外部から環境変数PORTで渡されたポート番号を利用する必要があります。
ローカル環境でコンテナの確認
いきなりクラウドで試すこともできますが、まずはローカル環境で確認しておくのが安心です。Dockerをインストールして起動しておいてください。
用意したプログラムをセットアップ、起動するDockerfileを用意して、コンテナをビルドします。ビルドができたらコンテナを実行して、指定したポートでつながることを確認します。
例えば次のような例で実行してみます。
- me/imagename ... イメージ名(適宜置き換えてください)
- ホスト側のポート番号 8002
- コンテナ側のポート番号 1323
$ docker build -t me/imagename
$ docker run --init -d -e PORT=1323 -p 8002:1323 me/imagename
ここではPORT環境変数で1323番を指定し、さらにホスト側の8002ポートをコンテナの1323ポートに接続しています。ブラウザで http://localhost:8002/ にアクセスして、想定したページが見られればOKです。
Cloud Build でのコンテナビルド
作成したプロジェクトID(ここでは cloud-run-0001)と、今回作るアプリ(サービス)の名前(ここでは helloworld)を使って、次のようにビルドします。
$ gcloud builds submit --project cloud-run-0001 --tag gcr.io/cloud-run-0001/helloworld
認証が終わっていなかったり、APIが有効になっていなかったりするとエラーになります。上記準備の部分を参考に設定してから、再トライしてください。
ビルドは数分~数十分かかります。成功すると、次のようなメッセージが表示されるはずです。
PUSH
Pushing gcr.io/cloud-run-0001/helloworld
The push refers to repository [gcr.io/cloud-run-0001/helloworld]
... 省略 ...
DONE
ここで示される「gcr.io/cloud-run-0001/helloworld」のようなコンテナイメージのURLが後で必要になります。
コンテナのデプロイ
コマンドラインからのデプロイ
先ほどのコンテナイメージのURLを使って、コマンドラインからCloud Runにデプロイします。
$ gcloud beta run deploy --project cloud-run-0001 --image gcr.io/cloud-run-0001/helloworld
初めてデプロイする場合は、サービス名を質問されますので、適宜名前を入力します。
Service Name を問われるので入力 (helloworldなど)
また認証の有無を問われたら、Webサイトの場合は y を、認証ありのWebAPIの場合は N を指定してください。
Allow unauthenticated invocations to new service [helloworld]? (y/N)? ←未認証の実行を許可するかの選択。Webサイトの場合はy(認証付きWebAPIの場合はN)
上手くいけば、次のようにURLが表示されてデプロイが完了します。
Service [helloworld] revision [helloworld-00001] has been deployed and is serving traffic at https://helloworld-xxxxxxxx-uc.a.run.app/
ここでブラウザで表示されたURLを開くと、自分が用意したページが表示されるはずです。(初回はコンテナが立ち上がるまでに10秒前後かかります)
コンソール画面からのデプロイ
ブラウザを使ってコンソール画面からデプロイすることもできます。「DEPLOY NEW REVISION」から
コンテナのイメージを指定してデプロイします。
オプションを指定することもできます。
- 割り当てメモリ
- 最大リクエスト(超えたら新しいコンテナを起動する)
- タイムアウト(超えたらタイムアウト扱いとする)
- 環境変数(PORT以外にも指定できる)
外部のコンテナイメージのデプロイ
Cloud Build ではなく、Docker Hub のようなコンテナイメージを管理する外部サービスに登録したイメージを使って Cloud Run にデプロイできるのかどうか試してみました。残念ながら UR Lが gcr.io で始まっていないとエラーになります。どうやら Cloud Build とセットで利用するのが前提のようです。
その他
他のGCPサービスとの比較
Google Cloud Platform には、似たようなサービスが複数存在します。個人的に App Engine SE (Standard Environment), App Engine FE(Flexible Environment), Cloud Run を使ってみて、ざっくりした位置づけを図にプロットしてみました。
お手軽さを取るか自由度を取るかで適切なサービスが変わってきます。個人的な印象では、従来のApp Engine や Conpute Engine (GCE) よりも、Cloud Run は少し高いレベルでバランスが取られているように思いました。
Cloud Run の制約
こちらの公式ドキュメントに制約事項が記載されています。
- コンテナは PORT環境変数で指定されるポートを待ち受ける必要がある
- PORTは現在 8080番固定だが、将来変更される可能性がある
- コンテナが起動してから4分以内に、HTTPリクエストに応答する必要がある
- コンテナはアクセスが増えると自動でスケールアウトする
- ※同時リクエスト数を1にすると、別コンテナが起動していることが観測できました
- コンテナはアクセスが無いと、自動で停止する(ゼロになる)
- ※が、2019年5月現在、8時間放置してもコンテナは起動されたままでした
- ファイルに書き込むことができるが、メモリ上の一時的なもののため、停止すると失われる
また、http 以外の通信は許可されていないようです。WebSocket 通信を試みましが、遮断されました。
※こちらの 2021.01.22のエントリーにある通り、CloudRunがWebSocketやHTTP/2, gRPCをサポートしました。(2021.02.07追記)