Как подключить Redis к сервису в NodeJS в кластере K8s?

Я разрабатываю приложение (автомобильное приложение), в котором используется socket.io. а теперь я собираюсь развернуть его в кластере кубернетов. Затем я использую функцию Redis pub / sub для общения.

My app structure:
  Backend: NodeJS
  Frontend: ReactJS
  Mongodb

Затем я пытаюсь подключить Redis в NodeJS. Его можно запустить на моем локальном хосте, но не на моем кластере GKE.

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

Ошибка при работе в кластере GKE:

Ошибка: подключение Redis к 127.0.0.1:6379 не удалось - подключите ECONNREFUSED 127.0.0.1:6379

Я думаю, что это может быть вызвано подключением к службе, и мое развертывание и служба Redis настроены ниже.

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

person potato    schedule 22.09.2020    source источник
comment
Ваш Redis работает в сети k8s. Вместо этого вам понадобится имя хоста модуля Redis (car-redis) kubernetes.io/ документы / концепции / услуги-сети / dns-pod-service   -  person Daniel    schedule 22.09.2020
comment
Вы также можете запустить 2 контейнера в одном модуле, и, сделав это, вы получите доступ к redis через localhost из другого контейнера, конечно, это не рекомендуется, если вы планируете использовать один и тот же экземпляр redis из других модулей.   -  person Luis Gonzalez    schedule 22.09.2020


Ответы (1)


Он работает на локальном хосте, потому что хост может быть уже настроен с запущенным redis, поэтому ваш node ищет 127.0.0.1:6379 и может подключиться к нему без каких-либо ошибок.

Переходя к k8s, ваш развернутый application ищет redis в том же контейнере. Итак, вы получаете сообщение об ошибке, делая то же самое.

При переходе в GKE или облако вам необходимо настроить node приложение с конкретным host ip или url, на котором работает ваше redis приложение. Как я вижу, вы уже используете redis в своем кластере k8, если это тот же кластер, что и развертывание вашего node приложения, вы можете напрямую подключить его к службе, используя что-то вроде этого

<service-name>.<namespace-name>.svc.cluster.local Как общаться между русскими?

В вашем примере убедитесь, что ваше node приложение поддерживает redis url, а не только порт. И добавьте свои car-redis-service.default.svc.cluster.local:6379 конфиги в node приложение, оно должно работать без проблем.

person BinaryMonster    schedule 22.09.2020
comment
Спасибо за подробный ответ. В моем случае следует использовать redis в качестве модуля (metadata.name: redis) и службы (metadata.name: redis-service)? Затем подключите его с помощью (redis.createClient (REDISPORT, 'redis: // redis-service');) в моем узле. Это будет работать? - person potato; 22.09.2020
comment
К сожалению, k8s не поддерживает обнаружение служб или модулей на основе их имен. Вы можете подключиться к модулю redis, найдя ip модуля redis и сделав что-то вроде этого (redis.createClient (REDISPORT, ‹* pod ip ››). Но я вижу, что у вас есть 3 реплики, поэтому подключите его с помощью службы redis.createClient (REDISPORT , redis: //car-redis-service.default.svc.cluster.local), я думаю, что-то вроде этого тоже должно сработать. - person BinaryMonster; 22.09.2020
comment
Использование: redis.createClient (REDISPORT, 'redis-service.default.svc.cluster.local'); работает. Спасибо! Вы знаете, как получить имя модуля, которое может отображать мой контейнер? т.е. получить имя модуля в NodeJS при подключении сокета. Я хочу определить, что мое соединение Redis все еще работает, когда мои клиенты подключены к разным модулям nodejs. - person potato; 23.09.2020
comment
Извините за поздний ответ. Да, вы можете получить имя pod из ns. Но он сохраняет изменения каждый раз, когда создается новый модуль, за исключением statefulsets. Лучший способ выполнить эту проверку - использовать этот address для службы, чтобы проверить, принимают ли pods соединения. - person BinaryMonster; 27.09.2020
comment
Здравствуйте, я не знаю, почему я использую redis-service.default.svc.cluster.local и сегодня получил ошибку подключения. Не могли бы вы также проверить здесь мой новый вопрос? stackoverflow.com/questions/64086429/ - person potato; 27.09.2020