etcd 备份与恢复
集群中的 etcd 服务是一个分布式键值存储,负责存储集群配置信息。etcd 部署在集群所有控制平面节点上。
安装 Alauda Container Platform Cluster Enhancer 插件后,会自动为集群配置创建一个 EtcdBackupConfiguration 资源。EtcdBackupConfiguration 包含备份数据源(控制节点、备份路径)、备份数据存储位置、备份方式等信息。每次基于策略执行备份时都会生成新的备份记录,支持按需或定期自动备份集群配置。
前提条件
启用 etcd 备份:
- 从 Customer Portal 下载 Alauda Container Platform Cluster Enhancer。
- 上传安装包 至平台。
- 在集群上安装插件。
安装完成后,会自动创建 EtcdBackupConfiguration 资源。
工作原理
- etcd 备份由 Alauda Container Platform Cluster Enhancer 提供。
- 支持本地存储和兼容 S3 的对象存储。默认备份存储在本地
/cpaas。配置 S3 存储后,会在 S3 桶中额外生成一份备份,本地备份仍会继续生成。
- 对于运行在 Immutable OS 上的集群,必须使用 S3 存储(不支持本地存储)。
配置参考
您可以配置 EtcdBackupConfiguration 资源,自定义备份计划、保留策略和存储选项。
计划与保留
schedule:使用标准 cron 语法定义备份频率。
localStorage:配置本地备份存储。
path:主机上存储备份的目录,默认是 /cpaas。
ttl:备份文件的保留时长(秒),超过该时长的备份将自动删除。
paused:设置为 true 可暂时暂停自动备份,但不删除配置。
示例配置:
apiVersion: enhancement.cluster.alauda.io/v1
kind: EtcdBackupConfiguration
metadata:
name: etcd-backup-default
spec:
schedule: "0 0 * * *" # 每天 00:00 执行
paused: false # 启用备份
localStorage:
path: /cpaas-backup # 自定义备份路径
ttl: "7776000" # 保留 90 天
# ... 其他字段
查看备份记录
您可以通过平台 UI 或命令行查看 etcd 备份记录。
使用平台 UI
- 在左侧导航栏点击 运维中心 > 监控 > 仪表盘。
- 点击页面右上角的 切换。
- 点击 集群 → etcd 备份 查看备份记录。
使用 CLI
通过查看 EtcdBackupConfiguration 资源的 status 字段验证备份状态和历史:
kubectl get etcdbackupconfiguration etcd-backup-default -o yaml
输出中包含 status.records 列表,详细信息包括:
backupTimestamp:备份创建时间。
fileName:备份文件名(例如 snapshot-etcd-<date>-<time>-<ip>.tar)。
result:备份结果(例如 Success)。
S3 备份配置
启用 etcd 备份的 S3 存储,步骤如下:
前提条件
- 集群已安装 Alauda Container Platform Cluster Enhancer。
步骤 1:创建 S3 Secret
准备好 S3 访问凭证,在 cpaas-system 命名空间创建 Kubernetes secret:
export ACCESS_KEY="your-access-key"
export SECRET_KEY="your-secret-key"
kubectl create secret generic etcd-backup-s3-secret \
--from-literal=ACCESS_KEY="$ACCESS_KEY" \
--from-literal=SECRET_KEY="$SECRET_KEY" \
--dry-run=client -n cpaas-system -o yaml | kubectl apply -f -
步骤 2:配置 EtcdBackupConfiguration
修改 EtcdBackupConfiguration 资源,添加带有 S3 配置的 remoteStorage 字段:
spec:
remoteStorage:
s3:
endpoint: "your-s3-endpoint" # 例如:https://s3.bucket.com
region: "your-s3-region"
bucket: "your-s3-bucket"
dir: "your-s3-bucket-dir"
skipTLSVerify: false # 仅自签名证书时设置为 true
secretRef: etcd-backup-s3-secret
步骤 3:验证备份
触发手动 etcd 备份验证配置:
# 设置环境变量
token="your-platform-token"
platform_url="your-platform-url"
cluster_name="your-cluster-name"
# 触发备份
curl $platform_url/kubernetes/$cluster_name/apis/enhancement.cluster.alauda.io/v1/etcdbackupconfigurations/etcd-backup-default/exec \
-k -H "Authorization: Bearer $token"
备份完成后,确认 S3 桶中存在备份文件。
etcd 恢复
警告:
- 此操作为 etcd 集群灾难恢复,会覆盖现有数据。请确保已有有效备份快照后再执行。
- 恢复过程风险较大,如不确定操作,请联系技术支持。
- 恢复期间 Kubernetes API Server 将不可用。
前提条件
- Kubernetes 集群使用主机名部署(
kubectl get node 显示节点名为主机名)。
- 已有 etcd 备份快照。
- 集群因 etcd 节点故障导致异常(例如超过半数控制平面节点宕机)。
- 本恢复流程仅适用于 3 节点控制平面 集群。若控制平面节点数为 5 个及以上,请联系技术支持。
步骤 1:备份原始数据并修改 etcd 配置
在 所有控制平面节点 执行:
# 创建备份目录
mkdir -p /root/backup_$(date +%Y%m%d%H)/old-etcd/
# 停止 kubelet
systemctl stop kubelet
# 备份 etcdctl 二进制文件
cp $(find /var/lib/containerd/ -name etcdctl | tail -1) /root/etcdctl
# 删除 etcd 容器
crictl ps -a | grep etcd | awk '{print $1}' | xargs -r crictl rm -f
# 备份 etcd 数据和 kubernetes 配置
cp -a /var/lib/etcd/* /root/backup_$(date +%Y%m%d%H)/old-etcd/
rm -rf /var/lib/etcd/*
cp -r /etc/kubernetes/ /root/backup_$(date +%Y%m%d%H)/old-etcd/
# 修改 etcd.yaml 使用现有集群状态
sed -i /initial-cluster-state=/d /etc/kubernetes/manifests/etcd.yaml
sed -i '/initial-cluster=/a\ - --initial-cluster-state=existing' /etc/kubernetes/manifests/etcd.yaml
注意:请确认 /etc/kubernetes/manifests/etcd.yaml 中 --initial-cluster-state=existing 的缩进正确。
步骤 2:复制备份快照
将最新的 etcd 备份快照复制到 第一个控制平面节点 的 /tmp 目录,命名为 snapshot.db。
步骤 3:恢复 etcd
在 第一个控制平面节点 执行以下脚本恢复快照。
注意: 以下脚本假设为 3 节点控制平面集群。若节点数为 5 个及以上,请联系技术支持。
#!/usr/bin/env bash
# 设置 etcd 节点 IP(替换为实际 IP)
export ETCD_1=1.1.1.1
export ETCD_2=2.2.2.2
export ETCD_3=3.3.3.3
# 设置对应节点主机名(替换为实际主机名)
export ETCD_1_HOSTNAME=etcd-1
export ETCD_2_HOSTNAME=etcd-2
export ETCD_3_HOSTNAME=etcd-3
export ETCDCTL_API=3
# 循环处理 3 个节点,若节点数不同请调整 '1 2 3'
for n in 1 2 3; do
ip_var=ETCD_${n}
host_var=ETCD_${n}_HOSTNAME
ip=${!ip_var}
host=${!host_var}
echo "正在恢复节点:${host} (${ip})..."
rm -rf /tmp/etcd
/root/etcdctl snapshot restore /tmp/snapshot.db \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--skip-hash-check=true \
--data-dir=/tmp/etcd \
--name "${host}" \
--initial-cluster \
${ETCD_1_HOSTNAME}=https://${ETCD_1}:2380,\
${ETCD_2_HOSTNAME}=https://${ETCD_2}:2380,\
${ETCD_3_HOSTNAME}=https://${ETCD_3}:2380 \
--initial-advertise-peer-urls https://"${ip}":2380 && \
mv /tmp/etcd /root/etcd_"${host}"
echo "${host} 恢复完成,数据目录:/root/etcd_${host}"
done
脚本执行完成后,/root 目录下会生成三个 etcd_$host 目录。
步骤 4:分发恢复数据
-
将恢复后的数据目录传输到对应控制平面节点。使用 scp 或类似工具,将步骤 3 生成的目录 /root/etcd_<hostname> 从第一个节点复制到其他节点。
例如,传输到 etcd-2 和 etcd-3:
# 替换 <etcd-2-ip> 和 <etcd-3-ip> 为实际 IP
scp -r /root/etcd_etcd-2 root@<etcd-2-ip>:/root/
scp -r /root/etcd_etcd-3 root@<etcd-3-ip>:/root/
-
在 每个控制平面节点 将数据恢复到 etcd 数据目录 /var/lib/etcd。
# 在 etcd-1:
cp -r /root/etcd_etcd-1/member/* /var/lib/etcd/
# 在 etcd-2:
cp -r /root/etcd_etcd-2/member/* /var/lib/etcd/
# 在 etcd-3:
cp -r /root/etcd_etcd-3/member/* /var/lib/etcd/
步骤 5:重启集群组件
在 所有控制平面节点 执行:
# 删除 Kubernetes 控制平面容器
crictl ps -a | grep -E "kube-api|kube-sche|kube-contro" | awk '{print $1}' | xargs -r crictl rm -f
# 重启 kubelet
systemctl restart kubelet
步骤 6:验证恢复
-
检查 etcd 集群健康状况。可在任意 etcd Pod 内或主机上使用 etcdctl 执行:
# 主机上使用 etcdctl
export ETCDCTL_API=3
/root/etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=https://127.0.0.1:2379 \
endpoint health
-
检查 Kubernetes Pod 是否正常运行:
kubectl get po -n kube-system
-
在 所有节点(控制平面和工作节点)重启 kubelet,确保所有组件重新连接到恢复后的 etcd:
systemctl restart kubelet
配置管理
如需修改默认 etcd 备份配置,请联系技术支持获取详细配置选项及高级设置。