Docker部署Redis主从集群主节点无法绑定6379端口的解决方法
部署3个Redis容器(1主2从)时,主节点频繁出现绑定IP失败错误:
2023-11-18 11:12:57 1:M 18 Nov 2023 08:12:57.243 # Warning: Could not create server TCP listening socket 172.28.0.1:6379: bind: Cannot assign requested address
2023-11-18 11:12:57 1:M 18 Nov 2023 08:12:57.243 # Failed listening on port 6379 (tcp), aborting.
部分从节点也会出现类似错误,偶尔能正常运行。
当前使用的docker-compose.yml:
networks: hl-lab3-network: ipam: driver: default config: - subnet: 172.28.0.0/16 services: server: build: context: ./server_component env_file: - .env ports: - "${PORT}:${PORT}" client: build: context: ./client_component redis-master: image: redis:7 container_name: master command: bash -c "redis-server ./redis-master.conf --appendonly yes --requirepass password" ports: - 6379:6379 networks: - hl-lab3-network volumes: - ./:/data redis-slave-1: image: redis:7 container_name: slave-1 command: redis-server ./redis-slave1.conf --replicaof master 6379 --requirepass password ports: - 6381:6381 networks: - hl-lab3-network volumes: - ./redis-slave1.conf:/data/redis-slave1.conf redis-slave-2: image: redis:7 container_name: slave-2 command: redis-server ./redis-slave2.conf --replicaof master 6379 --requirepass password ports: - 6382:6382 networks: - hl-lab3-network volumes: - ./redis-slave2.conf:/data/redis-slave2.conf
Redis配置文件:redis-master.conf:
port 6379 bind 172.28.0.1 requirepass password replica-read-only yes
redis-slave1.conf:
port 6381 bind 172.28.0.2 masterauth password replica-read-only yes slaveof master 6379
redis-slave2.conf:
port 6382 bind 172.28.0.3 masterauth password replica-read-only yes slaveof master 6379
错误核心原因:Redis配置中绑定的固定IP,Docker并未自动分配给对应容器。Docker默认会在子网内随机分配IP,除非显式指定固定IP,或让Redis监听所有网卡地址。
方案1:给Redis容器指定固定IP
修改docker-compose.yml,在每个Redis服务的networks字段下添加ipv4_address,明确分配你配置文件中指定的IP:
networks: hl-lab3-network: ipam: driver: default config: - subnet: 172.28.0.0/16 services: server: build: context: ./server_component env_file: - .env ports: - "${PORT}:${PORT}" client: build: context: ./client_component redis-master: image: redis:7 container_name: master command: bash -c "redis-server ./redis-master.conf --appendonly yes --requirepass password" ports: - 6379:6379 networks: hl-lab3-network: ipv4_address: 172.28.0.1 volumes: - ./:/data redis-slave-1: image: redis:7 container_name: slave-1 command: redis-server ./redis-slave1.conf --replicaof master 6379 --requirepass password ports: - 6381:6381 networks: hl-lab3-network: ipv4_address: 172.28.0.2 volumes: - ./redis-slave1.conf:/data/redis-slave1.conf redis-slave-2: image: redis:7 container_name: slave-2 command: redis-server ./redis-slave2.conf --replicaof master 6379 --requirepass password ports: - 6382:6382 networks: hl-lab3-network: ipv4_address: 172.28.0.3 volumes: - ./redis-slave2.conf:/data/redis-slave2.conf
方案2:让Redis监听所有网卡(更灵活)
如果不想维护固定IP,可将Redis配置中的bind改为0.0.0.0,让Redis监听容器内所有网卡地址,不管Docker分配什么IP都能正常启动:
- 修改
redis-master.conf:
port 6379 bind 0.0.0.0 requirepass password replica-read-only yes
- 修改
redis-slave1.conf:
port 6381 bind 0.0.0.0 masterauth password replica-read-only yes slaveof master 6379
- 修改
redis-slave2.conf:
port 6382 bind 0.0.0.0 masterauth password replica-read-only yes slaveof master 6379
容器间通过服务名master即可通信,Docker Compose会自动配置DNS解析。
最后:清理旧容器并重新部署
执行以下命令清理旧容器和网络,再启动新服务:
docker-compose down docker-compose up -d
内容的提问来源于stack exchange,提问作者aristotle

