Kubernetes 备份与灾难恢复指南
本文介绍 K3s 集群的备份与恢复策略,包括 etcd 快照、应用数据备份以及集群灾难恢复方法。
概述
在生产环境中运行 Kubernetes 集群时,制定完善的备份与恢复策略至关重要。本文将详细介绍 K3s 集群的备份方法,包括 etcd 数据备份、应用配置备份以及完整的灾难恢复流程。
备份策略规划
需要备份的内容
| 类型 | 内容 | 备份频率 |
|---|---|---|
| 集群状态 | etcd 数据 | 每小时 |
| 应用配置 | YAML 文件、Secrets | 每次变更 |
| 持久化数据 | PVC 数据 | 每日 |
| 证书 | TLS 证书、Token | 每月 |
备份工具选择
- K3s 内置:etcd 快照功能
- Velero:全面的集群备份方案
- 脚本工具:自定义备份脚本
etcd 数据备份
使用 K3s 内置快照
K3s 使用嵌入式 etcd 时,提供了便捷的快照功能:
# 手动触发快照
k3s etcd-snapshot save
# 查看快照列表
ls -la /var/lib/rancher/k3s/server/db/snapshots/
# 输出示例
on-demand-ip-172-31-3-36-1688025329
自动快照配置
# 配置定时快照(通过 cron)
crontab -e
# 每小时执行一次快照
0 * * * * /usr/local/bin/k3s etcd-snapshot save
# 保留最近 7 天的快照
0 0 * * * find /var/lib/rancher/k3s/server/db/snapshots/ -name "*.etcd" -mtime +7 -delete
快照文件位置
/var/lib/rancher/k3s/server/db/snapshots/
├── on-demand-k8s-server-01-1720245075
└── etcd-snapshot-2024-01-06T10:00:00Z
灾难恢复
基于内嵌 etcd 恢复
当集群出现严重故障时,可以通过快照恢复:
# 1. 停止 K3s 服务
systemctl stop k3s
# 2. 使用快照恢复
k3s server \
--cluster-reset \
--cluster-reset-restore-path=/var/lib/rancher/k3s/server/db/snapshots/on-demand-k8s-server-01-1720245075
# 3. 等待恢复完成,然后正常启动
systemctl start k3s
其他 Server 节点恢复
在主节点恢复后,其他 Server 节点需要清理 etcd 数据后重新加入:
# 在其他 Server 节点执行
systemctl stop k3s
rm -rf /var/lib/rancher/k3s/server/db/
# 重新启动,会自动从主节点同步数据
systemctl start k3s
全量备份脚本
备份脚本
#!/bin/bash
# k3s_backup.sh
BACKUP_DIR="/backup/k3s/$(date +%Y%m%d)"
K3S_DATA_DIR="/var/lib/rancher/k3s"
RETENTION_DAYS=7
mkdir -p "${BACKUP_DIR}"
# 1. 备份 etcd 快照
echo "[INFO] Creating etcd snapshot..."
k3s etcd-snapshot save
cp ${K3S_DATA_DIR}/server/db/snapshots/* "${BACKUP_DIR}/"
# 2. 备份集群配置
echo "[INFO] Backing up cluster configurations..."
kubectl get all --all-namespaces -o yaml > "${BACKUP_DIR}/cluster-resources.yaml"
kubectl get configmap --all-namespaces -o yaml > "${BACKUP_DIR}/configmaps.yaml"
kubectl get secret --all-namespaces -o yaml > "${BACKUP_DIR}/secrets.yaml"
kubectl get ingress --all-namespaces -o yaml > "${BACKUP_DIR}/ingresses.yaml"
kubectl get pvc --all-namespaces -o yaml > "${BACKUP_DIR}/pvcs.yaml"
# 3. 备份 K3s 配置
echo "[INFO] Backing up K3s configurations..."
cp -r /etc/rancher/k3s "${BACKUP_DIR}/k3s-config"
cp ${K3S_DATA_DIR}/server/token "${BACKUP_DIR}/" 2>/dev/null || true
cp ${K3S_DATA_DIR}/server/node-token "${BACKUP_DIR}/" 2>/dev/null || true
# 4. 压缩备份
echo "[INFO] Compressing backup..."
tar -czf "${BACKUP_DIR}.tar.gz" -C "${BACKUP_DIR%/*}" "$(basename ${BACKUP_DIR})"
rm -rf "${BACKUP_DIR}"
# 5. 清理旧备份
echo "[INFO] Cleaning up old backups..."
find /backup/k3s -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete
echo "[INFO] Backup completed: ${BACKUP_DIR}.tar.gz"
恢复脚本
#!/bin/bash
# k3s_restore.sh
BACKUP_FILE="$1"
K3S_DATA_DIR="/var/lib/rancher/k3s"
if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup-file.tar.gz>"
exit 1
fi
# 1. 停止 K3s
systemctl stop k3s
# 2. 备份当前数据(可选)
if [ -d "${K3S_DATA_DIR}" ]; then
mv ${K3S_DATA_DIR} ${K3S_DATA_DIR}.bak.$(date +%Y%m%d%H%M%S)
fi
# 3. 解压备份
mkdir -p ${K3S_DATA_DIR}
tar -xzf "${BACKUP_FILE}" -C /tmp
BACKUP_DIR="/tmp/$(basename ${BACKUP_FILE%.tar.gz})"
# 4. 恢复 etcd 数据
mkdir -p ${K3S_DATA_DIR}/server/db
if [ -d "${BACKUP_DIR}/snapshots" ]; then
cp ${BACKUP_DIR}/snapshots/* ${K3S_DATA_DIR}/server/db/snapshots/
k3s server --cluster-reset \
--cluster-reset-restore-path=$(ls -t ${K3S_DATA_DIR}/server/db/snapshots/ | head -1)
fi
# 5. 恢复配置
cp -r ${BACKUP_DIR}/k3s-config/* /etc/rancher/k3s/
# 6. 启动 K3s
systemctl start k3s
echo "[INFO] Restore completed"
应用数据备份
PVC 数据备份
使用 Velero
# 安装 Velero CLI
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
tar -xzf velero-v1.12.0-linux-amd64.tar.gz
mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
# 安装 Velero Server(使用 MinIO 作为后端)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket k8s-backup \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle=true,s3Url=http://minio.example.com:9000
创建备份
# 备份整个集群
velero backup create full-backup-$(date +%Y%m%d)
# 备份指定命名空间
velero backup create nginx-backup --include-namespaces nginx
# 备份包含 PVC
velero backup create app-backup \
--include-namespaces app \
--snapshot-volumes \
--volume-snapshot-locations aws
恢复备份
# 查看备份列表
velero backup get
# 恢复备份
velero restore create --from-backup full-backup-20240106
# 恢复到指定命名空间
velero restore create --from-backup app-backup --namespace-mappings app:app-new
数据库备份示例
MySQL 备份
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-backup
spec:
schedule: "0 2 * * *" # 每天凌晨 2 点
jobTemplate:
spec:
template:
spec:
containers:
- name: mysql-backup
image: mysql:8.0
command:
- /bin/sh
- -c
- |
mysqldump -h mysql-service -u root -p${MYSQL_ROOT_PASSWORD} \
--all-databases > /backup/mysql-$(date +%Y%m%d).sql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeMounts:
- name: backup-volume
mountPath: /backup
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: backup-pvc
restartPolicy: OnFailure
证书备份
备份证书和 Token
# 备份 Server Token
cp /var/lib/rancher/k3s/server/token /backup/
# 备份 Node Token
cp /var/lib/rancher/k3s/server/node-token /backup/
# 备份 TLS 证书
tar -czf /backup/k3s-certs-$(date +%Y%m%d).tar.gz \
/var/lib/rancher/k3s/server/tls/
轮换证书
K3s 客户端和服务器证书有效期为 365 天,到期前会自动轮换:
# 手动轮换证书
systemctl stop k3s
k3s certificate rotate
systemctl start k3s
# 轮换完成后验证
kubectl get nodes
异地备份策略
使用 rsync 同步到远程服务器
#!/bin/bash
# remote_backup.sh
LOCAL_BACKUP_DIR="/backup/k3s"
REMOTE_SERVER="backup@backup-server.example.com"
REMOTE_DIR="/backup/k8s-cluster"
# 同步到远程服务器
rsync -avz --delete ${LOCAL_BACKUP_DIR}/ ${REMOTE_SERVER}:${REMOTE_DIR}/
# 保留远程服务器上最近 30 天的备份
ssh ${REMOTE_SERVER} "find ${REMOTE_DIR} -name '*.tar.gz' -mtime +30 -delete"
使用云存储
# 使用 rclone 同步到对象存储
rclone sync /backup/k3s remote:my-k8s-backup-bucket
# 使用 AWS CLI 上传到 S3
aws s3 sync /backup/k3s s3://my-k8s-backup-bucket/k3s/
灾难恢复演练
演练步骤
-
模拟故障
# 停止所有 K3s 服务 systemctl stop k3s # 或删除 etcd 数据 rm -rf /var/lib/rancher/k3s/server/db -
执行恢复
- 使用备份脚本恢复数据
- 验证集群状态
-
验证应用
# 检查节点状态 kubectl get nodes # 检查 Pod 状态 kubectl get pods --all-namespaces # 测试服务访问 curl http://app.example.com
恢复时间目标(RTO)
| 场景 | RTO | 方法 |
|---|---|---|
| 单节点故障 | 5 分钟 | 自动重新调度 |
| etcd 数据损坏 | 15 分钟 | 快照恢复 |
| 整个集群丢失 | 1 小时 | 全量备份恢复 |
| 数据中心灾难 | 4 小时 | 异地备份恢复 |
最佳实践
备份建议
- 定期备份:etcd 每小时,配置每次变更,数据每日
- 多地存储:本地 + 异地 + 云存储
- 定期演练:每季度进行一次恢复演练
- 监控告警:备份失败及时通知
安全配置
# 加密备份文件
gpg --symmetric --cipher-algo AES256 backup.tar.gz
# 安全传输
scp -i /path/to/private_key backup.tar.gz user@remote:/backup/
总结
本文介绍了 K3s 集群的备份与恢复策略:
- etcd 备份:使用 K3s 内置快照功能定期备份集群状态
- 应用备份:使用 Velero 或 CronJob 备份应用数据
- 灾难恢复:详细的恢复步骤和演练方法
- 异地备份:多地点存储确保数据安全
完善的备份策略是生产环境稳定运行的重要保障,建议根据业务需求制定合适的备份计划和恢复流程。