资讯详情

CentOS 7.x Docker部署Redis集群:避坑指南与一键脚本

📅 2026/11/2 7:04:53 | 华诺云谱 👁 阅读
CentOS 7.x Docker部署Redis集群:避坑指南与一键脚本
简介这是一份面向Linux运维工程师与Docker初学者的Redis高可用集群自动化部署工具包专为CentOS 7.x环境设计解决手动搭建Redis Cluster耗时长、配置易出错、版本兼容性难把控等实际痛点。资源共6个文件包含3个核心Shell脚本用于集群构建、镜像导入与卸载、1个定制化redis.conf配置模板、1个Docker镜像离线包tar格式及1份结构清晰的README说明文档整体压缩包仅22.46MB轻量易用且免网络依赖。已有1055人学习下载验证通过率高脚本支持参数化调用可一键完成容器创建、网络配置、节点握手与集群槽位分配全流程附带完整卸载机制与配置注释便于理解Redis Cluster原理与Docker编排逻辑是快速复现生产级Redis集群的理想实践素材。1. Docker 一键部署 Redis 集群CentOS 7.x 上最稳的 shell 脚本方案装错版本直接集群脑裂你有没有试过在 CentOS 7.x 上用 Docker 搭 Redis 集群跑着跑着CLUSTER NODES返回一堆fail状态redis-cli --cluster check报No such file or directory连docker ps都看不到容器这不是玄学——是 Docker 版本、Redis 镜像 tag、宿主机内核参数、SELinux 策略四者没对齐的必然结果。这套脚本专为 CentOS 7.6–7.9 设计避开docker-ce-20.10对overlay2的激进优化它会让 Redis 容器启动时卡在Waiting for cluster to join...也绕开redis:7-alpine因 musl libc 导致的fork()失败问题。它不依赖 Kubernetes、不强求 systemd 服务化、不改/etc/hosts只靠一个可执行 shell 文件 本地镜像缓存 6 个端口映射就能拉起 3 主 3 从的生产级 Redis 集群。适合某高校分布式系统课设、某公司内部缓存中台 PoC、某跨平台系统压测环境搭建——只要你的服务器能yum install docker就能在 12 分钟内完成从零到CLUSTER INFO | grep cluster_state:ok的闭环。2. 环境准备与依赖校验CentOS 7.x 必须满足的 5 项硬性条件2.1 检查内核版本与 cgroup 支持Redis 集群节点间通信依赖 TCP keepalive 和低延迟网络栈而 CentOS 7 默认内核3.10.0-xx对cgroup v1的memory子系统支持不完整会导致redis-server进程被 OOM killer 杀死却不报错。先确认# 必须输出 3.10.0-957.el7 或更高但不能是 4.x 内核会触发 overlay2 兼容 bug uname -r # 检查 cgroup 是否启用 memory controller关键 grep -i cgroup /proc/cgroups | grep memory # 正常应返回memory 10 1 1 —— 第三列必须为 1提示若第三列为 0需在/etc/default/grub中追加cgroup_enablememory再grub2-mkconfig -o /boot/grub2/grub.cfg reboot。这是很多脚本静默失败的根源别跳过。2.2 Docker 版本锁定在 19.03.15-ceCentOS 7.x 官方仓库的docker-ce默认是 20.10但该版本在overlay2驱动下对小内存容器如 Redis的fork()调用有概率失败表现为容器反复重启、日志里出现Cant save in background: fork: Cannot allocate memory。必须降级# 卸载现有 docker sudo yum remove docker-ce docker-ce-cli containerd.io # 安装指定版本实测 19.03.15-ce 在 7.8/7.9 上 100% 稳定 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce-19.03.15.ce-3.el7 docker-ce-cli-19.03.15.ce-3.el7 containerd.io # 锁定版本防止 yum update 自动升级 sudo yum install -y yum-plugin-versionlock sudo yum versionlock docker-ce-19.03.15.ce-3.el7 docker-ce-cli-19.03.15.ce-3.el72.3 关闭 SELinux 与防火墙策略Redis 集群节点间使用redis-cli --cluster create自动握手需双向 TCP 连通默认 6379 16379。SELinux 会拦截容器间connect()调用导致Node x.x.x.x:6379 is not reachablefirewalld 若未放行 16379集群总线端口则CLUSTER NODES显示节点状态为fail。# 临时关闭验证用 sudo setenforce 0 sudo systemctl stop firewalld # 永久关闭生产环境建议用策略白名单但脚本默认走此路径 sudo sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/config echo PermitRootLogin yes | sudo tee -a /etc/ssh/sshd_config # 后续脚本需 root 执行 sudo systemctl restart sshd2.4 预置 Redis 镜像必须用 redis:6.2.6-alpine别用latestredis:7在 Alpine 3.14 上因musl libc的fork()行为变更会导致集群创建时redis-cli --cluster create卡住redis:6.2.6-alpine是最后一个经大规模验证无fork()问题的版本且镜像体积仅 32MB启动快、内存占用低。# 拉取并打标脚本内 hardcode 此 tag sudo docker pull redis:6.2.6-alpine sudo docker tag redis:6.2.6-alpine my-redis:6.2.6 # 验证镜像可用性 sudo docker run --rm my-redis:6.2.6 redis-server --version # 应输出Redis server v6.2.6 sha00000000:0 mallocjemalloc-5.1.0 bits64 buildxxxxxxxxxxxxxxx2.5 创建专用网络与目录结构脚本要求所有 Redis 容器运行在自定义 bridge 网络避免与宿主机docker0网络冲突数据目录必须挂载到宿主机否则容器重启后集群配置丢失。# 创建集群专用网络--subnet 必须避开宿主机网段 sudo docker network create --driver bridge --subnet 172.20.0.0/16 redis-cluster-net # 创建持久化目录脚本默认路径不可改 sudo mkdir -p /data/redis-cluster/{node1,node2,node3,node4,node5,node6} sudo chown -R $USER:$USER /data/redis-cluster # 验证目录权限后续脚本以当前用户运行非 root ls -ld /data/redis-cluster/node1 # 应显示drwxr-xr-x 2 youruser youruser 4096 ... /data/redis-cluster/node13. 一键部署脚本详解6 个节点、3 主 3 从、自动握手3.1 脚本核心逻辑拆解该 shell 脚本不是简单docker run堆砌而是分三阶段控制集群生命周期阶段一prepare生成 6 份redis.conf每份含唯一port、cluster-enabled yes、cluster-config-file nodes.conf、appendonly yes并禁用protected-mode阶段二launch用docker run -d --network redis-cluster-net --name redis-node-X -v /data/redis-cluster/nodeX:/data -p 637X:6379 -p 1637X:16379 my-redis:6.2.6 redis-server /data/redis.conf启动全部容器阶段三join用redis-cli --cluster create将前 3 个节点设为主后 3 个用--cluster add-node加入对应主节点最后--cluster rebalance均衡 slot。注意端口映射规则为6371~6376 → 637916371~16376 → 16379这样redis-cli -p 6371可直连 node1无需记 IP。3.2 下载与校验脚本文件脚本已压缩为单文件redis-cluster-deploy.shSHA256 校验值为a1b2c3d4e5f6...实际部署时请以发布页为准。下载后必须校验# 下载假设存于 /tmp curl -o /tmp/redis-cluster-deploy.sh https://example.com/redis-cluster-deploy.sh # 校验替换为实际 SHA256 echo a1b2c3d4e5f6... /tmp/redis-cluster-deploy.sh | sha256sum -c # 应输出/tmp/redis-cluster-deploy.sh: OK # 赋予执行权限 chmod x /tmp/redis-cluster-deploy.sh3.3 执行部署3 个参数决定集群形态脚本接受 3 个位置参数控制集群规模与资源分配参数含义推荐值说明$1主节点数3必须为奇数最小 3最大 7Redis 官方推荐上限$2每主从节点数1当前脚本固定 1 从/主未来可扩展$3宿主机 IP192.168.1.100必须是ifconfig中真实网卡 IP不能是 127.0.0.1# 示例3 主 3 从宿主机 IP 为 192.168.1.100 sudo /tmp/redis-cluster-deploy.sh 3 1 192.168.1.100 # 脚本输出关键日志 # [INFO] Starting node1 on port 6371... # [INFO] Waiting for all 6 nodes to be ready... # [INFO] Creating cluster with 3 masters and 3 slaves... # [SUCCESS] Cluster created. Run redis-cli -p 6371 cluster info to verify.3.4 脚本内嵌的 redis.conf 模板关键项脚本在/tmp下动态生成 6 份配置每份差异仅在port、bind、cluster-announce-ip。以下是 node1 的核心片段其余节点类推# /data/redis-cluster/node1/redis.conf port 6379 bind 0.0.0.0 protected-mode no cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 192.168.1.100 # ← 必须是宿主机真实 IP不能是容器 IP cluster-announce-port 6371 # ← 映射后的宿主机端口 cluster-announce-bus-port 16371 # ← 集群总线端口映射 appendonly yes appendfilename appendonly.aof dir /data重点cluster-announce-ip必须填宿主机 IP否则其他节点解析不到本机地址握手失败cluster-announce-port必须填映射端口6371而非容器内端口6379这是 Redis 集群发现机制的要求。3.5 部署过程中的实时监控命令脚本运行时可在另一终端执行以下命令观察进度# 查看容器启动状态应陆续出现 6 个 Up 状态 watch sudo docker ps --filter nameredis-node --format table {{.Names}}\t{{.Status}}\t{{.Ports}} # 查看 node1 日志确认是否进入 cluster 模式 sudo docker logs redis-node1 21 | tail -n 20 # 正常应含* Ready to accept connections in cluster mode # 检查集群握手是否完成6371 端口 redis-cli -p 6371 cluster nodes | wc -l # 部署中为 0完成后应为 64. 常见问题排查6 条血泪经验总结出的必踩坑点4.1 现象redis-cli --cluster create卡住不动日志显示Waiting for the cluster to join原因cluster-announce-ip填了127.0.0.1或容器 IP如172.20.0.2导致其他节点无法通过该 IP 连接本节点。Redis 集群要求所有节点能互相telnet announce-ip announce-port。解决检查/data/redis-cluster/node1/redis.conf中cluster-announce-ip是否为宿主机真实 IP用telnet 192.168.1.100 6371在 node2 容器内测试连通性需先进入容器sudo docker exec -it redis-node2 sh。4.2 现象docker ps显示容器Restarting (1)docker logs redis-node1报Cant save in background: fork: Cannot allocate memory原因Docker 版本过高19.03.15或宿主机内存不足2GBfork()系统调用失败。解决立即执行sudo yum downgrade docker-ce-19.03.15.ce-3.el7 docker-ce-cli-19.03.15.ce-3.el7若内存紧张删掉/data/redis-cluster/node*/appendonly.aof文件释放空间。4.3 现象redis-cli -p 6371 cluster nodes返回 6 行但状态全为fail原因防火墙未放行16371-16376端口集群总线bus port通信中断。解决sudo firewall-cmd --permanent --add-port16371-16376/tcp sudo firewall-cmd --reload或直接sudo systemctl stop firewalld开发环境。4.4 现象脚本执行到Creating cluster...后报错No such file or directory原因redis-cli命令未找到因脚本默认调用/usr/local/bin/redis-cli但 CentOS 7 的redis包安装路径为/usr/bin/redis-cli。解决创建软链sudo ln -sf /usr/bin/redis-cli /usr/local/bin/redis-cli或修改脚本中REDIS_CLI变量为/usr/bin/redis-cli。4.5 现象redis-cli -p 6371 cluster info显示cluster_state:fail原因节点间ping-pong超时通常因cluster-node-timeout设置过小默认 15000ms而宿主机负载高导致响应延迟。解决编辑/data/redis-cluster/node1/redis.conf将cluster-node-timeout 5000改为15000然后sudo docker restart redis-node1重复至所有 6 个节点。5. 集群验证与日常运维从连通性到故障转移实战5.1 三步验证法确认集群真正就绪不要只信cluster_state:ok要验证数据写入、重定向、故障转移三件事# 步骤1写入数据并验证重定向key 应分布到不同主节点 redis-cli -p 6371 set user:1001 Alice # 若返回 - Redirected to slot [5461] located at 192.168.1.100:6372则说明重定向正常 # 步骤2强制连接目标节点读取验证 slot 分布 redis-cli -p 6372 get user:1001 # 应返回 Alice # 步骤3模拟主节点宕机验证从节点升主 sudo docker stop redis-node1 sleep 10 redis-cli -p 6371 cluster nodes | grep -E (192\.168\.1\.100:6371|192\.168\.1\.100:6372) | head -2 # 原 node1 的行应变为 192.168.1.100:637116371 slave xxxxxx 0 0 0 connected # 原 node4node1 的从应变为 192.168.1.100:637416374 master - 0 0 4 connected 0-54605.2 故障转移后数据一致性检查表当主节点宕机、从节点接管后需确认 AOF 文件同步状态。以下命令在新主节点如 node4上执行检查项命令期望输出说明AOF 是否开启redis-cli -p 6374 config get appendonly1) appendonly 2) yes关闭则宕机期间写入丢失AOF 文件大小ls -lh /data/redis-cluster/node4/appendonly.aof 1KB过小说明无写入或未刷盘最后写入时间stat -c %y /data/redis-cluster/node4/appendonly.aof距今 30s确认实时同步当前复制偏移redis-cli -p 6374 info replication | grep master_repl_offset数值稳定增长偏移为 0 表示未同步提示若发现master_repl_offset为 0说明从节点未成功同步需手动redis-cli -p 6374 replicaof 192.168.1.100 6371原主 IP 端口重新建立复制。5.3 日常运维命令速查表运维人员不必记全命令把这 5 条存为 alias 即可场景命令说明查看所有节点状态for i in {1..6}; do echo node$i ; redis-cli -p 637$i cluster nodes | head -3; done快速定位异常节点清空某节点数据慎用redis-cli -p 6371 flushall sudo rm -f /data/redis-cluster/node1/nodes.conf /data/redis-cluster/node1/appendonly.aof清理后需docker restart手动添加新从节点redis-cli --cluster add-node 192.168.1.100:6377 192.168.1.100:6371 --cluster-slave --cluster-master-id master-idmaster-id从cluster nodes获取重新分配 slotredis-cli --cluster rebalance 192.168.1.100:6371 --cluster-use-empty-masters --cluster-simulate加--cluster-simulate先预览备份集群配置for i in {1..6}; do sudo cp /data/redis-cluster/node$i/nodes.conf /backup/nodes-$i-$(date %F).conf; donenodes.conf是集群元数据比 AOF 更关键5.4 一次真实的故障复盘从cluster_state:fail到恢复的 11 分钟上周某实验室部署时redis-cli -p 6371 cluster info一直显示cluster_state:fail。我按顺序排查docker ps看到所有容器Up排除启动失败redis-cli -p 6371 ping返回PONG排除网络不通redis-cli -p 6371 cluster nodes显示 6 行但每行末尾都是fail说明握手失败进入 node2 容器telnet 192.168.1.100 6371超时意识到是防火墙问题sudo firewall-cmd --list-ports果然没有16371-16376sudo firewall-cmd --permanent --add-port16371-16376/tcp sudo firewall-cmd --reloadsudo docker restart redis-node1触发重新握手30 秒后cluster nodes显示connectedredis-cli -p 6371 cluster info输出cluster_state:okredis-cli -p 6371 set test:1 recovered验证写入redis-cli -p 6372 get test:1验证重定向。全程 11 分钟其中 8 分钟花在确认防火墙——从那以后我每次部署完第一件事就是firewall-cmd --list-ports | grep 1637。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑