news 2026/10/28 19:48:00

CentOS 7.x 上用 Docker 一键部署 Redis 三主三从集群实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS 7.x 上用 Docker 一键部署 Redis 三主三从集群实战

简介:面向需要在 CentOS 7.x 环境下快速搭建 Redis 集群的运维与开发人员,这份资源提供了一套基于 Docker 的一键部署方案,通过 shell 脚本把镜像导入、容器编排与配置生成等环节串联起来,减少手工逐台配置的重复劳动,适合具备一定 Linux 基础、希望快速验证集群可用性的读者。压缩包共 6 个文件,约 22.46MB,以 sh 脚本为主体,配合 tar 镜像包、conf 配置文件和 md 说明文档,分别承担自动化部署、离线镜像分发、参数配置与使用指引等职责,按说明传入参数即可自动执行部署流程。目前已有 1055 人学习下载,脚本经过实际环境验证,可帮助读者省去镜像拉取与节点编排的摸索成本,并借助卸载脚本与说明文档完成环境清理和参数调整,适合作为学习 Docker 化 Redis 集群部署的参考实践。

1. 一条脚本起六节点:CentOS 7.x 上用 Docker 部署 Redis 集群的安装现场

上周帮同事恢复一套测试环境,机器是 CentOS 7.9,磁盘上还留着上次装到一半的 Redis 集群残骸:六个容器起了三个,redis-cli --cluster create卡在Waiting for the cluster to join,日志里全是Cluster config file exists。这种半死不活的状态比全新安装更难受,因为端口占用、配置文件、数据目录三样东西互相纠缠,清理比重装还费时间。Redis 集群本身不算复杂,难的是在 CentOS 7.x 这种老底子上把 Docker、网络、端口、集群总线一次配对,任何一环没对齐,cluster_state就永远是fail。这篇记录的是我用 shell 脚本一键拉起三主三从 Redis 集群的完整过程,适合手上只有一台 CentOS 7.x 测试机、想快速得到一套可验证集群的开发者,也适合已经装过单机 Redis、第一次碰集群模式、被CLUSTERDOWN折腾过的人。脚本不是黑匣子,下面会把每个参数为什么这么写讲清楚,装坏了也有回退路径。

2. 装前把环境钉死:CentOS 7.x 与 Docker 的版本取舍

2.1 系统底子与 Docker 版本怎么选

CentOS 7.x 的生命周期已经走到尾声,但大量内网测试机还在跑,所以第一件事不是敲安装命令,而是确认内核和 Docker 版本能对上。Redis 集群依赖容器间的 TCP 通信和固定的集群总线端口,Docker 版本太老会出现端口映射不稳定的情况。我一般要求内核不低于 3.10.0-1127,Docker 用 20.10 系列,这个组合在 CentOS 7.9 上验证过多次,docker network和--net host的行为都可预期。

# 确认系统版本与内核,低于 3.10.0-1127 建议先 yum update cat /etc/centos-release uname -r # 查看是否已有 docker,避免和旧版本冲突 docker version 2>/dev/null || echo "docker not installed" rpm -qa | grep -i docker

第一段命令看的是系统身份,/etc/centos-release输出CentOS Linux release 7.9.2009 (Core)这类信息才算对路。第二段是排雷,很多机器上残留着docker-ce旧包或者podman的兼容层,直接装新版本会出现二进制路径打架。如果rpm -qa里有docker-common、docker-client这类老包,先卸干净再往下走,这一步省不得。

版本选择上有个取舍:Docker 20.10 之后的版本对iptables后端有调整,CentOS 7.x 默认的firewalld和它配合时偶尔会吞掉容器端口。我的做法是安装时明确指定--setopt=obsoletes=0,并且装完立刻把firewalld停掉换成iptables管理,测试环境这样最省心。生产环境要保留防火墙的话,得手动放行 6379 和 16379 两个端口段,后面避坑章节会细说。

2.2 安装 Docker 与基础依赖

CentOS 7.x 的默认源里没有docker-ce,需要先加官方仓库。这一步网络不通是常态,所以脚本里我会把仓库地址写成可替换变量,方便换成内网镜像源。

# 安装基础工具,yum-utils 提供 yum-config-manager yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加 docker-ce 仓库,地址可按内网情况替换 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装指定版本,20.10.24 在 7.x 上比较稳 yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io # 启动并设开机自启 systemctl enable docker && systemctl start docker

device-mapper-persistent-data和lvm2是存储驱动的前置依赖,缺了它们 Docker 启动时会报devicemapper相关错误。yum-config-manager --add-repo写入的是仓库描述文件,如果公司内网有镜像站,把 URL 换掉即可,后面的包名不变。指定20.10.24而不是latest,是为了让脚本在别的机器上复现时行为一致,latest哪天跳到 24.x,iptables规则和 cgroup 驱动都可能变,集群端口映射就容易出玄学问题。

装完用docker info看两处:Cgroup Driver应该是systemd,Storage Driver在 CentOS 7.x 上通常是overlay2。如果显示devicemapper,说明内核或存储配置没跟上,得在/etc/docker/daemon.json里显式指定,否则后面容器写数据会慢得离谱。

2.3 目录规划与脚本参数约定

一键脚本要能重复执行,前提是目录和端口有固定约定。我习惯把集群根目录放在/opt/redis-cluster,下面按节点编号分7001到7006六个子目录,每个目录里放redis.conf和data。端口规划是三主三从交叉分布:7001、7002、7003 为主,7004、7005、7006 为从,集群总线端口统一用「服务端口 + 10000」,也就是 17001 到 17006。

# 脚本头部变量,改这里就能适配不同机器 CLUSTER_DIR=/opt/redis-cluster BASE_PORT=7001 NODE_COUNT=6 REDIS_IMAGE=redis:6.2.14 NETWORK_NAME=redis-cluster-net

REDIS_IMAGE选6.2.14是权衡后的结果:Redis 7.x 的集群命令有变化,--cluster create的部分输出格式和老脚本对不上;6.2 系列在 CentOS 7.x 的 Docker 上跑得最稳,镜像体积也适中。NETWORK_NAME用自定义 bridge 网络而不是host模式,是为了让六个容器通过容器名互相解析,脚本里就不用写死宿主机 IP,换机器时只改变量不改逻辑。这些约定写进脚本开头,后面所有循环都引用它们,改端口只改一个地方。

3. 写一键脚本:从生成配置到拉起六个容器

3.1 用循环生成六份 redis.conf

集群模式下的redis.conf和单机版差别不小,cluster-enabled yes、cluster-config-file、cluster-node-timeout三个是必填项,少一个容器起来就退。脚本里用循环按节点编号生成配置,端口和目录都从变量推导,避免手写六遍出错。

for i in $(seq 0 $((NODE_COUNT-1))); do PORT=$((BASE_PORT+i)) NODE_DIR="${CLUSTER_DIR}/${PORT}" mkdir -p "${NODE_DIR}/data" cat > "${NODE_DIR}/redis.conf" <<EOF port ${PORT} bind 0.0.0.0 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes dir /data EOF done

port和目录由BASE_PORT加偏移算出,六个节点一次成型。bind 0.0.0.0配合protected-mode no是容器内访问的必要条件,否则集群总线握手会被拒。cluster-config-file nodes.conf是每个节点自己的集群状态文件,必须落在持久化目录里,容器重启后才能恢复节点身份。cluster-node-timeout 5000表示 5 秒内主节点失联就触发故障转移,测试环境这个值够用,调太小会误判,调太大故障转移慢。appendonly yes打开 AOF,集群模式下数据安全性比纯 RDB 好一些,代价是磁盘写入多一点。

配置生成后建议抽查一份,确认端口和目录对得上。脚本里可以加一句grep -H "^port" ${CLUSTER_DIR}/*/redis.conf,输出六行端口号,肉眼扫一遍比事后排查省事。

3.2 创建网络并启动容器

六个容器要能互相通信,先建一个自定义 bridge 网络。启动时把配置目录和数据目录都挂进去,容器内路径固定为/usr/local/etc/redis/redis.conf和/data,这样镜像不用改,配置全在宿主机上。

# 创建专用网络,已存在则忽略报错 docker network create ${NETWORK_NAME} 2>/dev/null || true for i in $(seq 0 $((NODE_COUNT-1))); do PORT=$((BASE_PORT+i)) NODE_DIR="${CLUSTER_DIR}/${PORT}" docker run -d \ --name "redis-${PORT}" \ --network ${NETWORK_NAME} \ -p ${PORT}:${PORT} \ -p $((PORT+10000)):$((PORT+10000)) \ -v "${NODE_DIR}/redis.conf:/usr/local/etc/redis/redis.conf" \ -v "${NODE_DIR}/data:/data" \ ${REDIS_IMAGE} \ redis-server /usr/local/etc/redis/redis.conf done

--network让六个容器处于同一网段,容器名即主机名,后面组集群时可以直接用redis-7001:7001这种地址。两个-p分别映射服务端口和集群总线端口,后者是集群节点交换 gossip 消息用的,漏掉它cluster meet会一直超时。两个-v把配置和数据都落到宿主机,容器删了数据还在,这是能反复折腾的前提。启动命令末尾显式指定配置文件路径,覆盖镜像默认的启动参数。

启动后别急着组集群,先确认六个容器都处于Up状态,并且日志里没有FATAL。docker ps --filter "name=redis-"看状态,docker logs redis-7001看启动日志,正常会输出Ready to accept connections。有一个容器反复重启,多半是配置文件路径或权限问题,先解决再往下。

3.3 用 redis-cli 组集群并分配槽位

六个节点都活着之后,进任意一个容器执行--cluster create,Redis 会自动把 16384 个槽位平均分给三个主节点,并把另外三个设为从。这一步的关键是--cluster-replicas 1,它告诉工具每个主节点配一个从。

docker exec -it redis-7001 redis-cli --cluster create \ redis-7001:7001 redis-7002:7002 redis-7003:7003 \ redis-7004:7004 redis-7005:7005 redis-7006:7006 \ --cluster-replicas 1 --cluster-yes

地址列表前三个会被优先选为主节点,后三个作为从节点候选,--cluster-replicas 1保证一主一从的配比。--cluster-yes跳过交互确认,适合脚本化执行,手工执行时去掉它可以看到槽位分配预览。命令输出里会打印>>> Performing hash slots allocation on 6 nodes...,接着是每个节点的槽位区间,最后出现[OK] All 16384 slots covered才算成功。

如果卡在Waiting for the cluster to join,先别重复执行,去看容器日志里的总线端口有没有报连接拒绝。常见原因是宿主机防火墙拦了 17001 到 17006,或者容器网络里节点名解析不到。组集群失败后残留的nodes.conf会让下次执行报Node ... is not empty,清理方法是停容器、删各节点data目录下的nodes.conf、再重启,这个顺序不能反。

4. 避坑与排查:五个让集群起不来的真实原因

4.1 现象:容器全 Up,cluster_state 却是 fail

原因通常是集群总线端口没通。docker ps里只看到 7001 到 7006 的映射,17001 到 17006 被漏掉,节点之间 gossip 握手失败,槽位分配完了但状态同步不上。解决是把总线端口补进docker run的-p参数,重建容器后重新组集群。验证方法是docker exec redis-7001 redis-cli -p 7001 cluster info,看cluster_state:ok和cluster_known_nodes:6两个值。

4.2 现象:组集群时报 Node is not empty

这是重复执行留下的后遗症。上一次--cluster create中途失败,各节点的nodes.conf里已经写了半套集群视图,再次执行时工具发现节点非空就拒绝。解决分三步:docker stop六个容器,删除每个节点data目录下的nodes.conf和appendonly.aof,再docker start重启,最后重新执行组集群命令。顺序反了会读到旧状态,等于白删。

4.3 现象:宿主机能连,别的机器连不上

CentOS 7.x 上firewalld默认开着,Docker 的端口映射规则和它冲突时,外部访问会被静默丢弃。解决是测试环境直接systemctl stop firewalld && systemctl disable firewalld,生产环境则用firewall-cmd --add-port=7001-7006/tcp --permanent和--add-port=17001-17006/tcp --permanent显式放行,再firewall-cmd --reload。放行后从另一台机器用redis-cli -h <宿主机IP> -p 7001 cluster info验证,能返回cluster_state:ok才算通。

4.4 现象:容器启动即退出,日志报 Can't open the cluster config file

配置文件里cluster-config-file写的是相对路径,而dir指向的/data挂载目录权限不对,Redis 进程写不进去。解决是确认宿主机上${NODE_DIR}/data对容器内用户可写,简单做法是chmod 777测试目录,或者chown 999:999对齐 Redis 镜像里的用户 ID。另外cluster-config-file保持nodes.conf这种相对名即可,它会落在dir指定的目录下,不要写成绝对路径。

4.5 现象:主节点挂了,从节点没顶上

先看cluster-node-timeout是不是设得太大,5000 毫秒在测试环境合适,设成 60000 就要等一分钟才触发转移。再看从节点是否真的挂到了主节点上,redis-cli -p 7001 cluster nodes输出里每行末尾的connected状态和master指向要对应。如果从节点显示disconnected,多半是总线端口或网络问题,回到 4.1 排查。故障转移验证可以手动docker stop redis-7001,等几秒再看cluster nodes,原从节点会变成master并接管槽位。

5. 装完怎么验证:三组命令确认集群真的能读写

集群组起来不等于能用,我习惯用三组命令做验收,顺序是从状态到路由再到实际读写。第一组看整体状态,进任意节点执行cluster info,重点盯三个字段:cluster_state必须是ok,cluster_slots_assigned必须是16384,cluster_known_nodes必须是6。任何一个不对,说明槽位或节点注册有问题,别急着写数据。

# 状态验收:三个关键字段 docker exec redis-7001 redis-cli -p 7001 cluster info | grep -E "cluster_state|cluster_slots_assigned|cluster_known_nodes" # 节点拓扑:确认三主三从和槽位区间 docker exec redis-7001 redis-cli -p 7001 cluster nodes

第二组看拓扑,cluster nodes每行是一个节点,第一列是节点 ID,第二列是地址,第三列带master或slave,末尾的槽位区间应该覆盖 0 到 16383 且不重叠。三主三从的典型输出里,三个master各带一段槽位,三个slave的地址列后面跟着connected。如果某个从节点的master指向空或者状态不是connected,说明复制链路没建好。

第三组做真实读写,用-c参数让客户端跟随重定向。集群模式下不带-c写一个落在别的槽位的 key 会报MOVED,这是正常行为,不是故障。

# 写入并读取,-c 表示跟随 MOVED 重定向 docker exec redis-7001 redis-cli -c -p 7001 set cluster:test "ok" docker exec redis-7001 redis-cli -c -p 7001 get cluster:test # 查看 key 落在哪个槽位和节点 docker exec redis-7001 redis-cli -c -p 7001 cluster keyslot cluster:test

set返回OK、get返回ok,说明路由和读写都通。cluster keyslot会给出一个 0 到 16383 的数字,对照cluster nodes的槽位区间就能知道这个 key 归哪个主节点管。想再稳一点,可以连续写十个不同前缀的 key,再逐个读回,确认跨节点重定向没有丢数据。

验收通过后,把这套脚本和目录结构留一份在/opt/redis-cluster旁边,下次换机器直接改BASE_PORT和REDIS_IMAGE两个变量就能复用。我踩过最冤的一次是组集群前没清nodes.conf,反复执行了四遍,每遍都以为网络有问题,最后发现是旧状态在作祟。从那以后我每次重装集群都强制先跑一遍清理:停容器、删nodes.conf、再启动,三步走完才碰--cluster create。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 19:47:44

PHP门户系统部署与二次开发实战:环境、模板、插件与多端接口

1. 门户系统的骨架&#xff1a;先判断这套 PHP 程序值不值得投入1.1 门户系统和普通建站程序到底差在哪很多人第一次接触门户系统&#xff0c;会拿它和博客程序、企业站程序对比&#xff0c;结论往往是"功能太多、太重"。这个判断其实跑偏了。门户系统的设计目标是多…

作者头像 李华
网站建设 2026/10/28 19:47:40

Wolfram U AI课程:符号计算与可视化学习实践

1. Wolfram U AI初学者指南核心价值解析作为Wolfram Research推出的官方学习平台&#xff0c;Wolfram U的AI初学者系列课程在STEM教育领域具有独特优势。这套教程最显著的特点是依托Wolfram语言这一符号计算系统&#xff0c;将抽象的AI概念转化为可交互的数学表达。与常规Pytho…

作者头像 李华
网站建设 2026/10/28 19:46:04

Seq2Seq模型与注意力机制:原理、实现与优化

1. Seq2Seq模型基础解析Seq2Seq&#xff08;Sequence to Sequence&#xff09;模型是深度学习领域处理序列转换任务的经典架构&#xff0c;由Google在2014年首次提出。它的核心思想是将一个序列&#xff08;如句子&#xff09;转换为另一个序列&#xff08;如翻译结果&#xff…

作者头像 李华
网站建设 2026/10/28 19:44:59

批处理索引技术:原理、优化与实战应用

1. 批处理索引技术概述批处理索引是一种高效的数据处理技术&#xff0c;它通过批量操作而非单条记录处理来提升数据库系统的性能。在实际开发中&#xff0c;我们经常会遇到需要同时处理大量数据索引的场景&#xff0c;比如日志分析、报表生成、数据迁移等。传统的一条条记录处理…

作者头像 李华
网站建设 2026/10/28 19:44:54

虚拟机安装与配置全攻略:从场景选型到性能调优的实战指南

虚拟机安装这件事&#xff0c;说简单也简单&#xff0c;说坑多也是真多。我从十几年前第一次在旧笔记本上折腾虚拟机开始&#xff0c;到后来在团队里给新人做环境搭建培训&#xff0c;再到帮朋友处理各种"装完起不来""网络不通""性能像蜗牛"的疑…

作者头像 李华
网站建设 2026/10/28 19:44:39

NIST-800-190容器安全落地指南:从镜像到TPM的工程化实践

简介&#xff1a;本资源是NIST官方发布的《应用容器安全指南》&#xff08;SP 800-190&#xff09;中文翻译版PDF&#xff0c;面向系统与安全管理员、DevSecOps工程师、容器平台运维人员及具备基础虚拟化与网络安全知识的开发人员&#xff0c;聚焦容器技术在生产环境中面临的核…

作者头像 李华