公司动态
Kubernetes灾难恢复实战:Velero与ETCD备份方案
1. 项目概述Kubernetes灾难恢复的核心挑战在云原生架构中Kubernetes集群的灾难恢复能力直接关系到业务连续性。去年我们生产环境就遭遇过ETCD数据损坏导致整个集群不可用的严重事故当时由于缺乏有效的备份方案最终不得不耗时8小时重建集群。这次教训让我深刻认识到完善的备份还原体系不是可选项而是生产环境的生命线。Velero作为CNCF孵化的开源工具专为解决Kubernetes资源备份难题而生。它不仅能捕获集群状态包括Deployment、Service等API对象还能通过插件机制备份持久卷数据。而ETCD作为Kubernetes的大脑其数据完整性更是灾备的重中之重。本文将分享如何构建从应用层到控制平面的全方位防护体系。2. 核心组件解析与选型考量2.1 Velero架构深度剖析Velero的备份流程涉及三个关键组件服务端控制器运行在集群内的Pod负责协调备份/恢复操作CLI工具本地执行的命令行界面通过kubeconfig与集群交互对象存储后端支持AWS S3、Azure Blob等云存储也可用MinIO自建我们选择Velero而非传统方案如手动kubectl导出的主要原因原子性操作自动处理资源依赖关系避免手动备份时常见的对象遗漏CRD支持完美备份自定义资源这是很多DIY方案无法实现的增量备份通过--snapshot-volumes参数可只备份变更的持久卷数据2.2 ETCD备份的特殊性虽然Velero能备份工作负载但控制平面组件如kube-apiserver的状态仍依赖ETCD。ETCD备份有两大难点数据一致性直接拷贝etcd数据目录会导致损坏必须使用etcdctl snapshot save证书问题恢复时若证书过期会导致集群脑裂需要配合cert-manager处理3. 实战部署与配置指南3.1 Velero安装与初始化以AWS S3为例的安装步骤其他存储后端类似# 下载最新CLI工具 wget https://github.com/vmware-tanzu/velero/releases/download/v1.11.0/velero-v1.11.0-linux-amd64.tar.gz tar -xvf velero-v1.11.0-linux-amd64.tar.gz sudo mv velero /usr/local/bin/ # 创建S3存储桶 aws s3api create-bucket --bucket my-velero-backups --region us-west-2 # 安装服务端 velero install \ --provider aws \ --plugins velero/velero-plugin-for-aws:v1.6.1 \ --bucket my-velero-backups \ --backup-location-config regionus-west-2 \ --snapshot-location-config regionus-west-2 \ --use-restic关键参数说明--use-restic启用文件系统级持久卷备份替代已弃用的Restic--default-volumes-to-restic自动备份所有Pod挂载的卷3.2 ETCD定期备份方案对于使用kubeadm部署的集群建议通过CronJob实现自动化备份apiVersion: batch/v1 kind: CronJob metadata: name: etcd-backup namespace: kube-system spec: schedule: 0 */6 * * * jobTemplate: spec: template: spec: containers: - name: etcdctl image: bitnami/etcd:3.5.9 env: - name: ETCDCTL_ENDPOINTS value: https://127.0.0.1:2379 - name: ETCDCTL_CACERT value: /etc/kubernetes/pki/etcd/ca.crt - name: ETCDCTL_CERT value: /etc/kubernetes/pki/etcd/server.crt - name: ETCDCTL_KEY value: /etc/kubernetes/pki/etcd/server.key command: - /bin/sh - -c - | etcdctl snapshot save /backup/etcd-snapshot-$(date %Y%m%d-%H%M%S).db aws s3 cp /backup/*.db s3://my-etcd-backups/ volumeMounts: - mountPath: /etc/kubernetes/pki/etcd name: etcd-certs readOnly: true - mountPath: /backup name: backup volumes: - name: etcd-certs hostPath: path: /etc/kubernetes/pki/etcd - name: backup emptyDir: {} restartPolicy: OnFailure hostNetwork: true nodeSelector: node-role.kubernetes.io/control-plane: tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule重要提示备份文件必须包含时间戳避免覆盖历史备份。同时建议启用S3版本控制功能。4. 灾难恢复全流程演练4.1 场景一应用级故障恢复当某个命名空间被误删除时使用Velero恢复的完整流程# 查看可用备份 velero backup get # 执行恢复可选择特定资源 velero restore create ns-restore \ --from-backup my-backup \ --include-namespaces critical-app \ --include-resources deployments,services,configmaps # 监控恢复进度 velero restore describe ns-restore常见问题处理StorageClass冲突若目标集群StorageClass不同需添加--storage-class-mappings参数节点亲和性失效恢复后检查Pod分布可能需要调整节点标签4.2 场景二全集群ETCD恢复当控制平面完全崩溃时按以下步骤重建# 在所有控制节点停止kube-apiserver sudo systemctl stop kube-apiserver # 从S3下载最新快照 aws s3 cp s3://my-etcd-backups/etcd-snapshot-20230801-120000.db . # 在每个控制节点执行恢复 sudo etcdctl snapshot restore etcd-snapshot-20230801-120000.db \ --data-dir /var/lib/etcd-restore \ --initial-cluster controller1https://10.0.1.101:2380 \ --initial-advertise-peer-urls https://10.0.1.101:2380 \ --name controller1 # 修改etcd.service配置指向新数据目录 sudo sed -i s|/var/lib/etcd|/var/lib/etcd-restore| /etc/systemd/system/etcd.service # 重启服务 sudo systemctl daemon-reload sudo systemctl start etcd sudo systemctl start kube-apiserver关键检查点证书有效期确保etcd证书在恢复后仍然有效节点IP变更若集群IP地址变化需调整--initial-cluster参数数据一致性恢复后运行etcdctl endpoint status验证各成员状态5. 高级配置与优化技巧5.1 备份策略精细化控制通过Schedule资源实现智能备份策略apiVersion: velero.io/v1 kind: Schedule metadata: name: daily-backup namespace: velero spec: schedule: 0 2 * * * template: includedNamespaces: - * excludedNamespaces: - kube-system - velero ttl: 720h storageLocation: default volumeSnapshotLocations: - aws-default hooks: resources: - name: pre-backup-hook includedNamespaces: - * pre: - exec: container: app command: - /bin/sh - -c - flock -n /tmp/db.lock mysqldump -u root -p$DB_PASSWORD --all-databases /var/lib/mysql/backup.sql onError: Fail timeout: 5m这个配置实现了每日凌晨2点全量备份除系统命名空间备份前自动执行数据库dump自动清理30天前的旧备份5.2 ETCD备份验证方案定期验证备份有效性的CronJob示例#!/bin/bash # 下载最新备份 BACKUP_FILE$(aws s3 ls s3://my-etcd-backups/ | sort | tail -n 1 | awk {print $4}) aws s3 cp s3://my-etcd-backups/$BACKUP_FILE /tmp/ # 启动临时etcd集群 docker run -d \ -p 12379:2379 \ -p 12380:2380 \ -v /tmp:/data \ --name etcd-verify \ bitnami/etcd:3.5.9 \ etcd --data-dir /data --snapshot-count0 # 验证数据可读性 if etcdctl --endpointshttp://localhost:12379 get / --prefix; then echo Backup verification SUCCESS else echo Backup verification FAILED exit 1 fi # 清理 docker stop etcd-verify docker rm etcd-verify6. 生产环境经验总结6.1 Velero性能优化参数在大规模集群中500节点这些配置可显著提升备份效率velero install \ ... --restic-timeout 4h \ --restic-node-selector backupenabled \ --default-volumes-to-fs-backupfalse \ --featuresEnableCSI关键调整项专用备份节点通过nodeSelector将备份Pod调度到特定节点CSI插件对CSI卷使用原生快照功能需存储供应商支持并行度控制调整--client-qps和--client-burst参数应对API限流6.2 ETCD恢复的黄金法则根据多次真实故障演练总结出三条铁律3-2-1备份原则至少保留3份备份存储在2种不同介质其中1份异地保存变更立即备份集群证书更新后节点扩缩容操作前Kubernetes版本升级前后定期恢复演练每季度执行全集群灾难恢复演练验证备份的可用性而不仅是存在性7. 典型故障排查手册7.1 Velero常见错误代码错误现象可能原因解决方案BackupStorageLocation不可用凭证失效/网络中断检查velero日志中的AWS错误详情Volume备份卡住Pod有大量小文件增加restic-timeout或排除缓存目录恢复后PodPendingStorageClass不匹配使用--storage-class-mappings参数7.2 ETCD恢复异常处理案例恢复后apiserver无法连接etcdError while dialing dial tcp 10.0.1.101:2379: connect: connection refused排查步骤检查etcd服务状态sudo systemctl status etcd查看etcd日志journalctl -u etcd -n 100验证证书有效性openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates检查监听地址ss -tulnp | grep 2379根本原因往往是证书过期需更新所有相关证书数据目录权限错误chown -R etcd:etcd /var/lib/etcd网络配置变更检查防火墙规则8. 多云环境下的备份策略对于跨云部署的集群建议采用分级备份方案本地快速恢复层Velero 集群内MinIO保留最近24小时备份RTO恢复时间目标30分钟云端持久层每日同步到AWS S3 IA存储保留30天备份启用对象锁定防篡改异地灾备层每周备份到Azure Archive Storage保留1年以上需要时人工激活配置示例使用velero的多个备份位置# 添加Azure备份位置 velero backup-location create azure-backup \ --provider azure \ --bucket velero-archive \ --config resourceGroupmy-rg,storageAccountmystorage # 创建迁移任务 velero create schedule cross-cloud-sync \ --scheduleweekly \ --include-cluster-resourcestrue \ --storage-locationdefault \ --snapshot-locationaws-default \ --ttl168h \ --copy-toazure-backup9. 监控与告警体系建设9.1 Prometheus监控指标关键监控指标配置- job_name: velero metrics_path: /metrics static_configs: - targets: [velero-server:8085] - job_name: etcd static_configs: - targets: [10.0.1.101:2379,10.0.1.102:2379] metrics_path: /metrics scheme: https tls_config: ca_file: /etc/prometheus/etcd-ca.crt cert_file: /etc/prometheus/etcd-client.crt key_file: /etc/prometheus/etcd-client.key insecure_skip_verify: false9.2 必须配置的告警规则groups: - name: backup-alerts rules: - alert: VeleroBackupFailed expr: velero_backup_failure_total{jobvelero} 0 for: 5m labels: severity: critical annotations: summary: Velero backup failed ({{ $labels.name }}) description: Backup {{ $labels.name }} has failed {{ $value }} times - alert: EtcdBackupMissed expr: time() - etcd_last_backup_timestamp_seconds 86400 labels: severity: warning annotations: summary: ETCD backup overdue description: No successful backup in last 24 hours10. 证书管理的特别注意事项在ETCD恢复场景中证书问题是最常见的陷阱。建议采用以下方案证书轮换策略使用cert-manager自动管理证书设置比备份周期更长的有效期如1年恢复时的证书处理# 检查证书有效期 openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -noout -dates # 临时解决方案测试环境 kubeadm certs renew all --config /etc/kubernetes/kubeadm-config.yaml systemctl restart kubelet长期方案将etcd证书与kubeadm管理的证书分离使用Hashicorp Vault等工具集中管理证书在备份元数据中记录证书过期时间对于大规模集群我推荐使用以下证书目录结构/etc/kubernetes/pki/ ├── etcd/ │ ├── ca.crt │ ├── healthcheck-client.crt │ └── peer.crt └── kubeadm/ ├── apiserver.crt └── front-proxy-ca.crt这种隔离设计可以避免恢复时证书的交叉影响。