在 Docker 上使用 Sentinel 的 Redis HA

问题描述

我现在正在为 Docker 上的 Redis HA 苦苦挣扎一周。我不太相信我的意图是否会奏效。文档是可以理解的,但是有很多例子与文档不对应。

好吧,我想做的是建立一个 Redis Cluster,其中包含 1 个主服务器、2 个副本和 3 个 Sentinel。这是托管在 192.168.1.10 上。我想通过来自 192.168.1.11 的应用程序访问集群。 RedisCluster 在没有 Sentinel 的情况下正常工作。复制工作正常。

当我启动哨兵时,我在所有 3 个 Redis-Container 上得到以下日志条目:redis-0、redis-1 和 redis-2

1:S 22 Dec 2020 18:43:38.349 * Connecting to MASTER 172.20.0.2:6379
1:S 22 Dec 2020 18:43:38.350 * MASTER <-> REPLICA sync started
1:S 22 Dec 2020 18:43:38.350 * Non blocking connect for SYNC fired the event.
1:S 22 Dec 2020 18:43:38.350 * Master replied to PING,replication can continue...
1:S 22 Dec 2020 18:43:38.350 * Trying a partial resynchronization (request eac3aa540e767589e9673ae0ed844d985ed2abb2:1856).
1:S 22 Dec 2020 18:43:38.350 * Master is currently unable to PSYNC but should be in the future: -NOMASTERLINK Can't SYNC while not connected with my master

我尝试按照 this 教程进行操作,但没有奏效。与描述的行为相同。 这些是我的 Docker 命令

# Redis (with custom redis.conf will not work the replication) so i keep it simple this way.
docker run --name redis-0 -d --network redis -p 6379:6379 redis redis-server
docker run --name redis-1 -d --network redis -p 6380:6379 redis redis-server --slaveof redis-0 6379
docker run --name redis-2 -d --network redis -p 6381:6379 redis redis-server --slaveof redis-0 6379
# Sentinel
docker run -d --name sentinel-0 --network redis -v ${PWD}/sentinel-0:/etc/redis/  redis  redis-sentinel /etc/redis/sentinel.conf
docker run -d --name sentinel-1 --network redis -v ${PWD}/sentinel-1:/etc/redis/  redis  redis-sentinel /etc/redis/sentinel.conf
docker run -d --name sentinel-2 --network redis -v ${PWD}/sentinel-2:/etc/redis/  redis  redis-sentinel /etc/redis/sentinel.conf

这些是sentinel.conf

port 5000
# sentinel monitor <master-group-name> <ip> <port> <quorum>
sentinel monitor mymaster 172.20.0.2 6379 2
sentinel down-after-milliseconds mymaster 1000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

Sentinel-Container 拥有对 sentinel.conf 的写访问权限。

这些是我的 iptables 说明

# Redis
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 6379 -j DNAT --to-destination 172.20.0.2:6379
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 6380 -j DNAT --to-destination 172.20.0.3:6379
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 6381 -j DNAT --to-destination 172.20.0.4:6379

# Sentinel
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 26379 -j DNAT --to-destination 172.20.0.5:6379
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 26380 -j DNAT --to-destination 172.20.0.6:6379
/usr/sbin/iptables -t nat -A PREROUTING -p tcp --dport 26381 -j DNAT --to-destination 172.20.0.7:6379

我非常了解文档:

由于 Sentinels 使用 masters INFO 输出自动检测副本 信息,检测到的副本将无法访问,并且 Sentinel 永远无法对主节点进行故障转移,因为没有好处 从系统的角度来看是副本,所以目前有 无法使用 Sentinel 监控一组主实例和副本实例 使用 Docker 部署,除非您指示 Docker 映射端口 1:1。

对于第一个问题,如果你想运行一组 Sentinel 使用带有转发端口(或任何其他 NAT 设置)的 Docker 的实例 端口重映射的地方),可以使用下面两个Sentinel 配置指令以强制 Sentinel 宣布一个 一组特定的 IP 和端口:

哨兵公告-ip 哨兵公告端口 请注意,Docker 能够在主机网络模式下运行(检查 --net=host 选项以获取更多信息)。这应该不会造成任何问题,因为在此设置中不会重新映射端口。

我只是不知道将announce-IP 和Port 放在哪里以及它们的值必须是什么。还要注意 --net=host 将不起作用,因为我在同一个 Host:port 上有 3 个容器。

如何在为 Redis HA 服务的 Docker 环境中运行 Sentinel?

感谢您的帮助!

编辑:

我进行了故障转移测试并得到以下结果(哨兵 0、1 和 2 的结果相同)

# docker exec -it sentinel-0 redis-cli -p 5000
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "172.20.0.2"
2) "6379"
# docker stop redis-0
redis-0
# docker exec -it sentinel-0 redis-cli -p 5000
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "172.20.0.2"
2) "6379"

解决方法

跟随你的Docker commandssentinel.conf,它对我有用。

1:S 23 Dec 2020 03:14:59.370 * Connecting to MASTER redis-0:6379
1:S 23 Dec 2020 03:14:59.371 * MASTER <-> REPLICA sync started
1:S 23 Dec 2020 03:14:59.371 * Non blocking connect for SYNC fired the event.
1:S 23 Dec 2020 03:14:59.371 * Master replied to PING,replication can continue...
1:S 23 Dec 2020 03:14:59.372 * Trying a partial resynchronization (request 5c52aa10610b365f29fec2968e095c5b49eb6136:43).
1:S 23 Dec 2020 03:14:59.373 * Full resync from master: 1f843162cf808a500a5d57392baf585f6e1679a3:0

也许你可以查看redis-0日志,它是否接受replica的询问。