根本原因是Docker默认bridge网络不支持容器名DNS解析,哨兵无法通过redis-master等名称发现主节点;必须使用自定义bridge网络并确保所有容器加入同一网络,才能实现基于名称的通信与自动发现。

为什么 Redis 哨兵容器之间 ping 不通?
根本原因不是配置写错了,而是默认 bridge 网络下容器只能靠 IP 互通,而哨兵配置里写的 redis-master 这类名字根本无法被解析。Docker 的默认网桥不支持容器名 DNS 解析,哨兵启动后连主节点都连不上,更别说互相发现。
必须用自定义网络,且所有容器(主、从、哨兵)都要加入同一个网络,才能通过容器名通信。
- 不要用
docker run --network bridge或不加--network参数 - 创建网络时别用
--driver=overlay单机部署——除非你真在多台宿主机上跑;单机就用bridge驱动 - 每个容器启动时必须显式指定
--network redis-sentinel-net,不能依赖默认 - 建议加上
--network-alias(如--network-alias redis-master),避免容器重启后别名失效
sentinel.conf 里该填 IP 还是容器名?
填容器名。哨兵配置中的 sentinel monitor mymaster redis-master 6379 2 这一行,redis-master 必须和主节点容器的 --name 或 --network-alias 完全一致,且两者都在同一自定义网络中。
如果填 IP(比如 172.18.0.2),看似能连上,但一旦容器重建,IP 变了,哨兵就会失联——这不是高可用,是伪高可用。
-
sentinel monitor后的地址必须是可被 DNS 解析的名称,不是硬编码 IP - 确认哨兵容器能
ping redis-master或telnet redis-master 6379,这是验证网络通的最简方式 - 如果用
docker-compose,服务名自动成为 DNS 名,无需额外配--network-alias
多个哨兵节点怎么确保彼此发现?
哨兵之间不靠“注册中心”或配置列表互相发现,而是靠「主动广播 + 主节点中转」:每个哨兵会向它监控的主节点发送 SENTINEL SENTINELS mymaster 命令,主节点会返回当前已知的所有哨兵列表。所以只要所有哨兵都正确监控同一个主节点,它们自然就能建立连接。
但前提是:所有哨兵必须能连上主节点,且主节点也得能反向连回哨兵(用于推送事件)。这意味着哨兵的 port(如 26379)必须对主节点开放——在自定义网络里默认是通的,但如果你加了 --ip 或限制了 bind,就可能断掉反向通道。
- 哨兵配置中不要设
bind 127.0.0.1,否则只监听本地,其他容器连不上它 - 确保
protected-mode no(尤其在非本地网络场景),否则哨兵拒绝外部连接 - 检查日志里有没有
+sentinel-address-switch或-tilt类报错,那是网络握手失败的典型信号
跨宿主机部署时防火墙和端口怎么开?
如果三台服务器各跑一部分(比如一台主+哨兵、一台从+哨兵、一台从+哨兵),就不能用 bridge 网络了,必须用 overlay 网络,并开启 Docker daemon 的 swarm 模式或使用第三方网络插件(如 Weave、Flannel)。
但更现实的做法是:关掉宿主机防火墙(或放行关键端口),并确保以下端口在所有机器间双向可达:
- Redis 主从端口:
6379(主)、6379(从,同端口也可,只要服务监听正确) - 哨兵端口:
26379(默认,可在sentinel.conf中改,但所有哨兵要一致) - Docker overlay 所需端口:
2377(管理)、7946(节点发现)、4789(VXLAN 数据)
最容易被忽略的是:哨兵需要从主节点拉取其他哨兵地址,而主节点又需要把事件推给哨兵——这个来回通信链路一旦被防火墙截断,集群就卡在「主观下线」阶段,永远升不到「客观下线」。


















