我正在尝试在安装了Istio Mesh的Kubernetes上配置Redis集群。 Redis群集可以在没有Istio的情况下创建,并且每个Pod都会自动注入一个Istio代理(Envoy)。但是,在安装Istio并将Istio代理连接到每个Redis Pods的情况下,Redis群集无法通过CLI的CLUSTER MEET命令正确“满足”。
例如,我有Redis Pod A(插槽0-10919)和Redis Pod B(插槽10920-16383)。这是尝试在它们之间执行CLUSTER MEET命令后得出的结果(群集符合ClusterIPForRedisPodB 6379)。
对于Redis Pod A,集群信息已更新,包括Redis Pod B:
相反,对于Redis Pod B,群集信息不会更新,并且不包括Redis Pod A:
我能够在两个Pod之间为端口16379和6379发送curl和netcat响应。此外,Envoy似乎也打开了这些端口。
我已经复制了您的问题,并找到了解决您问题的方法。
让我首先解释造成问题的原因。
Redis八卦协议以这种方式工作:在redis1上键入cluster meet <ip> <port>
时,redis1打开与redis2的TCP连接。在正常情况下,当redis2接收到连接时,它会接受该连接,并查找正在连接的源IP地址。并且还会打开一个与该地址的tcp连接,在这种情况下也将打开redis1。(有关[闲聊协议的工作原理,请参见redis documentation,或this article)
这里是REDIRECT
编程,并作为文档中的状态:
此模式在重定向期间丢失源IP地址这是我们的问题根源。
redis2
收到连接时,将其视为来自本地主机。 Envoy丢失了源IP地址redis1,并且redis2现在无法打开连接回到redis1。现在,我们有一些选择:TPROXY
(我尝试过但无法使它起作用)redis.conf
中文件,您可以在此部分找到:集群客户端/ NAT支持例如,您可以这样修改在某些部署中,Redis群集节点地址发现失败,因为地址是NAT-ted或因为端口已转发(典型情况是Docker和其他容器)。
为了使Redis Cluster在这样的环境中工作,每个节点都需要知道其公共地址的配置。的以下两个选项用于此范围,分别是:
cluster-announce-ip
- 集群通告端口
- 集群公告总线端口
- 每个指示节点有关其地址,客户端端口和集群消息的信息巴士港。然后将信息发布在总线数据包的标题中这样其他节点就能正确映射该节点的地址发布信息。
如果不使用上述选项,则正常的Redis群集自动检测将改为使用。
请注意,重新映射后,总线端口可能不会位于客户端端口+ 10000,因此您可以根据需要指定任何端口和总线端口有关如何重新映射它们的信息。如果未设置总线端口,则固定偏移量为通常将使用10000。
示例:
cluster-announce-ip 10.1.1.5群集通知端口6379群集公告总线端口6380
我们需要将
redis.conf
变量设置为Redis的Pod自己的IP地址。
cluster-announce-ip
ConfigMap,例如(它是redis-cluster
的修改后的redis configmap):还记得像这样将容器的--- apiVersion: v1 kind: ConfigMap metadata: name: redis-cluster data: update-node.sh: | #!/bin/sh REDIS_NODES="/data/nodes.conf" sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES} cp /conf/redis.conf /redis.conf # <------HERE----- sed -i "s/MY_IP/${POD_IP}/" /redis.conf # <------HERE----- exec "$@" redis.conf: |+ cluster-enabled yes cluster-require-full-coverage no cluster-node-timeout 15000 cluster-config-file /data/nodes.conf cluster-migration-barrier 1 appendonly yes protected-mode no cluster-announce-ip MY_IP # <------HERE-----
更改为指向正确的command
文件:
redis.conf
每个Redis节点现在都将通告此地址,因为它自己拥有,因此其他Redis节点现在将知道如何与其连接。
让我知道是否有帮助。