Need help connecting Node to Neo4j database with Kubernetes

7/19/2017

Currently, I am getting the ECONNREFUSED where node can't connect to the database. I am not sure where the database host is supposed to end up. Should I be using localhost:7474, 127.0.0.1:7474, 0.0.0.0:7474, or am I supposed to use some host that gets generated when I get my Kubernetes pods up that I can somehow pass in? e.g. like $(minikube ip) = 192.168.90.100:7474, but for my database? Is there an ENV containing the database host that I am supposed to be pulling from somewhere?

const neo4jDatabase = connect({
  server: 'http://<what goes here!?>:7474',
  user: process.env.DB_USER,
  pass: process.env.DB_PASS,
});

I seem to have gotten the pods running with the below .yml configs, but am not sure if the neo4j one is correct.

NAME                     READY     STATUS    RESTARTS   AGE
neo4j-4166717986-8qbwq   1/1       Running   0          41m
node-481322091-g27md     1/1       Running   0          11m

node.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: node
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: node
        tier: backend
        track: stable
    spec:
      containers:
        - name: node
          image: "myapp"
          ports:
            - name: nodeport
              containerPort: 8080
          env:
           - name: DB_USER
             valueFrom:
               configMapKeyRef:
                 name: config
                 key: db_user
           - name: DB_PASS
             valueFrom:
               configMapKeyRef:
                 name: config
                 key: db_pass
---
apiVersion: v1
kind: Service
metadata:
  name: node
spec:
  selector:
    app: node
    tier: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort:
  type: LoadBalancer

neo4j.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: neo4j
spec:
  template:
    metadata:
      labels:
        run: neo4j
    spec:
      containers:
        - name: neo4j
          image: "my-neo4j"
          ports:
            - containerPort: 7474
---
apiVersion: v1
kind: Service
metadata:
  name: neo4j
  labels:
    run: neo4j
spec:
  selector:
    run: neo4j
  ports:
    - port: 7474
      targetPort: 7474
      protocol: TCP
-- atkayla
docker
kubernetes
neo4j
node.js

1 Answer

7/21/2017

Perhaps a less known feature of Kubernetes is the fact that some magic environment variables are injected in the running pods.

In your particular case, pods have an environment variable for each service in the namespace. The format is the following:

<your service>_SERVICE_HOST
<your service name>_SERVICE_PORT_EXPOSED_PORT

You can verify this is true by attaching to a running pod with kubectl exec -ti <your pod id> sh and issuing a printenv command.

Please note that if the service was created AFTER the pod, you have to delete the pod with kubectl delete pod <your pod id> to force recreation (and injection) of the environment variables.

In your case, the final code will look like this:

const serviceHost = process.ENV.NEO4J_SERVICE_HOST;
const servicePort = process.ENV.NEO4J_SERVICE_PORT_EXPOSED_PORT;
const neo4jDatabase = connect({
  server: `http://${serviceHost}:${servicePort}`,
  user: process.env.DB_USER,
  pass: process.env.DB_PASS,
});
-- danielepolencic
Source: StackOverflow