目次
こんにちは、tomatsuriです。
Cloud Schedulerを触ってみたいという衝動に駆られ、Cloud RunにLaravelアプリケーションをデプロイし、Cloud Schedulerで定期実行するサンプルを作成してみました。
Laravelアプリケーションの作成
まず、Cloud Schedulerから定期的にアプリケーションが実行されていることを確認するために、/batch
にGETリクエストをしたらログに”batch executed.“と出力するだけの簡単な機能を用意しておきます。
Cloud Runは標準出力に出力したログはCloud Loggingによって自動的に取得されるため1、Laravelから標準出力にログを出力するためにconfig/logging.php
のchannelsに以下を追加します。
'stdout' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'with' => [
'stream' => 'php://stdout',
],
],
(Laravel8系を使用)
あとは環境変数のLOG_CHANNELをstdoutに書き換えればOKです。 環境変数はCloud Run上で設定が可能です。2
Dockerイメージの作成
以下のようなDockerfileをプロジェクトのルートに用意します。 Cloud RunにLaravelをデプロイする方法としてApacheを使用している例をいくつか見たので、 今回はnginxでやってみました。
FROM php:8.0-fpm-alpine
RUN apk add --no-cache nginx wget
RUN mkdir -p /run/nginx
COPY docker/nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /app
COPY . /app
RUN sh -c "wget http://getcomposer.org/composer.phar && chmod a+x composer.phar && mv composer.phar /usr/local/bin/composer"
RUN cd /app && \
/usr/local/bin/composer install --no-dev
RUN chown -R www-data: /app
CMD sh /app/docker/startup.sh
nginx.confとstartup.shはこちら。 ドキュメント3に従い、PORT環境変数で定義されたポートをリッスンするように構成しています。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
keepalive_timeout 65;
server {
listen LISTEN_PORT default_server;
server_name _;
root /app/public;
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /dev/stdout;
error_log /dev/stderr;
client_max_body_size 100m;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
}
daemon off;
#!/bin/sh
sed -i "s,LISTEN_PORT,$PORT,g" /etc/nginx/nginx.conf
php-fpm -D
nginx
startup.shはchmod a+x docker/startup.sh
でパーミッションを変更しておきます。
これらはプロジェクトのルートにdockerフォルダを作成し、その中に配置しています。
Dockerfile、nginx.conf、startup.shが用意できたらdocker build -t laravel-batch01 .
を実行してビルドします。
ビルドが完了したら、docker run -e PORT=80 -p 8080:80 laravel-batch01
で起動し、localhost:8080でアクセスして確認してみましょう。
Container Registryへイメージをpush
まずはビルドしたイメージにレジストリ名をタグ付けします。4
docker tag laravel-batch01 asia.gcr.io/[PROJECT-ID]/laravel-batch01
次に、Container Registryへアクセスするための認証を行います。今回は推奨とされているgcloud 認証情報ヘルパーを使用します。5
ユーザーまたはサービスアカウント(推奨)で認証を行い、gcloud auth configure-docker
でgcloudをDockerの認証ヘルパーとして設定します。
これでタグ付きイメージをContainer Registryにpushできるようになりました。
docker push asia.gcr.io/[PROJECT-ID]/laravel-batch01
でpushし、Cloud ConsoleのContainer Registry上で確認できればOKです。
Cloud Runを作成
laravel-batch01という名前のCloud Run サービスを作成します。
Cloud Console上でCloud Runのページにアクセスし、サービスの作成へ進みます。
「サービスの最初のリビジョンの構成」のコンテナイメージのURLは、先程pushしたイメージを選択します。
Container Registryのイメージ詳細から直接作成することも可能です。
最後の「このサービスをトリガーする方法の構成」では、 Ingressは「すべてのトラフィックを許可する」を選択します。
現時点(2021/05/14)ではCloud Schedulerから内部サービスに対してhttpリクエストすることはできません。6
認証は「認証を必要とする」を選択し、作成します。
Cloud SchedulerからCloud Runを起動するためのサービスアカウントを作成
このままCloud SchedulerからCloud Runへhttpリクエストをしても、権限がなく失敗してしまいます。
そこで、作成したCloud Runを起動する権限を持つサービスアカウントを作成し、それを使用してCloud SchedulerからCloud Runへリクエストするように設定します。
ここではlaravel-batch01-invokerという名前のサービスアカウントを作成し、以下のコマンドで権限を付与します。
gcloud run services add-iam-policy-binding laravel-batch01 \
--member=serviceAccount:[サービスアカウントのメールアドレス] \
--role=roles/run.invoker
Cloud Run詳細ページの権限タブを開き、Cloud Run 起動元の権限を持つサービスアカウントが追加されていればOKです。
Cloud Schedulerの設定
「ジョブを定義する」で名前、頻度(unix-cron形式)、タイムゾーンを設定します。
「ジョブのターゲットを構成する」で、どこにどのようなリクエストを送信するのかを設定します。 今回は以下のようになります。
- ターゲットタイプ:HTTP
- URL:Cloud Runにデプロイしたアプリケーションのエンドポイント
- HTTPメソッド:GET
Authヘッダーは「OIDC トークンを追加」を選択し、先程作成したサービスアカウント(laravel-batch01-invoker)のメールアドレスを入力します。
「詳細設定を構成する」でリトライ回数などを設定できますが、今回はデフォルトのままにします。
ジョブを作成したら、ジョブが実行されるまで待ってもよいですし、「今すぐ実行」ボタンで任意のタイミングで実行することもできます。
実行結果
ジョブの結果が「成功」となり、Cloud Runのログにアプリケーションで実装したログのメッセージが出力されていれば完了です。
おわり
Cloud Run、Cloud Schedulerを使用して手軽にバッチ処理のサンプルを作成できました。
ちなみにCloud Scheduler料金は実行単位ではなくジョブ単位です。
請求アカウント毎(プロジェクト毎ではない)に3ジョブの無料枠があり、課金対象となってもジョブあたり$0.10/月とお手頃です。
今後はCloud Schedulerのhttp以外のターゲットを使ってみたり、他のサービスを使用したバッチ処理のアーキテクチャなど色々試していけたらなと思います。
脚注
- Cloud Run ドキュメント ログの記録と表示 コンテナログを作成する ↩︎
- Cloud Run ドキュメント 環境変数の使用 ↩︎
- Cloud Run ドキュメント コンテナポートの構成 ↩︎
- Container Registry ドキュメント ローカル イメージにレジストリ名でタグ付けする ↩︎
- Container Registry ドキュメント gcloud 認証情報ヘルパー ↩︎
- Cloud Run ドキュメント 内部サービスへのアクセス ↩︎
株式会社grasys(グラシス)は、技術が好きで一緒に夢中になれる仲間を募集しています。
grasysは、大規模・高負荷・高集積・高密度なシステムを多く扱っているITインフラの会社です。Google Cloud (GCP)、Amazon Web Services (AWS)、Microsoft Azureの最先端技術を活用してクラウドインフラやデータ分析基盤など、ITシステムの重要な基盤を設計・構築し、改善を続けながら運用しています。
お客様の課題解決をしながら技術を広げたい方、攻めのインフラ技術を習得したい方、とことん技術を追求したい方にとって素晴らしい環境が、grasysにはあります。
お気軽にご連絡ください。