Windows Docker部署Redis一主两从+哨兵完整实战(含静态IP方案)

前言

最近在Windows环境下使用Docker部署Redis主从+哨兵集群时,遇到了一个非常棘手的问题:哨兵容器启动时始终报错 Can't resolve instance hostname,即使容器名和服务名完全一致也无法解决。经过反复排查,最终通过静态IP方案彻底解决了DNS解析问题。本文将完整记录整个部署过程和踩坑经历。

环境说明

  • 操作系统:Windows 10/11
  • Docker Desktop:最新版本
  • Redis版本:7.2.15
  • 部署架构:一主两从 + 三个哨兵节点

一、项目目录结构

redis-sentinel/

├── docker-compose.yml

├── sentinel1_conf/

│ └── sentinel1.conf

├── sentinel2_conf/

│ └── sentinel2.conf

├── sentinel3_conf/

│ └── sentinel3.conf

├── redis_master_data/

├── redis_slave1_data/

└── redis_slave2_data/

二、完整 docker-compose.yml

version: '3.8'

services:

# ==================== Redis主节点 ====================

redis_master:

image: redis:7.2.15

container_name: redis_master

ports:

- "6379:6379"

volumes:

- ./redis_master_data:/data:rw

command: redis-server --requirepass test123# --appendonly yes

networks:

redis_net:

ipv4_address: 172.28.0.2

restart: always

# ==================== Redis从节点1 ====================

redis_slave1:

image: redis:7.2.15

container_name: redis_slave1

ports:

- "6380:6379"

volumes:

- ./redis_slave1_data:/data:rw

command: redis-server --replicaof 172.28.0.2 6379 --masterauth test123# --appendonly no --dir /tmp

networks:

redis_net:

ipv4_address: 172.28.0.3

depends_on:

- redis_master

restart: always

# ==================== Redis从节点2 ====================

redis_slave2:

image: redis:7.2.15

container_name: redis_slave2

ports:

- "6381:6379"

volumes:

- ./redis_slave2_data:/data:rw

command: redis-server --replicaof 172.28.0.2 6379 --masterauth test123# --appendonly no --dir /tmp

networks:

redis_net:

ipv4_address: 172.28.0.4

depends_on:

- redis_master

restart: always

# ==================== 哨兵节点1 ====================

redis_sentinel1:

image: redis:7.2.15

container_name: redis_sentinel1

ports:

- "26379:26379"

volumes:

- ./sentinel1_conf:/usr/local/etc/redis:rw

command: redis-sentinel /usr/local/etc/redis/sentinel1.conf

networks:

redis_net:

ipv4_address: 172.28.0.10

depends_on:

- redis_master

- redis_slave1

- redis_slave2

restart: always

# ==================== 哨兵节点2 ====================

redis_sentinel2:

image: redis:7.2.15

container_name: redis_sentinel2

ports:

- "26380:26380"

volumes:

- ./sentinel2_conf:/usr/local/etc/redis:rw

command: redis-sentinel /usr/local/etc/redis/sentinel2.conf

networks:

redis_net:

ipv4_address: 172.28.0.11

depends_on:

- redis_master

- redis_slave1

- redis_slave2

restart: always

# ==================== 哨兵节点3 ====================

redis_sentinel3:

image: redis:7.2.15

container_name: redis_sentinel3

ports:

- "26381:26381"

volumes:

- ./sentinel3_conf:/usr/local/etc/redis:rw

command: redis-sentinel /usr/local/etc/redis/sentinel3.conf

networks:

redis_net:

ipv4_address: 172.28.0.12

depends_on:

- redis_master

- redis_slave1

- redis_slave2

restart: always

networks:

redis_net:

driver: bridge

ipam:

config:

- subnet: 172.28.0.0/16

三、哨兵配置文件

sentinel1.conf

port 26379

dir /tmp

sentinel monitor mymaster 172.28.0.2 6379 2

sentinel auth-pass mymaster test123#

sentinel down-after-milliseconds mymaster 30000

sentinel failover-timeout mymaster 180000

logfile ""

sentinel2.conf

port 26380

dir /tmp

sentinel monitor mymaster 172.28.0.2 6379 2

sentinel auth-pass mymaster test123#

sentinel down-after-milliseconds mymaster 30000

sentinel failover-timeout mymaster 180000

logfile ""

sentinel3.conf

port 26381

dir /tmp

sentinel monitor mymaster 172.28.0.2 6379 2

sentinel auth-pass mymaster test123#

sentinel down-after-milliseconds mymaster 30000

sentinel failover-timeout mymaster 180000

logfile ""

四、部署步骤

1. 创建目录和配置文件

在项目根目录下创建所需目录:

mkdir redis_master_data redis_slave1_data redis_slave2_data

mkdir sentinel1_conf sentinel2_conf sentinel3_conf

将上述哨兵配置文件分别放入对应目录。

2. 启动所有服务

docker-compose up -d

3. 查看容器状态

docker ps

预期看到6个容器全部处于 Up 状态。

五、验证集群

1. 验证主从复制

查看主节点状态

docker exec -it redis_master redis-cli -a test123# info replication

预期输出:

role:master

connected_slaves:2

slave0:ip=172.28.0.3,port=6379,state=online

slave1:ip=172.28.0.4,port=6379,state=online

查看从节点状态

docker exec -it redis_slave1 redis-cli info replication

预期输出:

role:slave

master_host:172.28.0.2

master_port:6379

master_link_status:up

测试数据同步

docker exec -it redis_master redis-cli -a test123# set test_key "hello"

docker exec -it redis_slave1 redis-cli get test_key

docker exec -it redis_slave2 redis-cli get test_key

两个从节点都应返回 "hello"

2. 验证哨兵监控

查看哨兵信息

docker exec -it redis_sentinel1 redis-cli -p 26379 info sentinel

预期输出:

master0:name=mymaster,status=ok,address=172.28.0.2:6379,slaves=2,sentinels=3

查看哨兵识别的主节点

docker exec -it redis_sentinel1 redis-cli -p 26379 sentinel master mymaster

查看哨兵识别的从节点

docker exec -it redis_sentinel1 redis-cli -p 26379 sentinel slaves mymaster

3. 验证故障转移

模拟主节点宕机

docker stop redis_master

等待约30秒,观察哨兵日志:

docker logs redis_sentinel1 -f

查看新主节点

docker exec -it redis_sentinel1 redis-cli -p 26379 sentinel master mymaster

查看 ip 字段,确认已切换到从节点。

恢复原主节点

docker start redis_master

docker exec -it redis_master redis-cli -a test123# info replication

预期输出 role:slave,原主节点已降级为从节点。

六、踩坑记录

问题1:Can't resolve instance hostname

现象:哨兵容器启动时报错:

*** FATAL CONFIG FILE ERROR ***

>>> 'sentinel monitor mymaster redis_master 6379 2'

Can't resolve instance hostname.

原因分析

  1. Docker Compose 的 depends_on 只保证容器启动顺序,不保证服务完全就绪
  2. 哨兵容器启动时,DNS 解析可能尚未完成
  3. 容器名与服务名不一致时,DNS 解析会失败

解决过程

  1. 初次尝试 :将容器名改为与服务名一致(redis_master),仍然失败
  2. 二次尝试:添加启动延迟脚本,等待 DNS 解析成功,仍然不稳定
  3. 最终方案:使用静态 IP 地址,彻底避免 DNS 依赖

问题2:如何确定静态IP网段

检查现有网络

docker network ls

docker network inspect bridge

确保选择的网段不与现有网络冲突。默认 bridge 网络使用 172.17.0.0/16,因此选择 172.28.0.0/16 是安全的。

问题3:Windows CMD 命令差异

在 Windows CMD 中,grep 命令不可用,需要使用 findstr 替代:

docker network inspect redis_net | findstr "Name IPv4Address"

七、配置要点总结

配置项 说明
静态IP网段 172.28.0.0/16,与默认bridge网络隔离
主节点IP 172.28.0.2
从节点IP 172.28.0.3 ~ 172.28.0.4
哨兵IP 172.28.0.10 ~ 172.28.0.12
哨兵端口 26379、26380、26381
主节点别名 mymaster(所有哨兵配置中必须一致)
下线票数 2(至少2个哨兵同意才判定下线)
主观下线时间 30000毫秒(30秒)
故障转移超时 180000毫秒(3分钟)

八、Spring Boot 集成示例

spring:

redis:

sentinel:

master: mymaster

nodes:

- 127.0.0.1:26379

- 127.0.0.1:26380

- 127.0.0.1:26381

password: test123#

lettuce:

pool:

max-active: 8

max-idle: 8

min-idle: 0

结语

在 Docker 环境中部署 Redis 哨兵集群时,静态 IP 方案虽然增加了配置复杂度,但能彻底避免 DNS 解析问题,保证集群的稳定启动。如果你也遇到了类似的主机名解析失败问题,不妨尝试本文的静态 IP 方案。

相关推荐
笑锝没心没肺1 小时前
Linux安装docker及运行容器测试
linux·运维·docker
零域码客1 小时前
Redis 双刃剑:缓存与分布式锁的本质区别
redis·分布式·缓存·并发控制·后端架构
Escalating_xu1 小时前
【Linux】线程概念与控制:从地址空间、LWP 到 pthread_create、join、detach 与 NPTL
java·linux·redis
芷栀夏2 小时前
极空间部署Sokoban:Docker搭建网页版推箱子并实现远程访问
运维·docker·容器
老王的笔记v2 小时前
40期 本地语音克隆工具LuxTTS,1GB显存也能快速生成配音
windows
InfinitePlus2 小时前
docker redis部署
redis·docker·容器
Pocker_Spades_A4 小时前
极空间安装1Panel:图形化管理Docker应用并部署AList
运维·docker·容器
会编程的土豆4 小时前
12306 春运抢票:数据一致性怎么保证
redis·消息队列·go·高并发
ltl11 小时前
Redis 紧凑编码:listpack、quicklist 与 intset
redis