GKEからCloud SQLの接続オプションを調べてみた


## はじめに

GKEからCloud SQLへの接続について、サイドカーパターンで接続することが多かったのですが、他にどういう接続方法があるかな？と思い、調べてみました。

:::note warn
警告
2023年9月下旬時点の情報となります。

最新の情報は、公式ドキュメントをご確認ください。
:::

## この記事の対象者
* Google Kubernetes Engineのユーザ

## Cloud SQL Auth Proxyでつなぐ(サイドカーパターン)
PodとCloud SQL Auth ProxyをCloud SQL Auth Proxyを[サイドカーパターン](https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine?hl=ja#run_the_in_a_sidecar_pattern)で実行し、  
アプリケーションからはTCPやUnixSocket経由で接続する方法です。アプリケーションはCloud SQL Auth Proxy起動時に指定したローカルホストのポートにアクセスすれば、インスタンスに接続できます。

![Sidecar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/1dcfe348-4122-2e39-c432-d380cb147057.png)

アプリケーションから複数のCloud SQLインスタンス接続することも可能です。
```./cloud-sql-proxy --unix-socket /cloudsql \
myProject:us-central1:myInstance myProject:us-central1:myInstance2 & mysql -u myUser -S /cloudsql/myProject:us-central1:myInstance2
```

上記のように、接続するインスタンスを複数記述すれば、記述分のソケットファイルが作成されるので、指定するソケットファイルを切り替えてあげれば複数のインスタンスにも接続できます。

![Some_Socket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/997eba48-3b0a-174b-e5b5-22319331500b.png)

#### メリット
*   構成がシンプル
*   IAM 認可: Identity and Access Management（IAM）権限を使用して、Cloud SQLインスタンスに接続できるユーザーや対象を制御できる。
*   Cloud SQLインスタンスとの通信は、Cloud SQL Auth Proxyによって暗号化される。

#### デメリット
*   インスタンスごとにAuth Proxyの構成が必要。Cloud SQL Auth Proxyの設定情報やバージョンは、個別管理（Podごと）になる。
*   DB接続が必要なアプリケーションが増えた場合、マニフェストファイルのメンテナンスが必要になる。
*   規模が大きくなると、マニフェストのメンテナンスコストが負担となる。

## Cloud SQLのグローバルIPを指定して接続する。
Cloud SQLインスタンスのグローバルIPに直接接続する方法です。  
Cloud SQLインスタンスの設定で、承認済みネットワークでGKEのIPを許可する必要があります。  
送信元IPが不定の場合、セキュリティ上リスクとなりますので、例えば、限定公開クラスタの場合、Cloud NATに割り当てたグローバルIPを許可IPとして登録しましょう。

![GlobalIP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/e3a6ac98-546d-ea5c-82f9-c7fdf3994d83.png)


:::note warn
トラフィックは暗号化されていないため、パブリックIPアドレスを使用してインスタンスに接続する場合は、SSL/TLS証明書を適用して、転送中のデータを暗号化する必要があります。
この場合、各Cloud SQLインスタンスに紐づくクライアント証明書をアプリケーションコンテナに持たせる必要があります。
:::

#### メリット
*   構成がシンプル
*   アプリケーションごとにCloud SQL Auth Proxyを構成する必要がなくなるため、リソース使用量を抑えることができる。

#### デメリット
*   **SSL/TLSによる暗号化を行う場合、10年に1度、コンテナに組み込んだクライアント証明書の置き換え作業が必要**になる。
*   SSL/TLSによる暗号化を行わない場合、データが暗号化されていないため脆弱。
*   認証レベルが、IAMによる認証からIPレベルの認証に変更となる。(承認済みネットワーク＋MySQLによる組み込み認証での認証となる。)

## Cloud SQLのプライベートIPを指定して接続する。
Cloud SQLインスタンスにプライベートIPを構成し、プライベートIP経由で直接接続する方法です。Cloud SQLインスタンスにプライベートIPを構成する必要があります。

![PrivateIP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/5bbcb0b6-1fda-ef3f-9bd1-747d81f73a59.png)


:::note info
Cloud SQLは推移的なピアリングをサポートしてません。
参考：[GCPの細かすぎて伝わらないハイブリッドネットワーキング](https://medium.com/google-cloud-jp/gcp-%E3%81%AE%E7%B4%B0%E3%81%8B%E3%81%99%E3%81%8E%E3%81%A6%E4%BC%9D%E3%82%8F%E3%82%89%E3%81%AA%E3%81%84%E3%83%8F%E3%82%A4%E3%83%96%E3%83%AA%E3%83%83%E3%83%89%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0-14ed12ebe84d)
そのため、GKEクラスタのあるプロジェクトと、Cloud SQLインスタンスのあるプロジェクトが異なる場合は、接続できません。
\[GKEプロジェクト]-----\[Cloud SQLのプロジェクト]------\[Cloud SQL]
のような構成では、直接接続可能なのは隣り合うVPCのみとなり、VPCを経由した接続ができません。
※VPC Peeringにて接続した場合になります。
※Cloud SQLは、見た目上はプロジェクトに紐づいているように見えますが、実際のインスタンスは、プロジェクトとVPCピアリングによって接続された、[GoogleのプロジェクトにあるVPC](https://cloud.google.com/sql/docs/mysql/private-ip?hl=ja#example)に存在します。

:::

#### メリット
*   トラフィックがGCP内部にとどまるため、セキュアな通信が実現できる。

#### デメリット
*   認証レベルが、IAMによる認証からIPレベルの認証に変更となる。(MySQLによる組み込み認証での認証となる。)
*   GKEのプロジェクトと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構成を指定するカスタムリソースのAuth Proxy Workloadを利用します。  
CloudSQL Auth Proxy Operatorがこのリソースを読み取り、必要な構成を含むCloudSQL Auth Proxyコンテナを適切なワークロードに追加します。
GKEクラスタにオペレーターをインストールして、ワークロードとCloudSQLインスタンスを構成すると、CloudSQL Auth Proxy OperatorはCloudSQL Auth Proxyを自動的に構成し、GKEワークロードをCloudSQLインスタンスに接続します。

![Proxy_Operator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989477/f45f2d4a-c402-4f4d-e598-e572d861206d.png)


#### メリット
*   IAM 認可: Identity and Access Management（IAM）権限を使用して、Cloud SQLインスタンスに接続できるユーザーや対象を制御できる。
*   Cloud SQL Auth Proxyのコンテナを個別に作成する場合に比べ、バージョンアップなど管理面でメリットがある
*   Cloud SQLインスタンスとの通信は、Cloud SQL Proxy Operator(Auth Proxy)によって暗号化される。

#### デメリット
* Cloud SQL Proxy Operator分のリソースが必要
### Cloud SQL Auth Proxyとの違い

| 製品 | Cloud SQL Auth Proxy Operator| Cloud SQL Auth Proxy |
|--------|-----------------------------------------------|-------------------|
| 目的 | Cloud SQL Auth Proxy のデプロイと管理を自動化します| Cloud SQL インスタンスへの安全なアクセスを提供します|
| インストール | Kubernetes リソースを使用してインストールされる|手動でインストール |
| 設定|Kubernetesリソースを使用して設定される| 手動で設定|
| スケーラビリティ| Kubernetesリソースによって、自動でスケーリングする| 手動でスケーリングする|
| メンテナンス|Kubernetes による自動更新とメンテナンス| 手動でメンテナンスとアップデートが必要|



### Cloud SQL言語コネクタを使用して接続する
Cloud SQL言語コネクタは、Cloud SQLインスタンスへの接続時に暗号化とIAM承認を行うライブラリです。
Cloud SQL言語コネクタは、ユーザーのアプリケーションに代わってプロキシ側サーバーへの承認済み接続を作成し、その接続をアプリケーションのデータベースドライバに渡してくれます。
Cloud SQL言語コネクタは、クライアント側コンポーネントを使用してCloud SQLインスタンス上のプロキシ サーバーに接続します。
コネクタは、所有者がサーバー側プロキシに接続することを承認する一時証明書を作成し、サーバー側プロキシは、接続するために有効なTLS証明書を要求し、Cloud SQLデータベースへのアクセスを制限します。

#### メリット
*   IAM 認可: Identity and Access Management（IAM）権限を使用して、Cloud SQLインスタンスに接続できるユーザーや対象を制御できる。
*   簡素化: SSL証明書の管理、ファイアウォール ルールの構成、承認済みネットワークの有効化が不要になる。

#### デメリット
* アプリケーションの改修が必要

### Cloud SQL Auth Proxyとの違い

| 製品 | Cloud SQL Connector| Cloud SQL Auth Proxy |
|--------|-----------------------------------------------|-------------------|
| 接続方式 | Cloud SQLインスタンスに直接接続する| Proxy経由での接続となる|
| 認証 | IAMによる認証|同左|
| セキュリティ| プライベートIPとVPCで使用可能|プライベート IP および VPC で使用でき、暗号化や監査ログなどの追加のセキュリティ機能も提供する。|
| スケーラビリティ| 高トラフィックのワークロードを処理できる| 中程度のトラフィックのワークロードを処理できる|
| 互換性|すべての Cloud SQL インスタンスと互換性がある| すべての Cloud SQL インスタンスと互換性がありますが、特定の機能が利用できない場合がある|

### 全体比較

| 製品                    | Cloud SQL Auth Proxy      | グローバルIPで接続                     | プライベートIPで接続            | Cloud SQL Operator        | Cloud SQL言語コネクタ           |
| :-------------------: | :-------------------:     | :-------------------:          | :-------------------:  | :-------------------:     | :-------------------:     |
|  接続方式                 |  Proxy経由での接続              |  Cloud SQLインスタンスに直接接続          | Cloud SQLインスタンスに直接接続   |  Proxy経由での接続              |  Proxy経由での接続              |
|  トラフィックの公開範囲          | インターネット<br>(暗号化されたトラフィック) | インターネット<br>(暗号化/非暗号化されたトラフィック) | 内部通信(GCP内)             | インターネット<br>(暗号化されたトラフィック) | インターネット<br>(暗号化されたトラフィック) |
|  認証                   | IAM＋MySQL組み込み認証(ユーザID＋PW) |  MySQL組み込み認証(ユーザID＋PW)         | MySQL組み込み認証(ユーザID＋PW)  | IAM＋MySQL組み込み認証(ユーザID＋PW) | IAM＋MySQL組み込み認証(ユーザID＋PW) |
|  セキュリティ               | ◎                         |  △(非暗号化通信の場合脆弱)                | ○                      | ◎                         | ◎                         |
|  スケーラビリティ             |  手動でスケーリングが必要             |  スケーリング不要                      | スケーリング不要               | 自動でスケーリングされる              | 自動でスケーリングされる              |
|  メンテナンス性              |  手動バージョンアップが必要            | 10年に一度証明書の置き換えが必要              | 不要                     | 自動でバージョンアップされる            | 手動バージョンアップが必要             |


## おわりに
GKEからCloud SQLへの接続オプションについて、いかがだったでしょうか。
複数選択肢もあり、迷うところですが、既存のアプリケーションのコードに変更を避けたい場合は、接続の安全性やメンテナンス性を考慮すると、Cloud SQL Proxy Operator、  
アプリケーションの改修も可能なら、Cloud SQL言語コネクタが良さそうですね。  

本記事が、皆様のGCP利用のお役に立てますと幸いです。