如何在 Kubernetes 集群内配置 Redis 集群以供外部应用程序访问

如何在 Kubernetes 集群内配置 Redis 集群以供外部应用程序访问

我无法将 Kubernetes 上的 Redis 集群暴露给外部应用程序。使用 Kubernetes 负载均衡器服务,我能够为 Redis 分配一个外部 IP,以提供初始连接。问题是,每当客户端收到命令时MOVED,IP 地址都是 Kubernetes 内部 POD IP,集群外的 Redis 客户端无法访问。

以下是一个示例会话,用于redis-cli演示:

10.150.0.5:7000> set test value
-> Redirected to slot [6918] located at 10.28.1.9:6379
Could not connect to Redis at 10.28.1.9:6379: Operation timed out

您如何解决这个问题?我读过的所有教程/指南都没有对如何将集群暴露给外部服务提供太多指导。大多数人关心的是在 K8s 中设置 Redis 集群。

答案1

对于仍在寻找答案的人来说,我发现最好的选择是使用(现在官方的)Redis Proxyhttps://github.com/RedisLabs/redis-cluster-proxy

注意:正如 Yogesh 在他的评论中提到的 - 这是 alpha 代码 - 所以请避免在生产工作负载中执行此操作,直到代码稳定/您知道自己在做什么。

  1. 在 K8 中设置 Redis 集群
  2. 部署 redis-cluster-proxy 并设置它以连接到您的 redis 集群
  3. 创建 K8 的外部服务以指向 redis-cluster-proxy 实例,而不是实际的 redis 集群实例
  4. 您的应用应使用此服务连接到 Redis

解释 代理基本上“假装”是一个单一的 Redis 实例,因此连接到它的客户端不需要具备集群意识。

您应该使用最新版本的 Redis,最好是 v6 或更高版本。

答案2

更新:

我认为我对这个问题不太清楚。在原帖的评论之后。我将查看 redis 集群设置和类似问题。

以下是我发现的内容

由此Github 问题当 Redis 执行“重定向到插槽 xxx”行为时,它不会通过 Redis 服务器代理连接,而是简单地将适当服务器的 IP 地址传回给客户端,然后客户端直接发起连接。

由此Github 问题如果某个 docker 容器死亡,而新容器重新启动,我们会将 nodes.conf 从卷重新连接到该容器,以便它可以自动再次加入当前正在运行的 Redis 集群。但是,当容器重新启动时,它会带有不同的 IP 地址。当我们在此容器内启动新的 Redis 服务器时,它不会更新唯一新生成的容器的 nodes.conf 文件中的 IP 地址。但所有其他节点都知道其 nodes.conf 中的新 IP 地址。总体而言,发生故障的节点不会在 nodes.conf 中更新其自己的 IP 地址

所以这里的结论是我们需要在重启后将 pod 的 IP 更新到nodes.conf文件中,这样它才能加入集群。示例可以在这里找到这里nodes.conf通过添加脚本在重启后添加podIP 。

旧答案:

如果您正在使用LoadBalancer服务进行公开,请考虑使用静态 IP,这样它就不会被分配给新 IP。

以下是一个示例

apiVersion: v1
kind: Service
metadata:
  name: redis
  labels:
    app: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379
  type: LoadBalancer
  loadBalancerIP: "YOUR.IP.ADDRESS.HERE"

用保留的内部 IP替换YOUR.IP.ADDRESS.HERE(记住它是区域 IP)。

如何在 GCP 中保留内部 IP

答案3

由于这是我的专业领域,我已经在 Google Cloud Platform 方面研究了这个问题,并发现了以下文档[1]。有关 Redis 的其他文档 [2] 证实了您对 Redis 如何处理 IP 的假设。似乎 Redis 节点在向客户端发送时会使用自己的 IP,因此,当客户端回复(通过负载均衡器)时,会使用错误的 IP。这种行为可能是 Redis 设计人员故意为之。我找不到解决方法,而且我必须承认这超出了我的范围。一些值得思考的问题:虽然 GKE 可以与数据库一起使用,但这不是最佳实践。如果您确实想在 k8s 中使用数据库,则应使用 StatefulSet,它将尝试维护相同的 pod ip。Google 确实提供了集成到云中的替代方法。有几种产品可供选择,也许花一些时间审查您的需求和 Google 产品的功能会很有成效。其中一个特别的产品是 Cloud Memorystore,因为它的预期用途是与 Redis 一起使用。该产品的文档指出:“Cloud Memorystore for Redis 完全符合 Redis 协议。”[3]

[1] 连接Redis实例:https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-gke [2] 客户端和服务端角色: https://redis.io/topics/cluster-spec [3] Cloud Memorystore for Redis 概述: https://cloud.google.com/memorystore/docs/redis/redis-overview

相关内容