【问题标题】:How to connect Redis with service in NodeJS in K8s cluster?如何在 K8s 集群中将 Redis 与 NodeJS 中的服务连接起来?
【发布时间】:2020-09-22 13:34:06
【问题描述】:

我正在开发一个使用 socket.io 的应用程序(汽车应用程序)。现在我要将它部署到 Kubernetes 集群。然后我使用 Redis 的 pub/sub 功能进行通信。

My app structure:
  Backend: NodeJS
  Frontend: ReactJS
  Mongodb

然后我尝试在 NodeJS 中连接 Redis。它可以在我的本地主机上运行,​​但它不能在我的 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

【问题讨论】:

  • 你的 Redis 在 k8s 网络下运行。您将需要 Redis pod 主机名 (car-redis) kubernetes.io/docs/concepts/services-networking/dns-pod-service
  • 您也可以在一个 pod 中运行 2 个容器,这样您就可以通过 localhost 从另一个容器访问 redis,当然如果您打算使用同一个实例,则不建议这样做来自另一个 pod 的 redis

标签: node.js kubernetes redis kubernetes-pod kubernetes-service


【解决方案1】:

它可以在 localhost 上运行,因为主机可能已经配置了 redis 运行,因此您的 node 正在寻找 127.0.0.1:6379 并且它能够连接到一个而不会出现任何错误。

来到 k8s,您部署的 application 正在同一个容器中寻找 redis。因此,您在执行相同操作时会遇到错误。

进入 GKE 或云时,您需要使用运行 redis 应用程序的特定 host ipurl 配置您的 node 应用程序。因为,我可以看到您已经在您的 k8 集群中运行 redis,如果它与您的 node 应用程序部署是同一个集群,您可以使用类似这样的方式直接将其与服务连接

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

从您的示例中,确保您的 node 应用程序支持 redis url 而不仅仅是端口。并将您的配置 car-redis-service.default.svc.cluster.local:6379 添加到您的 node 应用程序中,它应该可以正常工作。

【讨论】:

  • 感谢您的详细回复。就我而言,我应该将 redis 用作 pod (metadata.name: redis) 和 service (metadata.name: redis-service) 吗?然后将它与我节点中的 (redis.createClient(REDISPORT, 'redis://redis-service');) 连接。它会起作用吗?
  • 不幸的是,k8s 不支持基于名称的服务或 pod 发现。您可以通过查找 redis pod ip 连接到 redis pod 并执行类似的操作 (redis.createClient(REDISPORT, >)。但我可以看到您有 3 个副本,因此使用服务 redis.createClient 连接它(REDISPORT,redis://car-redis-service.default.svc.cluster.local),我猜这样的东西也应该起作用。
  • 使用:redis.createClient(REDISPORT, 'redis-service.default.svc.cluster.local');正在工作中。谢谢!你知道如何获取可以显示我的容器的 pod 名称吗?即在连接套接字时获取 NodeJS 中的 pod 名称。当我的客户端连接到不同的 nodejs pod 时,我想确定我的 redis 连接仍在工作。
  • 抱歉回复晚了。是的,您可以从 ns 获取 pod 名称。但每次创建新 pod 时它都会保持更改,statefulsets 除外。进行该检查的最佳方法是使用该address 服务来检查pods 是否仍在接受连接。
  • 你好,我不知道为什么我使用'redis-service.default.svc.cluster.local'今天连接错误。您能否也在这里查看我的新问题?stackoverflow.com/questions/64086429/…
猜你喜欢
  • 2019-08-03
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 2022-10-31
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
相关资源
最近更新 更多