Cloud SQL Proxy in a Kubernetes cluster
The goal of this guide is to help you set-up and use Google Cloud SQL in a Kubernetes cluster (GKE or not), through the Cloud SQL Proxy.
To make this as easy as possible, we will use the prepared docker image so we can minimize the number of steps. No compilation needed!
In order to set-up the Cloud SQL you will need,
One or more Google Cloud SQL Databases. Refer to the documentation to create them.
We will assume the name of the database instances are as follow:
You need a service-account token with "Project Editor" privilegies, and we will assume the file is in
$HOME/credentials.json. Refer to the documentation to get the json credential file.
$HOME/.kube/configpoints to your cluster and the namespace you want to use.
The recommended way to use the Cloud SQL Proxy in a Kubernetes cluster is to use a TCP connection, as this allows the pod to be located on any node. We will use Kubernetes DNS service to connect to the proxy seamlessly.
Setting-up the credentials
We need to create a secret to store the credentials that the Cloud Proxy needs to connect to the project database instances:
kubectl create secret generic service-account-token --from-file=credentials.json=$HOME/credentials.json
Creating the Cloud SQL Proxy deployment
We need to create a deployment that will keep the Cloud SQL Proxy container image alive.
Here is an example deployment file,
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: cloudsqlproxy spec: replicas: 1 template: metadata: labels: app: cloudsqlproxy spec: containers: # Make sure to specify image tag in production # Check out the newest version in release page # https://github.com/GoogleCloudPlatform/cloudsql-proxy/releases - image: b.gcr.io/cloudsql-docker/gce-proxy:latest # 'Always' if imageTag is 'latest', else set to 'IfNotPresent' imagePullPolicy: Always name: cloudsqlproxy command: - /cloud_sql_proxy - -dir=/cloudsql - -instances=project:database1=tcp:0.0.0.0:3306,project:database2=tcp:0.0.0.0:3307 - -credential_file=/credentials/credentials.json # set term_timeout if require graceful handling of shutdown # NOTE: proxy will stop accepting new connections; only wait on existing connections - term_timeout=10s lifecycle: preStop: exec: # (optional) add a preStop hook so that termination is delayed # this is required if your server still require new connections (e.g., connection pools) command: ['sleep', '10'] ports: - name: port-database1 containerPort: 3306 - name: port-database2 containerPort: 3307 volumeMounts: - mountPath: /cloudsql name: cloudsql - mountPath: /credentials name: service-account-token volumes: - name: cloudsql emptyDir: - name: service-account-token secret: secretName: service-account-token
And then, create the deployment:
kubectl apply -f sqlproxy-deployment.yaml
This deployment will create pods that listen for connections on port
You can also change the number of replicas to increase availability.
Services to find the proxy
We can create services to find the pods. We have decided to use one service per database to be able to select the database by name rather than by port.
Create the services configuration,
apiVersion: v1 kind: Service metadata: name: sqlproxy-service-database1 spec: ports: - port: 3306 targetPort: port-database1 selector: app: cloudsqlproxy --- apiVersion: v1 kind: Service metadata: name: sqlproxy-service-database2 spec: ports: - port: 3306 targetPort: port-database2 selector: app: cloudsqlproxy
This will create two different services,
Apply the configuration to create them:
kubectl apply -f sqlproxy-services.yaml
You can now connect using the same port
3306 to each database:
mysql --host=sqlproxy-service-database1 --port=3306 ... mysql --host=sqlproxy-service-database2 --port=3306 ...