Cloud SQL Proxy Operator を使ったプライベート IP の Cloud SQL インスタンスへの接続
要約
クラウドエースの北野です。
Cloud SQL Proxy Operator を使って、GKE からプライベート IP のみを有する Cloud SQL インスタンスに接続する方法を紹介します。
以下のような GKE 上の Pod から Cloud SQL への接続を実現させます。
構築の手順は以下の通りです。
- Google Cloud 上で GKE クラスター、 Cloud SQL インスタンス、Pod 用の Service Account の作成
- Kubernetes に Cloud SQL Proxy Operator のインストール
- Pod、ServiceAccount、AuthProxyWorkload リソースの作成
また簡便に構築するため、GKE の構成は以下とします。
- 運用モード: Autopilot クラスタ
- ネットワーク: Private Service Access によるプライベート IP での接続
検証では、Cloud SQL for PostgreSQL を作成し、postgres のコンテナから psql コマンドを使い接続を確認します。
Cloud SQL Proxy Operator とは
Cloud SQL Proxy Operator は、2023年5月16日にリリースされた機能で、オープンソースの Kubernetes オペレータです。
Cloud SQL Proxy Operator は Pod に AuthProxy コンテナを挿入し、Cloud SQL のデータベースへの接続を作成します。 このリソースを使用するには、カスタムリソース AuthProxyWorkload
を定義し、挿入する Pod を指定します。
今まで AuthProxy を使い接続する場合、AuthProxy コンテナをサイドカーとして挿入する必要がありましたが、 Cloud SQL Proxy Operator を使うと、AuthProxy のコンテナが Pod に自動で挿入されます。そのため、Cloud SQL Proxy Operator を使うと、アプリケーションのマニフェストから AuthProxy を分離させることが可能になります。
Cloud SQL Proxy Operator が、AuthProxy コンテナを挿入できるリソースは以下の通りです。
- Deployment
- StatefulSet
- Pod
- ReplicaSet
- DaemonSet
- Job
- CronJob
カスタムリソース AuthProxyWorkload
AuthProxy の接続を定義するカスタムリソース AuthProxyWorkload の API 仕様について簡単に紹介します。
AuthProxyWorkload リソースの spec では、以下の内容を指定します。
- workloadSelector: AuthProxy コンテナを挿入するリソースの指定
- instances: AuthProxy で接続する Cloud SQL の指定
- authProxyContainer: AuthProxy コンテナのスペックの指定
workloadSelector は以下の内容を設定できます。
変数名 | 変数の内容 |
---|---|
selector | 対象のリソースのラベル情報 |
kind | 対象のリソースの種類 |
name | リソース名 |
instances は以下の内容を設定できます。
変数名 | 変数の内容 |
---|---|
connectionString | Cloud SQL の インスタンス接続名 ( プロジェクト ID :リージョン:インスタンス名 ) |
port | Cloud SQL の接続先ポート番号 |
autoIAMAuthN | IAM 認証のインスタンスか否か |
privateIP | Cloud SQL にプライベート IP で接続するか否か |
pcs | Private Service Connect での接続か否か (privateIP の設定と一緒には使えない) |
portEnvName | Cloud SQL インスタンス接続先ポート番号を格納した環境変数名 |
hostEnvName | Cloud SQL インスタンス接続先のホスト情報を格納した環境変数名 |
unixSocketPath | プロキシがリッスンしている Unix ソケットのパス |
unixSocketPathEnvName | unixSocketPath の値を格納した環境変数名 |
authProxyContainer は以下の内容を設定できます。
変数名 | 変数の内容 |
---|---|
container | Container を使い AuthProxy コンテナ以外のコンテナの挿入 |
resources | Resource を使い AuthProxy のリソースの limits, requests の指定 |
telemetry | コンテナが出力するテレメトリーの指定 |
adminServer | Pod 内のコンテナが利用できるプロキシの管理サービスの指定 |
authentication | Cloud SQL への認証方法の指定 |
maxConnections | Cloud SQL への接続数の最大値 |
maxSigtermDelay | TERM 受信後の接続の閉塞を待つ最大時間 |
sqlAdminAPIEndpoint | デバッグ時の Google Cloud API のエンドポイントの変更先 |
image | AuthProxy のコンテナイメージ名 |
rolloutStrategy | AuthProxy のコンテナのロールアウトストラテジを挿入先のリソースのストラテジに沿わせるか否か |
quiet | AuthProxy のログ量を抑える --quiet を設定するか否か |
プライベート IP のみ Cloud SQL インスタンスへの接続
以下のような構成で Cloud SQL Proxy Operator の挙動を確認します。
Cloud SQL と GKE の VPC ネットワークを Private Service Access によりプライベート通信の経路を確保します。また、Cloud SQL インスタンスは、作成時にパブリック IP を無効にし、外部ネットワークからアクセスできないようにします。
今回、Cloud SQL for PostgreSQL のインスタンスを作成します。GKE からの接続には、Docker Hub の postgres イメージを使い作成した Pod から psql コマンドを発行し接続を確認します。
Google Cloud 上に作成するリソースは以下の通りです。
リソースの種類 | 役割 |
---|---|
Cloud SQL | GKE が接続する Cloud SQL for PostgreSQL インスタンス |
GKE | Cloud SQL に接続する Pod を稼動させる Kubernetes 基盤 |
VPC Network | GKE が稼動するネットワーク |
Service Account | Pod への権限付与 |
Kubernetes 上に作成するリソースは以下の通りです。
リソースの種類 | 役割 |
---|---|
AuthProxyWorkload | Cloud SQL への接続 |
Pod | psql コマンドにより Cloud SQL に接続するコンテナが動く環境 |
ServiceAccount | Pod のサービスアカウント |
Google Cloud のリソース作成
まず、Cloud SQL インスタンスおよび GKE Autopilot を作成します。
始めに Cloud SQL インスタンスと GKE Autopilot クラスタを作成する VPC ネットワークとサブネットワークを作成します。
gcloud compute networks create $VPC_NETWORK_NAME \
--project $PROJECT_ID \
--subnet-mode custom
gcloud compute networks subnets create $SUBNETWORK_NAME \
--project $PROJECT_ID \
--network $VPC_NETWORK_NAME \
--region $REGION \
--range $ADDRESS_RANGE
次にプライベート IP の Cloud SQL インスタンス用のプライベート IP と Private Service Access を作成します。
gcloud compute addresses create $ADDRESS_NAME \
--project $PROJECT_ID \
--global \
--purpose VPC_PEERING \
--prefix-length $PREFIX_LENGTH \
--network $VPC_NETWORK_NAME \
gcloud services vpc-peerings connect \
--project $PROJECT_ID \
--service servicenetworking.googleapis.com \
--ranges $ADDRESS_NAME \
--network $VPC_NETWORK_NAME
プライベート IP の Cloud SQL インスタンスを先のプライベート IP と Private Service Access を使い作成します。
gcloud beta sql instances create $CLOUDSQL_INSTANCE_NAME \
--project $PROJECT_ID \
--network $VPC_NETWORK_NAME \
--tier $TIER \
--database-version $DATABASE_VERSION \
--no-assign-ip \
--allocated-ip-range-name $ADDRESS_NAME \
--region $REGION \
--enable-google-private-path
続いて、GKE Autopilot を次のコマンドで作成します。
gcloud container clusters create-auto $GKE_CLUSTER_NAME \
--project $PROJECT_ID \
--location $REGION \
--network $VPC_NETWORK_NAME \
--subnetwork $SUBNETWORK_NAME \
最後に Pod 用のサービスアカウントを作成し、Cloud SQL の接続に必要な権限を付与します。
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
--project $PROJECT_ID
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[$NAMESPACE/$KSA_NAME]"
Kubernetes 上の設定
作成した GKE クラスタに接続します。
gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
--region $REGION \
--project $PROJECT_ID
GKE に Cloud SQL Proxy Operator をインストールします。
gcloud container clusters get-credentials $GKE_CLUSTER_NAME \
--region $REGION \
--project $PROJECT_ID
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version "v1.9.1" \
--create-namespace \
--set global.leaderElection.namespace=cert-manager \
--set installCRDs=true
kubectl apply -f https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v1.4.5/cloud-sql-proxy-operator.yaml
作成が完了すると、cert-manager および cloud-sql-proxy-operator-system の namespace に以下のリソースが作成されます。
kubectl get deployment -n cert-manager
NAME READY UP-TO-DATE AVAILABLE AGE
cert-manager 1/1 1 1 11m
cert-manager-cainjector 1/1 1 1 11m
cert-manager-webhook 1/1 1 1 11m
kubectl get deployment -n cloud-sql-proxy-operator-system
NAME READY UP-TO-DATE AVAILABLE AGE
cloud-sql-proxy-operator-controller-manager 1/1 1 1 9m11s
以下のマニフェストを使い postgres の Pod と Pod が使う ServiceAccount を作成します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: $KSA_NAME
annotations:
iam.gke.io/gcp-service-account: $SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
---
apiVersion: v1
kind: Pod
metadata:
name: $POD_NAME
labels:
app: cloudsql
spec:
serviceAccountName: $KSA_NAME
containers:
- name: postgresql-clien
image: postgres
env:
- name: "DB_PORT"
- name: "INSTANCE_HOST"
command: ['sh', '-c', 'sleep infinity']
最後に AuthProxyWorkload リソースを以下のマニフェストを使い作成します。
apiVersion: cloudsql.cloud.google.com/v1
kind: AuthProxyWorkload
metadata:
name: $AUTHPROXYWORKLOAD_NAME
spec:
workloadSelector:
selector:
matchLabels:
app: cloudsql
kind: Pod
instances:
- connectionString: "$PROJECT_ID:$REGION:$CLOUDSQL_INSTANCE_NAME"
privateIP: true
portEnvName: "DB_PORT"
hostEnvName: "INSTANCE_HOST"
authProxyContainer:
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11
AuthProxyWorkload のリソースを作成すると、以下の様に対象の Pod 内に AuthProxy のコンテナが挿入されます。
kubectl get pod cloudsql -o json | jq '.spec.containers[] | {name: .name, image: .image}'
{
"name": "postgresql-clien",
"image": "postgres"
}
{
"name": "csql-default-sample",
"image": "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11.0"
}
最後に Pod にアクセスし、psql コマンドを使って接続できているかを確認します。
まず、AuthProxyWorkload リソースで作成した portEnvName と hostEnvName の環境変数に入力されている値について確認してみます。
kubectl exec -it $POD_NAME /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "postgresql-clien" out of: postgresql-clien, csql-default-sample
root@cloudsql:/# echo $INSTANCE_HOST
127.0.0.1
root@cloudsql:/# echo $DB_PORT
5000
psql コマンドを使って、 Cloud SQL に接続してみます。
root@cloudsql:/# psql -h $INSTANCE_HOST -p $DB_PORT -U postgres
Password for user postgres:
psql (16.3 (Debian 16.3-1.pgdg120+1), server 15.7)
Type "help" for help.
postgres=>
さいごに
Cloud SQL Proxy Operator について紹介しました。AuthProxyWorkload リソースを使い Cloud SQL への接続を分離できます。そのため、他の環境で利用していたマニフェストを簡単に移行することが可能かと思います。GKE で Cloud SQL を使う際には活用を検討してみてください。
Discussion