etcd节点噶了导致的k8s集群瘫痪处理参考——筑梦之路
背景说明
etcd集群有3个节点,某天机房突然断电,导致etcd的1个节点数据丢失,etcd集群数据不一致,同样的命令在不同master节点上查询的结果不一样,存在脏数据。
问题根源
etcd作为K8s的“大脑”,负责存储所有集群配置、资源信息。一旦某个节点离线,轻则集群读写性能下降,重则触发“quorum机制”(半数以上节点存活才能正常工作),直接导致集群不可用。
因此,遇到节点故障,核心要做3件事:查状态→删故障节点→重新加入集群,最后再加上备份,防患于未然。
集群检查
1. 查询节点成员
# 默认配置
ETCD_ENDPOINTS="https://192.168.1.100:2379,192.168.1.101:2379,192.168.1.102:2379"
CA_CERT="/data/k8s/ssl/ca.pem"
ETCD_CERT="/data/k8s/ssl/etcd.pem"
ETCD_KEY="/data/k8s/ssl/etcd-key.pem"
ETCDCTL_PATH="/opt/kube/bin/etcdctl"# 以表格形式展示成员列表
ETCDCTL_API=3 "$ETCDCTL_PATH" -wtable \--cacert="$CA_CERT" \--cert="$ETCD_CERT" \--key="$ETCD_KEY" \--endpoints="$ETCD_ENDPOINTS" \member list# 需要注意查看节点ID
2. 查询健康状态
# 查询集群健康状态ETCDCTL_API=3 "$ETCDCTL_PATH" -wtable \--cacert="$CA_CERT" \--cert="$ETCD_CERT" \--key="$ETCD_KEY" \--endpoints="$ETCD_ENDPOINTS" \endpoint health# 检查集群节点状态ETCDCTL_API=3 "$ETCDCTL_PATH" -wtable \--cacert="$CA_CERT" \--cert="$ETCD_CERT" \--key="$ETCD_KEY" \--endpoints="$ETCD_ENDPOINTS" \endpoint status --cluster
如果显示“某个节点unhealthy”,数据大小差距比较大,就说明故障实锤,需要将故障节点的ID信息记录下来,后面处理会用到。
故障处理
思路:删故障节点+清旧数据,避免“脏数据”坑
故障节点不删掉,新节点加不进来,会一直占用集群资源。这里要注意:必须先从集群删除节点,再去故障机上清数据,顺序反了会出问题。
1. 从集群中删除故障节点
ETCDCTL_API=3 "$ETCDCTL_PATH" \--cacert="$CA_CERT" \--cert="$ETCD_CERT" \--key="$ETCD_KEY" \--endpoints="$ETCD_ENDPOINTS" \member remove [故障节点ID]
看到“Member xxx removed from cluster”就说明删成功了,再用member list确认,故障节点已经消失。
2. 清理故障节点的数据
登陆到故障节点的机器上停掉etcd服务,删除数据目录
systemctl stop etcdrm -rf /var/lib/etcd/*
3. 重新加入集群内
1)故障节点改启动参数:关键是“existing”
把ETCD_INITIAL_CLUSTER_STATE从“new”改成“existing”——因为集群已经存在,新节点是“加入”不是“新建”。
ETCD_INITIAL_CLUSTER_STATE="existing" # 重点!改成existing
2) 加节点+重启服务
在正常节点操作
ETCDCTL_API=3 "$ETCDCTL_PATH" \--cacert="$CA_CERT" \--cert="$ETCD_CERT" \--key="$ETCD_KEY" \--endpoints="$ETCD_ENDPOINTS" \member add [节点名称] --peer-urls=https://[节点IP]:2380
看到“Member xxx added to cluster”后,登录新加入节点重启服务
systemctl daemon-reload # 重新加载配置
systemctl restart etcd # 重启etcd
systemctl status etcd # 检查状态,确保是“active (running)”
3) 检查验证集群是否正常
此处主要检查节点成员、健康状态。
定期备份
#!/bin/bash
# etcd备份脚本
# 保留3天的备份# etcd节点信息,填写etcd的节点信息,一般为k8s集群master IP地址
etcd_hosts=(192.168.1.100 192.168.1.101 192.168.1.102)for i in ${etcd_hosts[@]}
doETCDCTL_API=3 /opt/kube/bin/etcdctl --cacert=/data/k8s/ssl/ca.pem --cert=/data/k8s/ssl/etcd.pem --key=/data/k8s/ssl/etcd-key.pem --endpoints="https://${i}:2379" snapshot save /data/backup-etcd/backup-etcd_${i}_`date +%F`.db
done# 清理
find /data/backup-etcd/ -name '*.db' -type f -mtime +3 -exec rm -rf {} \;
给这个脚本加上定时任务,定期对etcd集群节点进行备份,这样也能避免丢失数据导致集群崩溃。