【GCP】Cloud Run 調査メモ

Cloud Run について調べた内容を随時追記します。
該当箇所のリファレンスを貼り付ける形式にします。（時間節約＆信憑性のため）

## Cloud Run とは
フルマネージドなコンテナ実行基盤。
>フルマネージドのサーバーレス プラットフォーム上で、スケーラブルなコンテナ化されたアプリケーションを開発し、デプロイできます。
https://cloud.google.com/run?hl=ja

Knativeベースに構築されている。
>Knativeを元に構築されたCloud Runは、Googleの最新のサーバーレスサービスです。
https://cloud.google.com/run?hl=ja

フルマネージド版と、Anthos版がある。
Anthos版の方が細やかなハードウェア要件に対応可能。
>Cloud Run for Anthos on Google Cloud には、フルマネージド環境と Anthos のどちらでサービスを実行するかを選択できる柔軟性があります。
https://cloud.google.com/anthos/run/docs/choosing-a-platform?hl=ja


### メリット
こちらにまとめられています。下記にいくつかピックアップ。

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

インフラ管理不要。
>インフラストラクチャの管理は不要です。デプロイした後は Cloud Run がサービスを管理するため、管理について心配する必要はありません。

オートスケール。N は開発者が制限可能。
>Cloud Run は、トラフィックに応じてゼロから N まで自動的にスケールします。


自動で冗長構成が取られる。
>Cloud Run サービスはリージョン単位で、複数のゾーンにわたり自動的に複製されます。

HTTPS URLがデフォルトで付属。
>各 Cloud Run サービスには安定した HTTPS エンドポイントが最初から付属しています。TLS の終端はこのエンドポイントで自動的に処理されます。

従量課金。リクエストが全くなければコンテナ数を0にする。（常駐させることも可能）
>コードが実行されている間のみ料金が発生します。使用時間は最も近い 100 ミリ秒単位に丸められます。
https://cloud.google.com/run?hl=ja

### デメリット

サイドカーコンテナを利用できない
>フルマネージド Cloud Run は、Kubernetes の名前空間、ポッドでのコンテナ共存（サイドカー）、ノードの割り当てや管理といった機能を必要としないコンテナ化されたステートレス マイクロサービスにうってつけのサーバーレス プラットフォームです。
https://cloud.google.com/blog/ja/products/containers-kubernetes/when-to-use-google-kubernetes-engine-vs-cloud-run-for-containers

上記により、フルマネージド版では、Datadog APM が利用できない。（利用には[若干ハックな対応](https://qiita.com/aokabi/items/cec169124fb9b5d7e231)が必要）
>この機能は、Google Cloud Run for Anthos/GKE でサポートされています (Cloud Run Fully Managed ではサポートされていません)。
https://docs.datadoghq.com/ja/integrations/google_cloud_run/

## 管理
### サービス
Cloud Run の管理境界。URLや認証、サービスアカウントはサービス毎に定義される。
>サービスは Cloud Run の主なリソースです。各サービスには一意で永続的な URL があります。この URL は、新しいリビジョンをサービスにデプロイしても変わりません。
https://cloud.google.com/run/docs/managing/services?hl=ja

### リビジョン
リリースバージョンみたいなもの。
>サービスにデプロイするか、サービスの構成を変更すると、新しいリビジョンが作成されます。このリビジョンは変更できません。
https://cloud.google.com/run/docs/managing/revisions?hl=ja

リビジョンに対するトラヒックの制御も可能。
>新しいリビジョンが、すべてのトラフィックを受信するか、まったく受信しないか、またはいくつかを受信するかを指定できます。また、新しいリビジョンを段階的にロールアウトするだけでなく、トラフィックを複数のリビジョン間で分割することや、リビジョンからロールバックすることもできます。
https://cloud.google.com/run/docs/managing/revisions?hl=ja

リビジョンは、コンテナイメージ、CPU、メモリ、ポート番号等から構成される。
逆に言えば、それらが異なるリビジョンを同居させ、同時にリクエストを受け付けることも可能。
>リビジョンは、環境変数、メモリ制限、同時実行などの環境設定と特定のコンテナ イメージから構成されています。
https://cloud.google.com/run/docs/resource-model?hl=ja#revisions

### サービスとリビジョンのイメージ図
サービス -> リビジョン、リビジョン -> コンテナが １対多の関係を持つ。
サービス 1 -> * リビジョン 1 -> * コンテナ (水平スケール)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/0845331a-0e68-0149-b701-23d338211673.png)
画像出典：https://www.topgate.co.jp/ggg-study-cloud-run

## 構成
### 同時実行
※ Cloud Run を利用する上で同時実行のコンセプトは把握しておくべき。

Cloud Run サービスが実行可能な最大同時リクエスト数は次のように計算される。
`サービスの最大同時リクエスト数 = 同時実行数 * コンテナインスタンス数`

>サービスにおける最大同時リクエスト数は Concurrency * コンテナインスタンス数となります
https://medium.com/google-cloud-jp/cloud-run-ga-fb31378cd0a1

同時実行数とは、1個のコンテナインスタンスが受信可能なリクエスト数
>Cloud Run では、特定のコンテナ インスタンスで同時に処理できる最大リクエスト数を指定する同時実行を設定できます。
https://cloud.google.com/run/docs/about-concurrency

同時実行数とコンテナインスタンス数(Max)をどう設計するのかは、しっかり検討する必要がある。

### オートスケーリング
受信リクエストを処理できるように、インスタンス数を自動スケール。
>Cloud Run では、リビジョンのスケーリングが自動的に行われます。すべての受信リクエストを処理できるように、必要なコンテナ インスタンスの数が調整されます。リビジョンがトラフィックを受信しない場合、デフォルトでは、コンテナ インスタンスの数がゼロにスケールインされます。このデフォルトは必要に応じて変更できます。インスタンスをアイドル状態のままにすることも、最小インスタンスの設定を使用してウォームアップを指定することもできます。
https://cloud.google.com/run/docs/about-instance-autoscaling?hl=ja

コンテナインスタンスのCPU 使用率を60%維持させるようにターゲティングしつつ、同時実行数を超えるリクエストがある場合は、コンテナインスタンスの最大数の範囲で自動スケール。（ドキュメントの内容より推察）
>スケジュールされるインスタンス数は、以下の影響を受けます。
・ 既存のインスタンスの CPU 使用率（スケジュールされたインスタンスを CPU 使用率 60% に維持するためのターゲティング）
・ 同時実行の設定
・ コンテナ インスタンスの最大数の設定
・ コンテナ インスタンスの最小数の設定
https://cloud.google.com/run/docs/about-instance-autoscaling

### キューイング
受信リクエスト数が、サービスの最大同時実行数を超える場合、60秒間だけキューで保持する。
`サービスの最大同時リクエスト数 = 同時実行数 * コンテナインスタンス数`
>最大インスタンス数の上限を設定すると、トラフィック負荷を処理できるインスタンスが不足することがあります。その場合、受信リクエストは最大 60 秒間キューに入れられます。この 60 秒間に、インスタンスがリクエストの処理が完了すると、キューに入れられたリクエストを処理できるようになります。60 秒の間に使用可能になるインスタンスがない場合、リクエストは失敗し、Cloud Run 上に 429 のエラーコードを表示します。
https://cloud.google.com/run/docs/about-instance-autoscaling

### タイムアウト
デフォルトで5分。最長で60分。
60分以上かかるバッチ処理などには不向き。
>リクエスト タイムアウトの設定には、Cloud Run にデプロイされたサービスがレスポンスを返すまでの制限時間を指定します。指定した時間内にレスポンスが返されない場合、リクエストが終了し、エラー 504 が返されます。
タイムアウトはデフォルトで 5 分に設定されていますが、60 分まで延長できます。
https://cloud.google.com/run/docs/configuring/request-timeout

追記: Always on CPU の登場により、一部のユースケースに対応できるようになった。
>この機能により、これまで Cloud Run では対応できなかった多くのユースケースに可能性が広がります。
・応答を返した後にバックグラウンド タスクとその他の非同期処理作業を実行する
・バックグラウンド スレッドでの CPU アクセスが想定される可能性のある OpenTelemetry などのモニタリング エージェントを利用する
・Go の Goroutine または Node.js async、Java スレッド、Kotlin コルーチンを使用する
・組み込みのスケジューリング / バックグラウンド機能を使用する Spring Boot アプリを動かす
・Firestore の変更をリッスンしてメモリ内キャッシュを最新に保つ
https://cloud.google.com/blog/ja/products/serverless/cloud-run-gets-always-on-cpu-allocation

### 外向きの静的 IP アドレス
デフォルトでは動的IPだが、VPCコネクタにより静的IPを付与可能。
>デフォルトでは、Cloud Run サービスは、動的 IP アドレスプールを使用してインターネットの外部エンドポイントに接続します。Cloud Run サービスが、IP アドレスベースのファイアウォールを使用してデータベースや API などの静的 IP アドレスからの接続を必要とする外部エンドポイントに接続する場合、このデフォルトの設定は適していません。このような接続では、静的 IP アドレスを介してリクエストをルーティングするように Cloud Run サービスを構成する必要があります。
https://cloud.google.com/run/docs/configuring/static-outbound-ip?hl=ja

## セキュリティ
### IAMによるアクセス管理
IAM によってアクセス制限可能。
特定のユーザやサービスアカウントのみ Cloud Run を呼び出せるように設定可。
>これらのサービスは IAM で保護されています。デフォルトでは、サービスはプロジェクト オーナー、プロジェクト編集者、Cloud Run 管理者、Cloud Run 起動元によって呼び出すことができます。
https://cloud.google.com/run/docs/authenticating/overview

### 内向きトラヒックの制限
`すべて`、`内部のみ`、`内部とLBからのみ`の3つから選択可能。
>すべて: 使用中のサービスが公共のインターネットにアクセスできるようにします。IAM 起動元の権限は引き続き適用されます。
内部: サービスを非公開にします。これにより、同じプロジェクト内または VPC Service Controls の境界内からのリクエストのみがサービスにアクセスできるようになります。
内部と Cloud Load Balancing: サービスを公共のインターネットからアクセスできるようにしますが、内部リクエストと HTTP(S) 負荷分散経由のリクエストのみを受け入れます。
https://cloud.google.com/run/docs/securing/ingress?hl=ja

### Google Cloud Armor との統合
Google Cloud Armor は、GCP の提供する WAF である。
サーバレス NEG を使いロードバランサを構成することで、Cloud Run との統合が可能。
>Google Cloud Armor セキュリティ ポリシーは、Cloud Run、App Engine、Cloud Functions サービスを参照するサーバーレス NEG バックエンドで使用できます。
https://cloud.google.com/armor/docs/integrating-cloud-armor?hl=ja#serverless

### サービスアカウントの割当
Cloud Run で使用するサービス アカウントを独自に作成可能。
>デフォルトのサービス アカウントを使用する代わりに、ユーザーが管理するサービス アカウントを割り当て、各サービスに専用のサービス アカウントを割り当てることをおすすめします。
https://cloud.google.com/run/docs/configuring/service-accounts?hl=ja

## モニタリングとロギング
### モニタリング
Cloud Monitoring によって自動的に各種メトリクスが取得されている。
>Cloud Run は Cloud Monitoring と自動的に統合され、設定や構成の必要はありません。Cloud Run サービスの指標は、実行中に自動的に取得されます。
https://cloud.google.com/run/docs/monitoring

Cloud Monitoring により、目ぼしいメトリクスは一通り取得されている。
>Container CPU Utilization
Instance Count
Max Concurrent Requests
Container Memory Utilization
Request Count
Request Latency
https://cloud.google.com/monitoring/api/metrics_gcp#gcp-run

### ロギング
Cloud Logging によって自動的にリクエストログとコンテナログが収集されている。
>Cloud Run には 2 種類のログがあります。これらのログは、Cloud Logging に自動的に送信されます。
・ リクエストログ: Cloud Run サービスに送信されたリクエストのログ。これらのログは自動的に作成されます。
・ コンテナログ: コンテナ インスタンス（通常は独自のコード）から出力されたログです。コンテナログを作成するで説明されているように、サポートされているロケーションに書き込まれます。
https://cloud.google.com/run/docs/logging

デフォルトで出力されるリクエストログは、こんな感じ。

```
2021-06-15T01:21:58.230157Z GET 200 734B 948 ms Chrome 91 https://example.run.app/
```

コンテナログを Cloud Logging で取得する方法はいくつかある。
>サービスからログを作成する場合、ログの出力先が次のいずれかであれば、Cloud Logging によってログが自動的に取得されます。
・ 標準出力（stdout）または標準エラー（stderr）ストリーム
・ /var/log ディレクトリにあるすべてのファイル
・ syslog（/dev/log）
・ Cloud Logging クライアント ライブラリを使用して作成されたログ。このログは、多くの一般的な言語で利用可能です。
https://cloud.google.com/run/docs/logging#container-logs

ライブラリを使用することで、リクエストログとコンテナログの紐付けが可能。
>ログ エクスプローラでは、同じ trace で関連付けられたログを「親子」形式で表示できます。リクエスト ログエントリの左側にある三角形のアイコンをクリックすると、該当するリクエストに関連付けられたコンテナログが、リクエストログの下にネストされた状態で表示されます。
Cloud Logging クライアント ライブラリを使用しない限り、コンテナログは自動的にリクエストログに関連付けられません。クライアント ライブラリを使用せずにコンテナログをリクエストログに関連付けるには、上記の構造化ロギングのサンプルで示した X-Cloud-Trace-Context ヘッダーから抽出された、トレース ID を持つ logging.googleapis.com/trace フィールドを含む構造化 JSON ログの行を使用します。
https://cloud.google.com/run/docs/logging#correlate-logs

自動的にエラーを集計してくれる。
>Error Reporting は、実行中の Cloud Run サービスで発生したエラーを集計して表示します。Cloud Run は Error Reporting と自動的に統合されます。設定や構成の必要はありません。
次のエラーは自動的に表示されます。
・ Error Reporting でサポートされている言語のスタック トレースを含み、stdout、stderr などのログに送信されるすべての例外。
・ 「メモリ上限超過」と「利用できるインスタンスがありません」のサービスエラー
https://console.cloud.google.com/errors/CIb-6vLIioHJaw?time=P1D&project=zozo-zstaff-dev&hl=ja

### トレース
自動的にトレースを取得。
>Cloud Run サービスへの受信リクエストが発生すると、Cloud Trace に表示可能なトレースが自動生成されます。
https://cloud.google.com/run/docs/trace

ただし、ライブラリを入れて作り込まないと使い物にならない。
>ただし、さらに計測手法を追加する場合は、Cloud Trace を使用して、リクエストが実装内の各レイヤに伝播されるまでの時間を測定できます。たとえば、データベース クエリの完了、API リクエストの結果の取得、複雑なビジネス ロジックの実行などに要する時間を計測できます。
https://cloud.google.com/run/docs/trace

## デプロイ
GCRにプッシュし、Cloud Run にデプロイする方法が紹介されている。

https://cloud.google.com/build/docs/deploying-builds/deploy-cloud-run?hl=ja

## カスタムドメイン
>デプロイされたサービスに Cloud Run が提供するデフォルトのアドレスではなく、カスタム ドメインを設定できます。
https://cloud.google.com/run/docs/mapping-custom-domains

流れとしては、`①ドメイン登録` → `②サービスとドメインのマッピング` → `③DNS レコード追加` となる。

### ドメイン登録
https://cloud.google.com/run/docs/mapping-custom-domains#register-domain

### サービスとドメインのマッピング
https://cloud.google.com/run/docs/mapping-custom-domains#map

### DNS レコード追加
https://cloud.google.com/run/docs/mapping-custom-domains#dns_update

一連の流れについては、こちらが参考になる。

https://zenn.dev/mseto/articles/cloud-run-domain

Terraform を使いたい場合は拙稿をご覧ください。

https://qiita.com/sasamuku/items/d600faf977510989de8c

## 課金
同一リージョン内の GCR -> Cloud Run デプロイは無料。
>Container Registry からコンテナ イメージをデプロイするときに、コンテナ イメージと同じ大陸にある Cloud Run リージョンにデプロイする場合は料金が発生しません。 たとえば、us.gcr.io または gcr.io から、us-central1 または us-east1 の Cloud Run（フルマネージド）サービスにデプロイする場合は無料です。
https://cloud.google.com/run/pricing?hl=ja

CPU、メモリ、リクエスト数、ネットワーク使用量での課金。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/11c3586e-2e8f-1f21-4780-356856200d5e.png)
https://cloud.google.com/run/pricing?hl=ja

料金見積ツール（公式）

https://cloud.google.com/products/calculator?hl=ja

## Datadog との統合
### メトリクス
インテグレーションをセットアップするだけで、Datadog から確認可能。
>Cloud Run のフルマネージド版を使用する場合は、Google Cloud Platform インテグレーションをセットアップするだけです。
https://docs.datadoghq.com/ja/integrations/google_cloud_run/#メトリクスの収集

### ログ
Pub/Sub のセットアップが必要。
>Google Cloud Run は、監査ログも公開します。 Google Cloud Run のログは、Stackdriver を使用して収集され、HTTP プッシュフォワーダーを使用して Cloud Pub/Sub へ送信されます。Cloud Pub/Sub をまだセットアップしていない場合は、HTTP プッシュフォワーダーを使用してセットアップしてください。
https://docs.datadoghq.com/ja/integrations/google_cloud_run/#ログの収集

### APM
フルマネージド版は利用できない。
>注: この機能は、Google Cloud Run for Anthos/GKE でサポートされています (Cloud Run Fully Managed ではサポートされていません)。
Datadog Admission Controller を使用して、APM トレーサーと DogStatsD クライアントを自動的に構成します。次のいずれかを使用して、環境変数 DD_AGENT_HOST および DD_ENTITY_ID を挿入します。
https://docs.datadoghq.com/ja/integrations/google_cloud_run/#apm-および-dogstatsd