Cloud SQL Proxy Operatorを使って、Cloud SQLに接続する

# はじめに
みなさんはCloud SQL Proxy Operatorはご存知でしょうか。  
GKEクラスタ内のワークロードのCloud SQLデータベースへの接続を自動化するオープンソースのKubernetes Operatorとして、2023/5/19にGAされました。

今回は、Cloud SQL Proxy Operatorの導入から、接続テストまでを記事にしてみます。

# Cloud SQL Proxy Operatorを使って、Cloud SQLに接続する
## Cloud SQL Proxy Operatorとは

[Cloud SQL Proxy Operator](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator)は、GKEクラスタ内のワークロードのCloudSQLデータベースへの接続を自動化するオープンソースのKubernetesOperatorです。  
CloudSQL Auth Proxy Operatorを構成することで、必要な構成を含むCloudSQL Auth Proxyコンテナを作成してくれます。  
Cloud SQL Auth ProxyのコンテナのアップデートやスケーリングなどはCloud SQL Proxy Operatorによって管理されるため、個別でAuth Proxyのコンテナを立てるよりも、運用上のメリットがあります。

![Proxy_Operator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/de750a02-cb2b-9057-7232-15205414e136.png)


他の接続方法との比較は、下記をご参照ください。

https://qiita.com/kccs_tomoya-shirai/items/00a465b7e19d052b825f

## セットアップ
### 前提条件
- GCPプロジェクトを所有していること
- Google Cloud SDKの導入が完了していること(なければCloud Shellでも可)
- 特に指定がない場合、手順についてはGoogle Cloud SDKがインストールされたワークステーション上で実行しています。
### GKE Autopilotクラスタの作成
1\.　GCPプロジェクトにログインします。  
```shell
gcloud auth login
```

2\. プロジェクトを選択します。  

```shell
gcloud config set project [PROJECT_ID]
```

3\. 以下のコマンドを実行して、Autopilotクラスタを作成します。
```shell
gcloud container clusters create-auto autopilot-cluster \
  --region asia-northeast1 \
  --release-channel regular
```
4\. クラスタが正常に作成されるまで待機します。

### Cloud SQLのインスタンス作成
1\. gcloud sql instances createコマンドを実行して、Cloud SQLのインスタンスを作成します。
```shell
gcloud sql instances create autopilot-sql-instance \
  --tier db-f1-micro \
  --region asia-northeast1 \
  --database-version MYSQL_8_0
```

2\. Cloud SQL用のユーザを作成する
```shell
gcloud sql users create myapps --instance=autopilot-sql-instance --password="change password"
```

### サービスアカウントの作成、権限付与

1\. 下記コマンドで、Google サービスアカウントを作成します。
```shell
gcloud iam service-accounts create proxy-operator --display-name "proxy-operator"
```

2\. 次に、サービスアカウントにroles/cloudsql.clientのロールを割り当てます。
※Workload Identityを用いた接続では、接続先のCloud SQLインスタンスに対し、`roles/cloudsql.client`の権限が必要です。  
```shell
gcloud projects add-iam-policy-binding [PROJECT_ID] --member serviceAccount:[1で作成したサービスアカウントのアドレス] --role roles/cloudsql.client
```

### Kubernetes サービス アカウント（KSA）を Google サービス アカウント（GSA）にバインドする
1\. KubernetesのサービスアカウントとGoogleのサービスアカウントを紐づけ
```shell
gcloud iam service-accounts add-iam-policy-binding \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:[PROJECT_ID].svc.id.goog[YOUR-K8S-NAMESPACE/YOUR-KSA-NAME]" \
[1で作成したサービスアカウントのアドレス]
```

:::note info
Kubernetesサービスアカウント（KSA）をGoogleサービスアカウント（GSA）にバインドすることで、一致するKSAを使用するアプリケーションにGSAがアクセスできるようになります。
Workload IdentityはKSAをGSAにバインドし、Google Cloudとのやり取りは、GSAの権限で実行できます。
:::

### Cloud SQL Proxy Operatorの初期セットアップ
[公式リポジトリ](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/blob/main/docs/quick-start.md)の手順に従い、Cloud SQL Proxy Operatorのセットアップを行います。

1\. Kubernetesクラスタの認証を取得
```shell
gcloud container clusters get-credentials --region asia-northeast1 autopilot-cluster 
```

2\. Proxy Operatorのインストール
```shell
curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v1.2.0/install.sh | bash
```

インストールが完了すると、「cert-manager」と「cloud-sql-proxy-operator-controller-manager」が確認できます。
![installed_proxy-operator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/b0af55d4-06d3-8d72-021c-25dedef6c53b.png)



### 接続用プロファイル作成
Cloud SQLインスタンスへの接続用プロファイル(プロキシ構成)を作成します。

1\. テスト用のマニフェスト（例: cloudsql-proxy-operator.yaml）を作成します。
   ※[設定可能なパラメータ](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/blob/main/docs/api.md#api-reference)はドキュメント参照
```yaml:cloudsql-proxy-operator.yaml
apiVersion: cloudsql.cloud.google.com/v1
kind: AuthProxyWorkload
metadata:
  name: authproxyworkload-sample #ここで作成したプロファイル名をアプリケーションの環境変数にセットすれば、環境変数に接続先IPやポートが自動セットされる。
spec:
  workloadSelector:
    kind: "Deployment"
    name: "gke-cloud-sql-operator-quickstart" #プロキシ コンテナが追加されるワークロードを選択
  instances:
  - connectionString: "east-cs-verify191001:asia-northeast1:autopilot-sql-instance" #Cloud SQLのインスタンス接続名を記載
    portEnvName: "DB_PORT" 
    hostEnvName: "INSTANCE_HOST"
```
2\. プロキシ構成をデプロイします。
```
kubectl apply -f cloudsql-proxy-operator.yaml 
```
3\. サンプルアプリケーションのマニフェスト(my-apps.yaml)を作成します。

```yaml:my-apps.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: proxy-operator
  annotations:
    iam.gke.io/gcp-service-account: proxy-operator@[PROJECT_ID].iam.gserviceaccount.com
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-apps
spec:
  selector:
    matchLabels:
      app: my-apps
  template:
    metadata:
      labels:
        app: my-apps
    spec:
      serviceAccountName: proxy-operator
      containers:
      - name: my-apps
        image: mysql
        ports:
        - containerPort: 8080
        env:
        - name: PORT
          value: "8080"
        - name: INSTANCE_HOST
          value: "authproxyworkload-sample" #接続用プロファイルの名前を記載
        - name: DB_PORT
          value: "authproxyworkload-sample" #接続用プロファイルの名前を記載
        - name: MYSQL_ROOT_PASSWORD #公式のmysqlイメージで必須の環境変数となるので、仮で記載
          value: "changepassword"

```
4\. 接続確認用のサンプルアプリケーションをデプロイします。
```
kubectl apply -f cloudsql-proxy-operator.yaml 
```
 ![pod.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/b8cf09de-18d1-e549-f97e-e3f57c012f5b.png)

:::note info
環境変数に、接続用プロファイルの名前を記載すると、自動で接続用のIP、ポートが環境変数にセットされます。
Cloud SQL Auth Proxyのコンテナが自動で作成され、サイドカーとして振る舞います。
:::


## 接続テスト
1\. アプリケーションコンテナにログインします
```shell
kubectl exec -it my-apps-6459d4d574-zgz22 -c my-apps -- /bin/bash
```
2\. Proxy Operatorによって割り当てられたポートを確認します
```
bash-4.4# echo $DB_PORT
5000
```

3\. Proxy Operatorによって割り当てられたホストのIPを確認します
```shell
bash-4.4# echo $INSTANCE_HOST
127.0.0.1
```

4\. Cloud SQL Auth Proxy経由でインスタンスにログインします。  
```shell
bash-4.4# mysql -u myapps -h $INSTANCE_HOST -P $DB_PORT -p

Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2069
Server version: 8.0.31-google (Google)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

## おわりに
いかがだったでしょうか。今回は、Cloud SQL Proxy Operatorのセットアップから、サンプルアプリケーションを通して、Cloud SQLインスタンスへの接続確認を行いました。  
Cloud SQL Proxy Operatorの利用は、簡単かつ効果的な方法で、Cloud SQLへのアクセスを管理することができ、利用するAuth Proxyのバージョンなども最新のバージョンが使われアップデートなどの手間も減らすことができると思いますので、切り替えてみてはいかがでしょうか。