Restrict Google CloudSQL to a Kubernetes cluster

If you’re on the Google cloud and are using a SQL database it’s not unlikely that you’re using a Google CloudSQL instance or two. When creating a Cloud SQL instance you want to lock down the access so that only authorized networks can to connect to your instance. This is typically done by configuring the allowed hosts of the database instance. But if you want to lock down the database to only be accessible from a Kubernetes cluster running on Google Container Engine you need to manually maintain the allowed hosts list. The reason for is that your Kubernetes cluster doesn’t have a fixed IP range and cluster instances may come and go at any time. Also your cluster may be expanded with new machines that also needs to access the database. This places a huge burden for the operations team to keep track of and maintaining this.

The Workaround

Luckily it turns out that Jordi Collell has created a nice little app called cloudsqlip. This app can be deployed in a pod inside a Kubernetes cluster to monitor the nodes and maintain the Google CloudSQL allowed hosts list based on the current state of the cluster. Jordi was nice enough to publish the the app to DockerHub for everyone to use. So how do you use it? It’s really quite easy, here are the step-by-step instructions:

Make sure that the “Cloud SQL Enabled” permission is set for your Google Container Engine cluster (you can check this by going to Google Developers Console > Container Engine > Container clusters > and check “Permissions”)

Fork the github repository and customize the rc.yml file. Here’s an example:

YAML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

apiVersion: v1

kind: ReplicationController

metadata:

labels:

name: cloudsqlip

version: "0.3"

name: cloudsqlip

spec:

replicas: 1

selector:

name: cloudsqlip

version: v1

template:

metadata:

labels:

name: cloudsqlip

version: v1

spec:

containers:

- name: cloudsqlip

image: jordic/cloudsqlip:0.3

resources:

limits:

cpu: 10m

memory: 50Mi

command:

-/main

--db

-cloudsqldbserver

--extra

-188.166.20.115/32

Replace cloudsqldbserver with the name of your Google Cloud SQL instance name (for example if the instance id is my-project:my-server then the name should be my-server).
Also note the parameter called extra. This is optional and it’s a way to tell cloudsqlip that it should not only allow the Kubernetes cluster to access the database but also some other network. For example you might want to put the subnet of your workplace here if you want to access the database from work. If you don’t need this just leave the last two lines out.

Now all we need to do is to deploy the replication controller to Kubernetes:

Shell

1

$kubectl create-frc.yml

You can see that it’s up and running correctly by listing all pods (kubectl get pods):

Shell

1

2

3

NAME READY STATUS RESTARTS AGE

cloudsqlip-ysps91/1Running02s

....

Watching the logs (kubectl logs cloudsqlip-ysps9) should give you something like this:

And that’s it! The cloudsqlip pod will now poll the list of cluster nodes every 10 seconds and maintain the allowed hosts for you!

Note that you only need to deploy one instance of cloudsqlipper database in your cluster. In the future it might be possible to specify multiple databases (-db) when starting up the app.

Conclusion

This approach should be seen as a workaround until Google has a better solution to the problem, once they’ve fixed it there should be no need to run cloudsqlip in your cluster. But until then cloudsqlip is a nice little app that makes your life a bit easier when it comes to running Kubernetes on Google Container Engine with Cloud SQL.

[…] Luckily Jordi Collell has created a little app called cloudsqlip which can be deployed in a pod inside a Kubernetes cluster to monitor the nodes and maintain the Google CloudSQL allowed hosts list based on the current state of the cluster. Jordi was nice enough to publish the the app to DockerHub for everyone to use so this is what we ended up using. If you want to know more on how to actually use it please refer to this blog post. […]