Using Google Kubernetes Engine, I have set up a mysql database deployment & service in kubernetes, much like the wordpress example. I want to access it via R with R which I have in another deployment & service in my kubernetes cluster (r-user-app, w/2 containers). This worked with networks in docker.
> kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.15.240.1 <none> 443/TCP 8d
mysql LoadBalancer 10.15.248.129 35.227.123.232 3306:31410/TCP 3m
r-user-app LoadBalancer 10.15.255.135 35.227.33.206 3838:31003/TCP,8787:32395/TCP 1d
Exec into the rstudio container inside the r-user-app
deployment, I see the mysql service:
root@r-user-app-1788932656-vgczh:/# getent hosts mysql
10.15.248.129 mysql.default.svc.cluster.local
However, when I try to get it via R, I have no such luck:
root@r-user-app-1788932656-vgczh:/# R
R version 3.4.2 (2017-09-28) -- "Short Summer"
-----
> require("RMySQL")
Loading required package: RMySQL
Loading required package: DBI
> mydb<-dbConnect(MySQL(), user="root", password="mypassword", host="10.15.248.129")
Error in .local(drv, ...) :
Failed to connect to database: Error: Can't connect to MySQL server on '10.15.248.129' (107)
Using the EXTERNAL-IP
doesn't work either, and putting port=3306
doesn't help.
Same thing in python:
> db=MySQLdb.connect("10.15.248.129", "root", "mypassword")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/__init__.py", line 81, in Connect
return Connection(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/connections.py", line 193, in __init__
super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (2003, 'Can\'t connect to MySQL server on \'10.15.248.129\' (111 "Connection refused")')
Maybe I don't even know the right question to ask! Please help! #kubenube
Answering my own question: This was an issue with the yaml. Needed to be sure to match the Service
selector:
app: my-app
tier: mysql
and the Deployment
spec:
selector:
matchLabels:
app: my-app
tier: mysql
Now we can access the database using "mysql" instead of a host IP address.
You don't need to use the IP. You can access the servers directly by name. You even don't need to use the full DNS name with "mysql.default.svc.cluster.local", just "mysql" is enough.
You should also check the mysql pod, if it is deployed properly. Using Type=LoadBalancer
is not a good idea for databases, as it opens them to the outer network.