前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >解决redis集群内部ip问题

解决redis集群内部ip问题

作者头像
DH镔
发布2023-10-21 11:48:54
8560
发布2023-10-21 11:48:54
举报
文章被收录于专栏:编程从踩坑到跳坑

# 解决redis集群内部ip问题

# 背景

服务上云,内网的redis集群,通过ip映射的方式把redis的端口映射到公网(白名单),公网的机器通过lettuce等客户端连接的时候,lettuce客户端的集群模式是先通过cluster nodes 获取节点拓扑 ,在操作key的时候先通过算法定位到key在哪个节点,获取key如果重定向到其它节点的话,就会从对应的节点获取。这就会导致获取到的ip是内网的ip,公网连接不上的问题,以下是通过iptables的方式解决。

# 验证环境

使用docker创建3个redis,并关联成集群

代码语言:javascript
复制
# 生成3个redis
for port in $(seq 1 3); \
do \
mkdir -p ./node-${port}/conf
touch ./node-${port}/conf/redis.conf
cat << EOF > ./node-${port}/conf/redis.conf
port 800${port}
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-port 800${port}
cluster-announce-bus-port 1800${port}
appendonly yes
EOF
done

# 运行3个redis

sudo docker run --name redis-1 \
-v `pwd`/node-1/data:/data \
-v `pwd`/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d -p 8001:8001 redis:5.0.12 redis-server /etc/redis/redis.conf

sudo docker run --name redis-2 \
-v `pwd`/node-2/data:/data \
-v `pwd`/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d -p 8002:8002 redis:5.0.12 redis-server /etc/redis/redis.conf

sudo docker run --name redis-3 \
-v `pwd`/node-3/data:/data \
-v `pwd`/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d -p 8003:8003 redis:5.0.12 redis-server /etc/redis/redis.conf


# 关联集群,ip以实际ip为准
redis-cli --cluster create 172.17.0.2:8001 172.17.0.3:8002 172.17.0.4:8003  --cluster-replicas 0

ip映射关系:

代码语言:javascript
复制
10.8.46.40:8001 -- 172.17.0.2:8001
10.8.46.40:8002 -- 172.17.0.3:8002
10.8.46.40:8002 -- 172.17.0.4:8003

# 测试

在另一台机器(10.8.46.51)访问:

代码语言:javascript
复制
sudo docker run -it --rm --net host redis redis-cli -c -h 10.8.46.40 -p 8001

执行get请求ip访问不通

代码语言:javascript
复制
$ sudo docker run -it --rm --net host redis redis-cli -c -h 10.8.46.40 -p 8001
10.8.46.40:8001> get a
-> Redirected to slot [15495] located at 172.17.0.4:8003
Could not connect to Redis at 172.17.0.4:8003: No route to host
(3.05s)
not connected>

添加iptables规则

代码语言:javascript
复制
sudo iptables -t nat -A OUTPUT -d 172.17.0.2 -p tcp --dport 8001 -j DNAT --to-destination 10.8.46.40:8001
sudo iptables -t nat -A OUTPUT -d 172.17.0.3 -p tcp --dport 8002 -j DNAT --to-destination 10.8.46.40:8002
sudo iptables -t nat -A OUTPUT -d 172.17.0.4 -p tcp --dport 8003 -j DNAT --to-destination 10.8.46.40:8003
代码语言:javascript
复制
$ sudo iptables -t nat -nvL --line-number
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       95  6219 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
2        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            172.17.0.2           tcp dpt:8001 to:10.8.46.40:8001
3        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            172.17.0.3           tcp dpt:8002 to:10.8.46.40:8002
4        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            172.17.0.4           tcp dpt:8003 to:10.8.46.40:8003

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        6   360 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0 

访问正常,因为网络是通的了,就不需要访问10.8.46.40了,可以直接访问172.17.0.2

代码语言:javascript
复制
$ sudo docker run -it --rm --net host redis redis-cli -c -h 10.8.46.40 -p 8001
10.8.46.40:8001> get a
-> Redirected to slot [15495] located at 172.17.0.4:8003
"123"
172.17.0.4:8003> 
代码语言:javascript
复制
$ sudo iptables -t nat -nvL --line-number
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       95  6219 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        6   360 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 解决redis集群内部ip问题
    • # 背景
      • # 验证环境
        • # 测试
        相关产品与服务
        云数据库 Redis®
        腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档