☰
Docker一键部署Redis集群:CentOS 7脚本实战与避坑指南
2026/10/11 2:17:09 网站建设 项目流程

简介:面向需要在CentOS 7.x环境中快速搭建Redis集群的运维人员与开发工程师,该资源提供一套基于Docker的一键部署Shell脚本方案,调用者只需按说明传递参数,即可自动完成镜像加载、节点创建与集群初始化,大幅降低手动配置成本。压缩包共6个文件,涵盖多用途Shell部署脚本、Redis配置文件、离线镜像包与Markdown使用文档,整体仅22.46MB;其中自动构建脚本与备用构建脚本可适应不同部署环境,卸载脚本方便清理还原,离线镜像则破除网络限制,适合内网或离线场景。说明文档对脚本参数、执行顺序及常见用法做了整理,能帮助使用者快速上手并理解整个部署流程。目前已有1055人学习下载,资源经上传者亲测可用,尤其适合需要频繁搭建或验证Redis集群的中高级Linux使用者,可显著提升环境准备效率。

1. Docker 一键部署 Redis 集群:这套 CentOS 7 脚本到底怎么用、值不值得下

手动部署 3 主 3 从的 Redis 集群,在 CentOS 7.x 上通常要耗掉半个多小时:拉镜像、写六份 redis.conf、起容器、挨个节点执行 CLUSTER MEET、再手工分配 hash slot。这套 docker redis 集群 shell 脚本的价值,就是把前半段全部压成一条命令,后半段用 redis-cli --cluster create 自动完成槽位分配,适用对象就是 CentOS 7.x + Docker 的 linux 服务器。初次拿到它的人在测试机上跑通 3 主 3 从集群,前后不到一支烟的时间,中间不需要任何手工交互。适合两类人:一是自己维护服务器、想快速拿到一套可用于开发压测集群的从业者;二是后端开发,想在本机复现集群故障场景,又不想把精力耗在环境搭建上。需要先说明边界:它解决的是标准三主三从集群的初始化,跨机房网络抖动、自动化扩容这些事还得靠其他手段。

2. 前置环境与网络选型:host 网络、固定 IP 与端口规划

2.1 环境基线检查:内核、Docker 版本与防火墙

拿到资源先别急着执行,脚本开头通常会有一段环境检查逻辑,先把基础环境过一遍再往下走。我一般会先手动跑这几条命令确认基线:

cat /etc/redhat-release uname -r docker version --format '{{.Server.Version}}' systemctl status docker --no-pager

逻辑说明:第一条确认系统大版本,第二条看内核版本,第三条拿 Docker 服务端版本号,第四条看 Docker 服务有没有真正跑起来。脚本内置的环境检查基本就是把这四步的结果做字符串匹配,版本不对直接退出并提示。

参数说明:CentOS 7.6 以下的内核是 3.10.x,Docker 建议 20.10 以上,新版 Docker 引擎在 iptables 规则和 bridge 网络处理上明显比老版本稳定,CentOS 7 上我不想折腾内核,直接升 Docker 收益更高、风险更小。

防火墙这块在 host 网络下尤其重要:Redis Cluster 节点之间走 TCP 直连,除了数据端口,还必须放行端口 +10000 的总线端口,否则集群创建阶段会卡在握手超时。常见做法是提前把规划范围内的端口一次性放行,避免后面排错时来回折腾:

firewall-cmd --zone=public --add-port=6379/tcp --permanent firewall-cmd --zone=public --add-port=6380/tcp --permanent firewall-cmd --zone=public --add-port=16379/tcp --permanent firewall-cmd --zone=public --add-port=16380/tcp --permanent firewall-cmd --reload

这条命令分别放行了两个实例的数据端口以及对应的 bus 端口。需要注意的是,Redis Cluster 的 bus 端口默认是数据端口加 10000,6379 对应 16379,6380 对应 16380,只放行数据端口一定会翻车。

2.2 为什么用 host 网络而不是 bridge 端口映射

这个选择背后是 Redis Cluster 的通信结构决定的。一个集群节点同时监听两个端口:数据端口用于客户端读写,cluster bus 端口用于节点间 gossip 通信和故障检测,bus 端口默认等于数据端口 +10000。如果拿 Docker 的 bridge 模式做端口映射,每个容器至少得映射两个端口,还要处理容器 IP 和宿主机 IP 不一致的问题。

bridge 模式最典型的翻车现场:gossip 消息里广播的是容器 IP,比如 172.17.0.2,其他服务器上的节点拿着这个地址去连,路由直接失败,结果表现为节点能握手,但主从切换时连不上目标节点。而 host 网络下,容器直接复用宿主机网络栈,Redis 对外广播的地址就是宿主机真实 IP,链路少一层转换,故障面小很多。

对比项bridge + 端口映射host 网络
端口暴露每个容器至少映射两个端口直接监听宿主机端口
gossip 源 IP容器 IP,常不可被其他服务器路由宿主机真实 IP
bus 端口管理需要手动核对映射关系直接按配置监听
跨服务器部署要处理 announce-ip 与映射地址只需把 announce-ip 配成真实 IP
脚本复杂度高低

所以这个脚本默认走 host 网络,不是偷懒,而是它能在“可预测”和“可排错”之间取得最佳平衡。host 网络唯一需要付出的代价是端口规划要严格,不能让两个实例的端口跟其他服务冲突。

2.3 节点清单与 redis.conf 模板的填充变量

脚本拿到手后,真正有技术含量的部分在 redis.conf 模板和节点清单的配合方式。目录结构一般是每个实例一个 conf 目录和一个 data 目录,redis.conf 由脚本按模板生成,数据目录按实例序号隔离。核心模板长这样:

port 6379 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes daemonize no cluster-announce-ip 192.168.1.20 cluster-announce-port 6379 cluster-announce-bus-port 16379

逻辑说明:cluster-enabled yes 让 Redis 以集群模式启动,不写这一项后面的 cluster create 全部白搭;cluster-config-file 指定集群元数据文件位置,由节点自动维护,不需要人工编辑;appendonly yes 开启 AOF 持久化,这关系到重启后槽位和主从关系能否恢复;cluster-announce-ip 和两个 announce 端口是 host 网络下必须手填的,直接决定了其他节点和客户端拿到的地址。

参数说明:cluster-node-timeout 5000 表示 5 秒内收不到某一节点的响应,就认为该节点可能故障,会进入客观下线判定流程。生产网络抖动明显的时候,可以把这个值调到 10000,防止瞬时丢包误触发主从切换。cluster-announce-ip 不建议写作 127.0.0.1,那会让集群只能在单机内自嗨,跨服务器部署必坑。

如果是三台服务器,每台各跑两个实例,节点清单里同一个 IP 就会重复出现两次,分别配两个不同端口;如果只是单机演练,三个 IP 都写 127.0.0.1 也能建集群,但客户端访问方式就得通过本机端口来连。

3. 脚本结构拆解:从容器循环创建到 cluster create 的调用链

3.1 节点循环创建:目录、配置文件与容器启动

脚本的主体是一个 create_node 函数,循环拉起来所有容器。这段设计得比较规整,核心逻辑可以认为是下面这样:

IP_LIST=(192.168.1.20 192.168.1.21 192.168.1.22) REDIS_PORT=(6379 6380 6379 6380 6379 6380) BASE_DIR=/opt/redis-cluster IMAGE=redis:6.2 create_node() { local node_ip=$1 local node_port=$2 local idx=$3 mkdir -p ${BASE_DIR}/${idx}/data ${BASE_DIR}/${idx}/conf docker rm -f redis-${idx} >/dev/null 2>&1 docker run -d --name redis-${idx} --network host \ --restart unless-stopped \ -v ${BASE_DIR}/${idx}/data:/data \ -v ${BASE_DIR}/${idx}/conf/redis.conf:/usr/local/etc/redis/redis.conf \ ${IMAGE} redis-server /usr/local/etc/redis/redis.conf }

逻辑说明:先建数据中心和配置目录,再强制删除可能残留的同名容器,保证脚本重复执行不会因为容器名冲突中断,最后用 docker run 启动。redis-server 后面跟的路径是容器内配置文件的绝对路径,脚本故意把它指定到 /usr/local/etc/redis/redis.conf,覆盖官方镜像的默认配置入口。

参数说明:--network host 是前面讲的网络方案;--restart unless-stopped 保证宿主机重启后容器自动拉起,这对集群自愈至关重要,少了这一项,机器重启后你还得来手动 docker start;三个挂载路径把配置和数据都落到宿主机磁盘,容器删了重建数据不丢。

这个函数被调用时,脚本会用下标遍历 IP_LIST 和 REDIS_PORT 两个数组,同时为每个实例生成对应的 redis.conf。生成动作放在 mkdir 之后、 docker run 之前,目的是确保每个容器拿到的配置实例专属,不会存在共享一份配置的情况。

3.2 集群初始化命令:redis-cli --cluster create 的参数含义

六个容器都起来后,脚本进入最关键一步:执行 cluster create。这一步负责把零散节点拉成集群,并完成槽位分配:

redis-cli --cluster create \ 192.168.1.20:6379 192.168.1.20:6380 \ 192.168.1.21:6379 192.168.1.21:6380 \ 192.168.1.22:6379 192.168.1.22:6380 \ --cluster-replicas 1 \ --cluster-yes

逻辑说明:redis-cli --cluster create 会把后面所有节点依次做 cluster meet,然后根据节点总数和副本数自动计算槽位划分。这里三对节点,每对都是同一台服务器的两个实例,跨服务器互为副本,主从不会落在同一台物理机上,这样任意一台服务器宕机,整集群仍有完整副本可用。

参数说明:--cluster-replicas 1 的意思是每个主节点分配 1 个从节点,三主三从一共六个实例;如果想做三主六从,就把这个值改成 2,同时把 IP_LIST 和 REDIS_PORT 扩充到九个。--cluster-yes 跳过槽位分配的交互确认。

槽位分配是自动完成的:16384 个 hash slot 被切成三段,分别给三个主节点,从节点不持有槽位。脚本没有手动执行 CLUSTER MEET,因为 create 子命令已经内置了这一动作,这也是它能压缩部署时间的关键。

3.3 等待端口就绪与重试逻辑

直接跑 create 有个常见问题:容器刚启动时 Redis 进程可能还没完成监听,这时候 create 会报连接失败。脚本里通常会加一段等待循环:

for i in "${!REDIS_PORT[@]}"; do node_ip=${IP_LIST[$((i/2))]} node_port=${REDIS_PORT[$i]} while ! nc -z ${node_ip} ${node_port}; do sleep 1 done done

逻辑说明:nc -z 检查 TCP 端口是否可连,连不上就每秒重试一次,直到所有端口都接受连接才继续。这比固定 sleep 5 可靠得多,因为容器拉镜像、加载 RDB / AOF 的耗时并不稳定,固定等待时间要么浪费要么不够。

参数说明:这里用了一个数组下标映射技巧,i/2 是整数除法,把 0 和 1 都映射到 IP_LIST[0],正好对应同一台服务器上的两个实例。如果你的资源配置是每台服务器三个实例,要把除数改成 3。

有些版本的脚本还会在等待完端口后补一个 PING 探测,确认 Redis 真正进入可服务状态。正常情况下,这段等待在全新环境里耗时很短。

4. 部署执行清单:改三个变量、跑一次脚本、用 cluster info 验收

4.1 修改脚本顶部变量:节点 IP 与端口规划

拿到脚本后第一个要动的地方是文件顶部的变量区。这一段的注释通常写得很直白,照着改就行:

# 按实际部署环境修改 IP_LIST=(192.168.1.20 192.168.1.21 192.168.1.22) REDIS_PORT=(6379 6380 6379 6380 6379 6380) BASE_DIR=/opt/redis-cluster IMAGE=redis:6.2

改动前先想清楚拓扑:三台服务器、每台两个实例,共六个节点,这是标准三主三从。IP_LIST 只写三台机器的 IP,但 REDIS_PORT 写六个端口,两个数组长度比是 1 比 2,脚本就是按这个比例把同 IP 的两个端口当成一对。

如果你要在一台机器上模拟整个集群,IP_LIST 就写成同一个 IP 重复三次,比如 192.168.1.20 写三遍,端口仍按六个数排。要注意生产环境不要这么干,主从落在同一台机器上,就等于没有高可用。

BASE_DIR 是集群数据在宿主机上的根目录,每个实例会在其下建立序号目录。IMAGE 字段建议固定一个具体版本,比如 redis:6.2,别用 latest,省得哪天拉到一个大版本镜像行为发生变化。

4.2 执行脚本:日志重定向与执行过程观察

环境变量改好后,执行方式建议加上日志重定向,尤其是首次部署:

cd /opt/redis-cluster bash redis-cluster-deploy.sh > deploy.log 2>&1 tail -f deploy.log

逻辑说明:脚本执行到 redis-cli --cluster create 时会自动处理交互确认,不需要你守在终端前敲 yes。把输出重定向到日志文件,一是防止终端会话断开导致输出丢失,二是后面排错时有完整过程可查。

观察重点有三个:第一,有没有出现 bind: address already in use;第二,六个容器是否全部进入 Up 状态;第三,日志末尾有没有 Cluster created 或类似标识。前两个对应端口占用和容器启动失败,第三个才是真正的成功标志。

常见做法是执行后等到脚本自然退出,再用下面的验证命令做多重确认。不建议在脚本还在等待端口的时候就另起一个终端去操作,可能会打断它的状态判断。

4.3 验收动作:cluster info 与 cluster nodes 的输出解读

脚本跑完后,必须用一个动作确认集群真的可用,我的习惯是连续看两个输出:

redis-cli -p 6379 cluster info redis-cli -p 6379 cluster nodes

第一个命令的输出里重点看这几行:

cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_known_nodes:6 cluster_size:3

cluster_state 是 ok 而不是 fail,说明槽位分配完成;cluster_slots_assigned 等于 16384 说明没有空槽;cluster_known_nodes 显示 6,和物理节点数对得上。

cluster nodes 的输出则是看主从关系和 fail 标记。正常情况下,每台服务器上各有一个 master 和一个 slave,master 的 flags 栏显示 master,slave 的 flags 栏显示 slave,而且主从不会出现在同一台物理机上。如果看到某个节点 flags 里有 fail 或 pfail,集群状态多半不是真健康,需要回到日志里找原因。

4.4 这份脚本没有替你做的三件事

脚本解决了初始化,但有三件事它默认不管,部署完要自己补。第一是节点内存上限:没配 maxmemory 的话,Redis 在极端写入下可能会把宿主机内存吃爆,建议按实例内存给 redis.conf 模板追加 maxmemory 配置。第二是监控:容器本身的 CPU、内存、磁盘指标不在脚本范围内,上了生产环境要靠外部监控去盯。第三是跨机房的网络隔离,脚本按一个局域网场景设计,跨机房抖动和延迟可能导致集群频繁判主节点下线。

另外提醒一句,不要手动编辑 nodes.conf 或 redis.conf 里的集群元数据,节点间的状态以集群学到的 gossip 信息为准,手动改文件只会造成状态不一致。

5. 避坑记录:六个最容易遇到又不写进 README 的问题

5.1 端口与网络相关的坑

现象一:脚本执行到 docker run 时报 bind: address already in use,容器没起来,脚本卡住。原因通常是端口规划时只看了数据端口,漏掉了前面提到的 bus 端口。比如 6379 的数据端口空闲,但 16379 被别的服务占用,容器照样起不来。解决方法是先用 ss -lntp 查看端口占用,再把 REDIS_PORT 整体平移或者避开 bus 端口冲突区间,移动端口后记得 redis.conf 里 cluster-announce-bus-port 要同步改成新端口加 10000。

现象二:集群创建成功,但 redis-cli --cluster check 或者 failover 时报连接失败,错误指向的 IP 是完全不可路由的地址。原因多半是 cluster-announce-ip 没改,配置文件里保留着模板里的示例 IP。在 host 网络模式下,gossip 消息会广播这个 announce 地址,写错的话其他节点拿着假地址来连,自然连不上。解决方式是把三台机器 redis.conf 里的 cluster-announce-ip 统一改成各服务器真实内网 IP,重新生成配置再执行一次脚本。注意只改一份配置没用,六份全要动。

现象三:跨服务器部署时,集群创建过程反复 timeout,同一台机器上的两个节点却能正常 meet。原因基本可以锁到防火墙:firewalld 没放行 bus 端口。数据端口保证了客户端连接,但节点间的 gossip 走的是数据端口加 10000 的通道,这个端口被 drop 后,节点之间收不到心跳,表现为超时和 unstable。解决方法是把规划好的所有数据端口和 bus 端口一次性放行,然后 firewall-cmd --reload。

现象四:客户端从应用服务器连接集群,连第一个节点能通,但从节点返回 MOVED 指令后,客户端转向的那个地址连不上。原因是集群广播的 announce-ip 与客户端所在网络的访问路径不一致,比如 announce-ip 配成了内网地址,客户端却在另一个网段。解决方法是根据客户端的实际网络位置来决定 announce-ip 写哪个地址,客户端和应用如何访问集群,announce-ip 就写哪个可通地址。

5.2 配置与操作方式的坑

现象五:宿主机重启后,docker ps 显示容器全部 Up,但 cluster info 变成 cluster_state:fail,槽位大量缺失。原因通常是数据目录没有真正挂载,或 appendonly 没开。docker run 没加 -v 的情况下,nodes.conf 写在容器可写层里,容器一旦被删除重建,槽位元数据全部归零。解决方法是确认每个容器都挂载了宿主机 data 目录,并且 redis.conf 里 appendonly yes 已生效。判断生效与否,进容器看 /data 下有没有 appendonly.aof 文件即可。

现象六:CentOS 7 的 SELinux 处于 enforcing 状态时,容器写挂载目录报 Permission denied。原因是宿主机目录的 SELinux 上下文不是容器可写类型。我惯用的处理方式是执行 chcon -Rt svirt_sandbox_file_t /opt/redis-cluster,把整个集群数据目录的上下文改成容器可访问类型。这比直接 setenforce 0 精确,不会把整台机器的安全策略关掉。测试机不在乎安全策略的话也可以临时 setenforce 0,但生产环境不建议这么做。

提示:以上坑点的共同根源,一半是端口没有系统规划,一半是 announce-ip 假设了错误的网络路径。部署前把这两点值画清楚,能少走大半弯路。

6. 进阶验证:主从切换演练与 cluster check 巡检技巧

6.1 主从自动切换演练

集群建好只是一句开始,真正验证它有没有用,要模拟主节点宕机一次。我的做法是挑一个 master 容器直接停掉,观察它对应的 slave 能不能自动变成 master:

docker stop redis-0 sleep 15 redis-cli -p 6380 cluster nodes | grep -E "master|fail"

原理说明:redis-0 被停止后,其他节点会在 cluster-node-timeout 时间内探测不到它的心跳,然后集群进入客观下线流程,它的从节点发起选举,过半后自动晋升为新主节点。15 秒的等待时间给足了 5000ms 超时和选举过程。

执行后看 cluster nodes 输出,如果原来的 slave 变成了 master,而且没有节点处于 fail 状态,说明集群的故障转移链路是通的。这时候再把停掉的容器启动:

docker start redis-0

它会以旧主的身份回到集群,但已经变成新主节点的从节点,数据会自动做全量同步。这个动作模拟了实际生产里最常遇到的整机掉电场景。

6.2 cluster check 巡检 baseline

日常巡检我建议用 redis-cli --cluster check,它一次性输出槽位完整性、节点健康状态、主从关系,比逐条拼 cluster nodes 方便:

redis-cli --cluster check 192.168.1.20:6379 --cluster-yes

这个命令会给出槽位覆盖、节点数量、每个 master 的 slot 分布、以及是否有 fail 标记。我的习惯是把第一次成功部署后的 check 结果存成 baseline.txt,之后的每次巡检都输出一份新结果 diff 一遍。哪一行多出来一个 fail,哪一行槽位数量对不上,一眼就看清。

从那以后,我每次用这套脚本部署完集群,都强制自己走一遍 docker stop 演练加 check baseline,折腾次数多了,比对正常输出的效率远高于单独排查节点状态。这也算是一套供同行直接使用的判断习惯,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询