首页 新闻 会员 周边 捐助

redis 集群的一个 pod 无法启动

0
悬赏园豆:30 [已解决问题] 解决于 2025-08-24 06:28

在 kubernetes 集群上部署的 redis 集群,一共运行了6个 pod,有1个 pod 无法启动

redis-store-2                         0/1     CrashLoopBackOff   1131 (3m54s ago)   4d

错误日志如下

~# kubectl logs redis-store-2   
1:M 19 Aug 2025 00:39:57.234 # Unrecoverable error: corrupted cluster config file.

请问如何解决这个问题?

问题补充:

在 k8s 上部署 redis 集群时,nodes.conf 配置文件的内容为空,配置信息在 nodes.sh 文件中

这个宕机节点的 data 文件夹下比正常节点多了很多 temp-xxx.rdb 文件,还多了2个 temp-rewriteaof-xxx.aof 文件

redis 版本是 7.0.4

dudu的主页 dudu | 高人七级 | 园豆:24696
提问于:2025-08-19 08:48
< >
分享
最佳答案
0

第1步:从 redis 集群中移除处于 fail 状态的节点

  • 进入其中一个正常的 redis pod 并运行 redis-cli
kubectl exec -it redis-store-0 -- /bin/bash
redis-cli
  • 运行 cluster nodes 命令列出所有节点
  • 找到宕机节点的 id
5804611bc01610a1637d58fe1a7d7caae8a3a121 192.168.40.67:6379@16379 slave,fail - 1755947211706 0 0 connected
  • 根据 cluster nodes 命令列出的 ip,用 redis-cli 连接每个节点进行 forget 操作
redis-cli -c -h <ip>
cluster forget <node-id>

需要注意的是,这里在所有节点上进行 的 foget 操作总时间一定要控制在1分钟内,不然被移除的节点会重新出现,详见 github 上的 评论

一开始不知道这个时间限制,白折腾了一段时间,后来知道后,同时打开5个终端窗口(一共有5个节点),每个终端窗口都先用 redis-cli 连接上各个节点,并预先输入好 cluster forget <node-id> 命令,然后切换5个终端窗口,按5次回车,这样操作,1分钟内完成毫无压力

dudu | 高人七级 |园豆:24696 | 2025-08-23 22:26

第2步:准备全新的节点

这个 redis 集群是高可用集群,6个节点,3个master,3个slave,宕机的是一个 slave 节点,所以这个节点的数据不需要恢复

移走宕机节点对应 pod 所关联的 data 目录中的所有文件(相当于删除)并重新部署 pod(删除 pod 就会自动重新部署一个) ,data 目录中会自动生成下面的文件

appendonlydir  bak  dump.rdb  nodes.conf  nodes.sh
dudu | 园豆:24696 (高人七级) | 2025-08-23 22:34

第3步:尝试将新节点以 slave 角色加入集群(失败)

  • 先在正常节点上通过 cluster nodes 命令找出这个 slave 节点对应的 master 节点,拿到 node id 与 IP 地址
  • 在新节点上通过 cluster meet 命令将新节点加入集群
127.0.0.1:6379> cluster meet <master-ip> 6379
OK
  • meet 成功之后默认是 master 角色
  • 尝试通过 cluster replicas 命令改为 slave
127.0.0.1:6379> cluster replicas <master-id>
(empty array)

但命令的返回是空数组,尝试失败,新节点依然是 master

dudu | 园豆:24696 (高人七级) | 2025-08-23 22:45

第3步:换命令将新节点以 slave 角色加入集群(成功)

通过园子的这篇博文知道了需要通过 redis-cli --cluster add-node 添加新节点

  • 先在正常节点上通过 cluster nodes 命令找出缺少 slave 节点的 master 节点,拿到 node id
  • 通过下面的命令成功将新节点添加为 slave
redis-cli --cluster add-node 192.168.6.113:6379 192.168.39.122:6379 --cluster-slave --cluster-master-id 907fcd5c13324ea4716ba3c5541c19330a53f07c 

注:第1个 IP 192.168.6.113:6379 为新节点的 IP,第2个 IP 192.168.39.122:6379 为集群中已有节点 的 IP,这里用的是 slave 所关联的 master 的 IP

dudu | 园豆:24696 (高人七级) | 2025-08-24 06:19
其他回答(1)
0

从错误信息来看,Redis 集群的配置文件(通常是nodes.conf)已损坏,导致 Pod 无法启动并进入CrashLoopBackOff状态。以下是解决该问题的步骤:

  1. 定位损坏的配置文件
    Redis 集群的配置文件nodes.conf通常存储在数据目录中(由dir配置指定,默认是工作目录)。在 Kubernetes 环境中,该目录通常挂载了持久卷(PV)。
    可通过以下命令查看 Pod 的存储配置,确认数据卷挂载路径:
    bash
    kubectl describe pod redis-store-2 | grep -A 10 "Volumes:"
  2. 备份并删除损坏的配置文件
    需要删除损坏的nodes.conf,让 Redis 重新生成配置文件。
    方法 1:直接进入容器(如果能短暂启动)
    如果 Pod 能短暂运行(可在崩溃前快速执行):
    bash

尝试进入容器

kubectl exec -it redis-store-2 -- sh

进入数据目录(根据实际挂载路径调整)

cd /data

备份并删除损坏的配置文件

mv nodes.conf nodes.conf.corrupted
方法 2:通过节点访问持久卷
如果 Pod 完全无法进入,需登录到 Pod 所在的节点(需节点操作权限):
bash

查看Pod所在节点

kubectl get pod redis-store-2 -o wide

登录节点(替换为实际节点名)

ssh node-name

找到持久卷在节点上的挂载路径(根据PV类型,可能是hostPath/ceph等)

例如hostPath类型,假设路径为/var/lib/k8s/redis-store-2

cd /var/lib/k8s/redis-store-2

备份并删除配置文件

mv nodes.conf nodes.conf.corrupted
3. 重启 Pod
删除损坏的配置文件后,重启 Pod 让 Redis 重新生成配置:
bash
kubectl delete pod redis-store-2

StatefulSet会自动重建Pod

  1. 重新加入集群(如果需要)
    如果是 Redis 集群的一部分,重建后的节点可能需要重新加入集群:
    bash

进入集群中正常的节点

kubectl exec -it redis-store-0 -- redis-cli

查看集群状态

cluster nodes

将新节点加入集群(替换为实际IP和端口)

cluster meet <redis-store-2-ip> 6379

分配槽位(如果是新节点)

cluster addslots ...

  1. 检查存储健康状态
    配置文件损坏可能是存储问题导致(如磁盘错误、权限不足):
    检查持久卷(PV)是否正常挂载:kubectl describe pv <pv-name>
    确认数据目录权限(Redis 进程是否有读写权限):ls -ld /data
    检查节点磁盘健康状态(如df -h、dmesg | grep error)
    完成以上步骤后,Redis 节点应能正常启动。如果问题反复出现,建议检查 Redis 版本兼容性或考虑备份数据后重建集群。
收获园豆:30
华哥来也 | 园豆:266 (菜鸟二级) | 2025-08-19 09:19

请问是哪家 AI 回答的?

支持(0) 反对(0) dudu | 园豆:24696 (高人七级) | 2025-08-19 09:26

@dudu: 豆包,哈哈哈~

支持(0) 反对(0) 华哥来也 | 园豆:266 (菜鸟二级) | 2025-08-19 09:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册