Maximize the Security and Efficiency of Your GKE Applications with Cloud SQL Proxy

Learn in our latest blog post how to maximize the security and efficiency of your Kubernetes applications in GKE using Cloud SQL Proxy. Discover practical step-by-step instructions for seamlessly integrating cloud databases and optimizing your GKE infrastructure. Dive in and enhance the performance of your applications on Google Cloud today!

Benefits of Cloud SQL Proxy

As applications modernize, their components are moving towards resource hosting in public cloud environments like Google, Azure, Amazon, etc. Key components such as databases and cache stores have found their way into modernization. Most applications are now containerized to improve optimization and reduce CO2 footprint. Considering this scenario, there must be a way or path to establish a connection between the applications hosted as containers and the cloud database instances. This is where Cloud SQL Proxy comes into play. With Cloud SQL Proxy, we can establish the connection between the containerized application and the cloud database instance. We can also connect via the instance’s private IP address, but the benefits listed below tend to favor using Cloud SQL Proxy as the connection path for your applications to the cloud database instances.

  • Establish Secure Connections: Cloud SQL Proxy enables secure connections by encrypting traffic to and from the database instances.
  • IAM-Based Database Authentication: It allows authentication using service accounts/workload identities, thus replicating access through IAM.

Practical Implementation – Setting Up Cloud SQL Proxy as a Container/POD in GKE

Below is a list of prerequisites for setting up a Cloud SQL Proxy pod.

  • A fully functional Google Kubernetes Engine cluster with the installed kubectl tool.
  • If we want to use connections over a private IP, we need to ensure that the Cloud SQL Proxy and the database instance share the same VPC network.
  • A Cloud SQL instance (MYSQL, PostgreSQL, SQL Server)
  • An account in the PostgreSQL instance. The application running within the GKE cluster will use these account credentials to connect to the database.

Step 1: Create a Secret with Database Configurations

For our application running in the cluster, we will configure the Cloud SQL Proxy as a sidecar. In this scenario, the application communicates with the database instance through the proxy itself. So, we need to provide the database configuration values in the same namespace shared by the application container, as shown below:

 
kubectl create secret generic <YOUR-DB-SECRET> \
  --from-literal=username=<YOUR-DATABASE-USER> \
  --from-literal=password=<YOUR-DATABASE-PASSWORD> \
  --from-literal=database=<YOUR-DATABASE-NAME>

Step 2: Get the Configuration Values of the Cloud SQL Instance

To connect the application to the database instance, we need to set up the Cloud SQL Proxy either as a VM or as a container (sidecar). For this, we need the following information about the Cloud SQL instance:

  • The instance connection name
  • Enable the Cloud SQL Admin API in the project containing your GKE cluster
  • The JSON key file (credentials) of the service account having necessary permissions in the Google project containing the resource of the Cloud SQL instance.

Step 3: Generate a Service Account Used by Cloud SQL Proxy in GKE

To run a Cloud SQL Proxy instance within a GKE cluster, we need to create a service account and grant it the necessary permissions. It is recommended to use a separate service account for each application to provide a more secure experience and smoother transition. Service account requirements:

  • It must be created in the same project where the Cloud SQL instance is running.
  • It must receive at least the role of a Cloud SQL Client IAM.
  • In case of using a private IP for connection, the Cloud SQL instance and GKE must share the same VPC network.

 
gcloud iam service-accounts keys create ~/key.json \
--iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com


 
kubectl create secret generic YOUR-SA-SECRET \
--from-file=service_account.json=~/key.json

Step 4: Run the Cloud SQL Proxy as a Sidecar/POD

Once we reach Step 4, we need to create a sidecar proxy container within the application pod due to the following benefits:

  • Using the sidecar reduces the instance exposure to the entire cluster due to IAM database permissions.
  • It reduces and prevents local exposure of SQL outbound traffic by encrypting it.

 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
      - name: cloud-sql-proxy
        image: gcr.io/cloudsql-docker/gce-proxy:1.28.0 # make sure to use the latest version
        command:
          - "/cloud_sql_proxy"
          - "-ip_address_types=PRIVATE"
          # Replace DB_PORT with the port the proxy should listen on
          # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
          - "-credential_file=/secrets/service_account.json"
        securityContext:
          runAsNonRoot: true
        volumeMounts:
        - name: <YOUR-SA-SECRET-VOLUME>
          mountPath: /secrets/
          readOnly: true
        resources:
          requests:
            memory: "2Gi"
            cpu: "1"
      volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>

Conclusion

That concludes this topic. Feel free to comment below if you encounter any questions. Stay tuned for more posts on cloud databases and Kubernetes-specific information. Until then, happy learning!