how to access to a remote mysql database from a nodejs app inside a kubernetes pod?

6/25/2019

I have created a POD that contains a nodejs app from wich im trying to connect to a remote database in another server. My POD configuration goes like this:

apiVersion : "v1"
kind : "Service"
metadata :
  name : "mysql"
spec :
  ports :
    -
      name : "mysql"
      protocol : "TCP"
      port : 3306
      targetPort : 3306
      nodePort : 0
---
kind: "Endpoints"
apiVersion: "v1"
metadata:
  name: "mysql"
subsets:
  -
    addresses:
      -
        ip: "xxx.xxx.xxx.xxx" #The IP Address of the external web server
    ports:
      -
        port: 3306
        name: "mysql"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: productos
  labels:
    app: productos
spec:
  replicas: 3
  selector:
    matchLabels:
      app: productos
      tier: backend
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: productos
        tier: backend
    spec:
      restartPolicy: Always
      containers:
      - image: sospinah/tutorial:lopido-ms-productos6
        name: productos
        env:
        - name: MYSQL_HOST
          value: "mysql.default.svc.cluster.local"
        - name: MYSQL_USER
          value: "<username>"
        - name: MYSQL_DATABASE
          value: "<dbname>"
        - name: MYSQL_PASSWORD
          value: "<password>"
        ports:
        - containerPort: 4000

In my nodejs application i have defined my database connection as follows:

const connection = mysql.createConnection({
        host: process.env.MYSQL_HOST,
        user: process.env.MYSQL_USER,
        password: process.env.MYSQL_PASSWORD,
        database: process.env.MYSQL_DATABASE,
});

And im getting a timeout error on app startup

> nodejs-microservice@1.0.0 start /usr/src/app
> node index.js

server listening at port 0.0.0.0:4000
error connecting mysql:  { Error: connect ETIMEDOUT
    at Connection._handleConnectTimeout (/usr/src/app/node_modules/mysql/lib/Connection.js:419:13)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at Socket.emit (events.js:208:7)
    at Socket._onTimeout (net.js:422:8)
    at ontimeout (timers.js:498:11)
    at tryOnTimeout (timers.js:323:5)
    at Timer.listOnTimeout (timers.js:290:5)
    --------------------
    at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:145:48)
    at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:52:23)
    at Connection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:130:18)
    at Object.bdConfig.testConection (/usr/src/app/database/config.js:16:23)
    at Object.<anonymous> (/usr/src/app/index.js:18:14)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
  errorno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'connect',
  fatal: true }

I would like to know what am i missing in my POD configuration and/or application configuration.

-- Sebastian Ospina
kubernetes
mysql
node.js

2 Answers

6/26/2019

You can use service name to connect pods internally. you can use 'mysql' service name if your webserver is running inside same kubernetes cluster.

If you want to run your mysql inside kubernetes cluster and want to make connection outside of kubenetes cluster then probably you can expose your mysql service to internet and you can to your mysql database from anywhere. If your all application running inside same cluster then use a service name to resolve the address.

-- Harsh Manvar
Source: StackOverflow

6/26/2019

you have defined mysql host as mysql.default.svc.cluster.local

This would work if both nodejs and mysql run in same kubernetes cluster.

-- P Ekambaram
Source: StackOverflow