GCPチートシート

## はじめに

最近GCPデビューしました。
まだまだ書きかけ、公開メモとして、これから追記していきます。

## IAM

権限変更が反映されるまでの時間について

https://cloud.google.com/iam/docs/access-change-propagation?hl=ja

## CI/CDパイプラインやるならまずこれを読もう

https://cloud.google.com/architecture/application-development/secure-cicd-pipeline?hl=ja

## ロケーションについて

ロケーションは以下の用語で整理されている。

![スクリーンショット 2023-09-14 16.20.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169789/f5662b04-4914-daed-9630-363dee20d9fe.png)

### リージョン間の通信速度

自分がアクセスしているリージョンからの通信速度が見れるサイト

https://gcping.com/

## Cloud Run

### Cloud Runでエラーに遭遇したら

ステータスコードでも検索できる

https://cloud.google.com/run/docs/troubleshooting?hl=ja

### Cloud Run 403エラー

Cloud Run > サービス名 > セキュリティ > 認証
認証の部分をチェック

https://cloud.google.com/run/docs/troubleshooting?hl=ja#unauthorized-client

## Cloud Storage

### ロケーションに関する留意事項(可用性、パフォーマンス、料金について)

このリンク先の表で比較できます。

https://cloud.google.com/storage/docs/locations?hl=ja#considerations

Cloud Storage Standard ストレージ クラスの月間稼働率はマルチリージョンロケーションにおける 99.95% を超え、リージョン ロケーションでは 99.9% を超えています。つまり、一ヶ月を30日として計算すると、最大のダウンタイムはマルチリージョン ロケーションにおける月間約21分（年間約4時間）となり、リージョン ロケーションでは月間約43分 （年間約8時間）となります。

どれくらいのダウンタイムを許容するかで、どの設定を使用するか決まります。

https://cloud.google.com/storage/sla

### バケット名の考慮事項

https://cloud.google.com/storage/docs/buckets?hl=ja#considerations

### Cloud Storageは消去してしまった場合、復旧できない

> 警告: オブジェクトの削除は取り消すことができません。Google Cloud Storage は、デベロッパーに高い柔軟性とデータに対する制御を提供するように設計されています。Google は、削除されたデータの処理とパージの厳格な管理を維持しています。データの誤操作を防止するには、データ ライフサイクルを管理するオプションをご覧ください。


https://cloud.google.com/storage/docs/deleting-objects?hl=ja

### フロント側でCloud Storageとやり取りする場合の注意点

Cloud Storageのバケット名はデベロッパーツールから簡単に取得できる。独自ドメインを割り当てる方法は、ロードバランサーを割り当てる必要があり、別途コストも必要になる。

### Pythonクライアントのドキュメント

注意点として、用意されているライブラリでは並行アップロード・ダウンロードが許可されていないため遅い。

https://cloud.google.com/python/docs/reference/storage/latest

並行アップロード・ダウンロードを使用したい場合は、Pythonの”subprocess”モジュールを使用して、直接gsutilコマンドを実行する必要がある。

## Cloud SQL

### Cloud SQLとCloud Runの通信デバッグ用汎用インスタンス

Makefileで起動します。

```Makefile
INSTANCE_CONNECTION_NAME=test-nextjs-cloud-run-392506:us-central1:quickstart-instance
DB_NAME=quickstart_db
DB_USER=quickstart-user
DB_PASS=password

run-sql:
	gcloud run deploy run-sql --image gcr.io/$(YOUR_PROJECT_ID)/run-sql \
		--add-cloudsql-instances $(INSTANCE_CONNECTION_NAME) \
		--set-env-vars INSTANCE_UNIX_SOCKET="/cloudsql/$(INSTANCE_CONNECTION_NAME)" \
		--set-env-vars $(INSTANCE_CONNECTION_NAME)="$(INSTANCE_CONNECTION_NAME)" \
		--set-env-vars DB_NAME="$(DB_NAME)" \
		--set-env-vars DB_USER="$(DB_USER)" \
		--set-env-vars DB_PASS="$(DB_PASS)" \
		--region=$(REGION) \
		--allow-unauthenticated
```

https://cloud.google.com/sql/docs/postgres/connect-instance-cloud-run?hl=ja

## Compute Engine

### SSHで接続して開発環境として使用する

https://qiita.com/FukuharaYohei/items/fa2d75ad8406e497906f

### IPを固定する

https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address?hl=ja

この際、「API と ID の管理
」 > 「Cloud API アクセス スコープ」で「すべての Cloud API に完全アクセス権を許可」にすること。

この設定を行わないと、別プロジェクトへのAPIとか使えなくなります。

### 起動ログの確認

インスタンスに接続して、以下を実行

```
sudo journalctl -u google-startup-scripts.service
```

もしくは、インスタンスのシリアルポートってところから。

参考URL
https://cloud.google.com/compute/docs/instances/startup-scripts/linux?hl=ja

### インスタンスからメタデータ取れるかチェックするスクリプト

```
curl --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
```

### HTTPS化

https://cloud.google.com/iap/docs/load-balancer-howto?hl=ja#terraform

## GPU関連

### インスタンスの割り当て上限の確認

IAMと管理 > 割り当て > インスタンスタイプで検索

### スポットインスタンスの取得状況を確認

IAMと管理 > 割り当て > インスタンスタイプで検索 > 使用状況のアイコンをクリック

![ss 10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169789/6793bd5d-20b7-7d84-9da4-eb43dbaba0e6.jpeg)

### リージョンごとに使用できるGPUが異なるため注意が必要

https://cloud.google.com/compute/docs/gpus/gpu-regions-zones?hl=ja

### 使用可能な Deep Learning VM イメージの取得スクリプト

```sh
gcloud compute images list \
    --project deeplearning-platform-release \
    --format="value(NAME)" \
    --no-standard-images
```
## Cloud Build

### 権限の反映に時間がかかる

これ、一番ひどいと思った仕様なのですが、権限を変更したときに反映まで時間がかかります。
時間がかかるのですが、コンソールやコマンドでは権限が付与できている状態で表示されるので待ってから実行することでしか、検証ができないです。

https://blog.hirokiueno.com/deploy-cloud-functions-error/

### ビルド構成ファイルの書き方

https://cloud.google.com/build/docs/build-config-file-schema?hl=ja

### 予約済み変数の一覧

https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values?hl=ja

### ビルドに必要な権限を調べながら設定していくためのページ

https://cloud.google.com/build/docs/cloud-build-service-account?hl=ja

### ビルドで使用できるマシンタイプ

https://cloud.google.com/build/docs/api/reference/rest/v1/projects.builds#machinetype

| Enum | Description |
| --- | --- |
| UNSPECIFIED | Standard machine type. |
| N1_HIGHCPU_8 | Highcpu machine with 8 CPUs. |
| N1_HIGHCPU_32 | Highcpu machine with 32 CPUs. |
| E2_HIGHCPU_8 | Highcpu e2 machine with 8 CPUs. |
| E2_HIGHCPU_32 | Highcpu e2 machine with 32 CPUs. |
| E2_MEDIUM | E2 machine with 1 CPU. |

## GKE

### GKE での GPU について

https://cloud.google.com/kubernetes-engine/docs/concepts/gpus?hl=ja

### NVIDIA Terraform Kubernetes モジュールを使用した GPU 対応 Kubernetes クラスターのデプロイ

https://docs.omniverse.nvidia.com/farm/latest/deployments/gcp.html

### TerraformでGKEを管理する方法

https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/guides/using_gke_with_terraform

https://registry.terraform.io/modules/terraform-google-modules/kubernetes-engine/google/latest

### GKEのテスト

https://cloud.google.com/architecture/distributed-load-testing-using-gke?hl=ja

## Eventarc

TerraformでEventarcを作成するときはちょっと権限周りがややこしい。こちらのドキュメントを参考に。

https://cloud.google.com/eventarc/docs/creating-triggers-terraform?hl=ja#cloud-run

## Vertex AI

英語の記事と日本語の記事だと粒度が異なる。基本的に英語で読むこと。

https://cloud.google.com/vertex-ai/docs/predictions/use-custom-container

https://cloud.google.com/vertex-ai/docs/quotas

### VertexAIで複数モデルをデプロイする方法

主にこちらを参照

https://cloud.google.com/vertex-ai/docs/predictions/model-co-hosting

#### 最適なパターン

共同ホスティングは、デプロイされたモデルが多数あり、トラフィックがまばらな場合、つまりデプロイされた各モデルに専用マシンを割り当てるとリソースが効果的に利用されない場合にうまく機能します。

#### リクエスト数の制限

一度に実行できる同時デプロイメントリクエストの数は 20 に制限されています。

#### 制限

- Tensorflowでしか使えない(カスタムコンテナに非対応)
- 同じコンテナイメージのモデルのみ
- コンテナログが使えない


## 請求周り

### プロジェクトを消去する前に課金を無効にする

お支払い > アカウント管理 > マイプロジェクトのタブ > 個別のプロジェクト名から課金を無効にするものを選ぶ

## Terraform

### ベストプラクティス

特にディレクトリ構造を考えるとき参照しておくべき

https://cloud.google.com/docs/terraform/best-practices-for-terraform?hl=ja

### Terraform使うなら、まずブループリントが使えないか検討する

https://cloud.google.com/docs/terraform/blueprints/terraform-blueprints?hl=ja


### Error 403: Permission denied on '****' (or it may not exist).

このエラー、Permission deniedと書いているので権限周りを疑いがちだけど、存在しないパターンも多いので気をつける。

### 権限周り

Terraformで権限を触る場合、3つのリソースを使い分ける

- google_project_iam_policy
- google_project_iam_binding
- google_project_iam_member

https://blog.g-gen.co.jp/entry/how-to-use-iam-resources-of-terraform#google_project_iam_xxx-%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%81%A8%E6%B3%A8%E6%84%8F%E7%82%B9

### まず最初にブループリントがないか参照する

https://cloud.google.com/docs/terraform/blueprints/terraform-blueprints?hl=ja

### リソースを作成する場合は公式が用意しているサンプルを参考にする

https://cloud.google.com/docs/terraform/samples?hl=ja

### ドキュメントに書かれてないことも多いので最終的にはAPIのソースコードを見て判断する

snake_caseからcamelCaseに変更してソースコードを触れば出てくるので、そこを見る。

https://github.com/googleapis/googleapis

以下のような感じで定義されている。

```json
        "provisioningModel": {
          "description": "Specifies the provisioning model of the instance.",
          "type": "string",
          "enum": [
            "SPOT",
            "STANDARD"
          ],
          "enumDescriptions": [
            "Heavily discounted, no guaranteed runtime.",
            "Standard provisioning with user controlled runtime, no discounts."
          ]
        },
```

### IaS未対応のリソースもある。

Google OAuth設定のコード化をしようとしたけど、未対応っぽい?
機能リクエストが上がっていることが確認できる。

https://issuetracker.google.com/issues/116182848
https://github.com/hashicorp/terraform-provider-google/issues/6074

## モニタリング

### リアルタイムロギング

GUIのログ エクスプローラで監視するより、ローカルでリアルタイムロギングしながら監視するほうがデバッグはし易い。

例えば、VertexAIのエンドポイントなら以下のようにして、ログを取得できる。
readの後ろにクエリを記述することでGUIで取得しているものが見れる。

```bash
gcloud logging read 'resource.type="aiplatform.googleapis.com/Endpoint" resource.labels.endpoint_id="$(ENDPOINT_ID)" resource.labels.location="us-central1"' --limit 10 --format="value(jsonPayload.message)"
```

tailコマンドで監視すれば、リアルタイムでログを見れる。

```bash
gcloud beta logging tail 'resource.type="aiplatform.googleapis.com/Endpoint" resource.labels.endpoint_id="$(ENDPOINT_ID)" resource.labels.location="us-central1"' --format="value(jsonPayload.message)"
```