Nginx + PHP-FPMのマルチコンテナ構成のCloud Run servicesを作成する
はじめに
本日 Public Previewとなった Cloud Runの複数コンテナデプロイを使って Nginx + PHP-FPM 構成でデプロイして試した記録です。
構成
Nginx(ポート:80)が受け付けたリクエストをPHP-FPM(ポート:9000)にプロキシするシンプルな構成で検証しています。

試してみてどうだったか
- 複数のコンテナを立ち上げられるので、今までだったら1つのコンテナに詰め込まないといけなかったケースを救えるようになった。
- DatadogやFluentdのAgentをサイドカーとして共にデプロイするといった活用も可能に
- YAMLを使ったデプロイにしか対応していないため、今までの運用とは変わってくる
- 現時点(2023/5/16)では、WEBコンソールからだと Ingressコンテナ(リクエストを受け付けるコンテナ)しか変更できない。
- 今回のケースの場合
- NginxのコンテナはWEBコンソールからでも変更ができる
- PHP-FPMのコンテナはYAML経由でしか更新ができない
※ gcloud run deployコマンドからも同様に変更できませんでした。

ERROR: gcloud crashed (ValueError): List of containers must contain exactly one element

コード
今回検証に使ったコードはここにおいています。
デプロイの流れ
※ 今回のコードをcloneした前提で進めています。
イメージをビルド
# Cloud Buildでイメージビルドを実行
gcloud builds submit .
イメージ名をYAMLファイルに設定
【Nginxのイメージ】と【PHPのイメージ】にイメージ名を設定
(gcr.io/【プロジェクト】/nginx-php-fpm-example-nginx:latestというイメージができているので、これを設定する)
Cloud SDK(gcloud)のコマンドを使ってCloud Runへデプロイ
gcloud run services replace run-service.yaml
デプロイが成功したあと、セキュリティタブの認証のところで未認証の呼び出しを許可を選択して保存してください。

その後、Cloud Runが発行しているドメインへアクセスすると、phpinfoの内容が無事表示されました。
表示されたphpinfo

複数コンテナをデプロイしたときのWEBコンソール表示

Cloud Loggingを確認すると、それぞれのコンテナのログが識別できる形で出力されています。


引っかかった部分
containerPortをそれぞれのコンテナに設定するものと勘違いしてデプロイエラーとなった。
NginxとPHP-FPMそれぞれのコンテナにcontainerPortを書いてデプロイしようとすると
ERROR: (gcloud.run.services.replace) spec.template.spec.containers: Revision template should contain exactly one container with an exposed port.
と出力されました。
エラーメッセージの通り、公開できるポートは1つのみとなっているためです。
これは containerPort が設定されているコンテナが Ingressコンテナ(外からのリクエストを受け付けるコンテナ)になるため、複数コンテナに設定されていると判定ができなくなるためと推測されます。
今回のケースだと、外からのリクエストを受け付けるNginxのコンテナにのみcontainerPortを記述します。
おわりに
いままでは複数コンテナが必要な場合はGKEを使うといった方法を取るしかなかったですが、今回のサイドカー対応によってこの問題も解消できそうです。
YAMLファイルを使った更新なのでいままでの手軽さは少し減りますが、とても可能性を感じるアップデートだと思っています。
(先日のツイートの反応の数からも、結構な数の方々が期待されてるんだなと感じました)
追記
もしかして、Cloud Run jobs でもいけるのでは?と思いましたがだめでした。
(使えたら、定期実行時にだけ必要なコンテナを立ち上げて使えたのになと思い)

Discussion