Redis in Kubernetes doesn't connect with node

12/23/2020

I'm trying to learn DevOps and having issues using Kubernetes with redis and my node.js app

My node.js app connects to redis with following code:

const redis = require('redis');
const client = redis.createClient(process.env.REDIS_URL);
module.exports =  client

My redis.yaml file with a deployment and service:

---
apiVersion: apps/v1  # API version
kind: Deployment
metadata:
  name: redis-master # Unique name for the deployment
  labels:
    app: redis       # Labels to be applied to this deployment
spec:
  selector:
    matchLabels:     # This deployment applies to the Pods matching these labels
      app: redis
      role: master
      tier: backend
  replicas: 1        # Run a single pod in the deployment
  template:          # Template for the pods that will be created by this deployment
    metadata:
      labels:        # Labels to be applied to the Pods in this deployment
        app: redis
        role: master
        tier: backend
    spec:            # Spec for the container which will be run inside the Pod.
      containers:
      - name: master
        image: redis
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
---        
apiVersion: v1
kind: Service        # Type of Kubernetes resource
metadata:
  name: redis-master # Name of the Kubernetes resource
  labels:            # Labels that will be applied to this resource
    app: redis
    role: master
    tier: backend
spec:
  ports:
  - port: 6379       # Map incoming connections on port 6379 to the target port 6379 of the Pod
    targetPort: 6379
  selector:          # Map any Pod with the specified labels to this service
    app: redis
    role: master
    tier: backend

my app.yaml file with a deployment and service:

---
apiVersion: apps/v1
kind: Deployment                 # Type of Kubernetes resource
metadata:
  name: go-redis-app             # Unique name of the Kubernetes resource
spec:
  replicas: 3                    # Number of pods to run at any given time
  selector:
    matchLabels:
      app: go-redis-app          # This deployment applies to any Pods matching the specified label
  template:                      # This deployment will create a set of pods using the configurations in this template
    metadata:
      labels:                    # The labels that will be applied to all of the pods in this deployment
        app: go-redis-app 
    spec:
      containers:
      - name: go-redis-app
        image: alsoares59/devops-project:latest
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
          - containerPort: 8080  # Should match the port number that the Go application listens on    
        env:                     # Environment variables passed to the container
          - name: REDIS_URL
            value: redis-master
          - name: PORT
            value: "3000"
---
apiVersion: v1
kind: Service                    # Type of kubernetes resource
metadata:
  name: go-redis-app-service     # Unique name of the resource
spec:
  type: NodePort                 # Expose the Pods by opening a port on each Node and proxying it to the service.
  ports:                         # Take incoming HTTP requests on port 9090 and forward them to the targetPort of 8080
  - name: http
    port: 9090
    targetPort: 8080
  selector:
    app: go-redis-app            # Map any pod with label `app=go-redis-app` to this service

For some reason when creating those deployments and services, my node app will crash saying it can't connect to redis.

[vagrant@centos-minikube k8s]$ kubectl logs go-redis-app-6b687c7bd6-6npt7

> express-redis@1.0.0 start /
> node src/server.js

redis server should be at redis-master
Server listening on port 3000
events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: connect ENOENT redis-master
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1146:16)
Emitted 'error' event on RedisClient instance at:
    at RedisClient.on_error (/node_modules/redis/index.js:341:14)
    at Socket.<anonymous> (/node_modules/redis/index.js:222:14)
    at Socket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:106:8)
    at emitErrorCloseNT (internal/streams/destroy.js:74:3)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'connect',
  address: 'redis-master'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! express-redis@1.0.0 start: `node src/server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the express-redis@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-12-23T13_39_56_529Z-debug.log

What am I missing ? I know Kubernetes should translate redis-master into redis's pod IP address but I don't know if he is doing it well.

-- SoaAlex
kubernetes
node.js
redis

1 Answer

12/23/2020

I found it myself. I had to change the redis-client.js to this:

const redis = require('redis');
console.log("redis server should be at "+process.env.REDIS_URL)
const client = redis.createClient({
    host: process.env.REDIS_URL,
    port: process.env.REDIS_PORT
});

module.exports =  client
-- SoaAlex
Source: StackOverflow