0

I am developing an application (car-app) which uses socket.io. and now I am going to deploy it to kubernetes cluster. Then I use Redis pub/sub function to communicate.

My app structure:
  Backend: NodeJS
  Frontend: ReactJS
  Mongodb

Then I am trying to connect Redis in NodeJS. It can be run on my localhost, but it cannot run on my GKE cluster.

(NodeJS)
const redis = require('redis');
const REDISPORT = 6379;
const subscriber = redis.createClient(REDISPORT, redis);

Error while running on GKE cluster:

Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379

I think this maybe caused by service connection and my redis deployment and service are configured below.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: car-redis-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: car-redis
    spec:
      containers:
        - name: car-redis
          image: redis:latest
          ports:
            - containerPort: 6379
              name: http-port
  selector:
    matchLabels:
      app: car-redis

apiVersion: v1
kind: Service
metadata:
  name: car-redis-service
spec:
  ports:
    - port: 6379
      protocol: TCP
      targetPort: 6379
  selector:
    app: car-redis
  type: NodePort
potato
  • 203
  • 2
  • 15
  • Your Redis is running under the k8s network. You will need the Redis pod hostname instead (`car-redis`) https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ – Daniel Sep 22 '20 at 14:27
  • You can also run 2 containers in one pod, and by doing this you will have access to redis via localhost from your other container, of course this is not recomended if you are planing on using the same instance of redis from another pods – Luis Gonzalez Sep 22 '20 at 16:35

1 Answers1

1

It works on localhost because host might be already configured with redis running, so your node is looking for 127.0.0.1:6379 and it's able to connect to one without any errors.

Coming to k8s, your deployed application is looking for redis within the same container. So, you are getting an error while doing the same.

While coming to GKE or cloud, you need to configure your node application with the particular host ip or url on which your redis application is running. As, I can see you are already running a redis in your k8 cluster, if it is the same cluster as your node application deployment you can directly connect it with the service using something like this

<service-name>.<namespace-name>.svc.cluster.local How to communicate between ns?

From your example, make sure your node app supports redis url instead of just port. And add your configs car-redis-service.default.svc.cluster.local:6379 in your node app it should work without any issues.

Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107
BinaryMonster
  • 1,118
  • 7
  • 10
  • Thanks for the detailed reply. In my case, should I use redis as pod (metadata.name: redis) and service (metadata.name: redis-service) ? Then connect it with (redis.createClient(REDISPORT, 'redis://redis-service');) in my node. Will it work? – potato Sep 22 '20 at 14:46
  • 1
    Unfortunately, k8s doesn't support service or pod discovery based on their names. Yourcan connect to `redis` pod by finding the redis pod ip and do something like this (redis.createClient(REDISPORT, <>). But I can see you have 3 replicas so connect it using a service redis.createClient(REDISPORT, redis://car-redis-service.default.svc.cluster.local), something like this should also work I guess. – BinaryMonster Sep 22 '20 at 14:53
  • Using: redis.createClient(REDISPORT, 'redis-service.default.svc.cluster.local'); is working. Thanks! Do you know how to get the pod name that can be display my container? i.e. get the pod name in NodeJS when socket is connected. I want to identify my redis connection is still working when my clients are connected in different nodejs pod. – potato Sep 23 '20 at 09:36
  • 1
    Sorry for the late response. Yes you can get the `pod` name from a `ns`. But it keep changes each time a new pod is created except for `statefulsets`. Best way to do that check is to use that `address` for the service to check if the `pods` are still accepting connections. – BinaryMonster Sep 27 '20 at 06:25
  • Hello, I don't know why I use 'redis-service.default.svc.cluster.local' and got an connection error today. Could you please also check my new question in here?https://stackoverflow.com/questions/64086429/redis-connect-econnrefused-in-nodejs-in-kubernetes-cluster – potato Sep 27 '20 at 08:30