支持的后端存储:
本地
sftp (通过ssh)
http rest server (rest-server restic提供的 )
s3 (同时支持minio)
openstack swift
backblaze b2
azure blob storage
google cloud storage
以及其他可以通过rclone 访问的后端存储restic+miniominio(docker-compose搭建单机版)cat docker-compose.yml
version: '3.0'
services:tbc-minio:image: minio/minioports:- "9000:9000"- "9001:9001"volumes:- /data/minio/data:/data- /data/minio/config:/root/.minioenvironment:- MINIO_DOMAIN=tbc-minio- MINIO_ACCESS_KEY=admin12345678 #用户- MINIO_SECRET_KEY=admin12345678 #密码command: server /data --console-address ":9001"healthcheck:test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]interval: 30stimeout: 20sretries: 3restart: on-failuremkdir /data/minio/{data,config} -pdocker-compose up -d浏览器访问验证:http://ip:9000配置s3环境变量:export AWS_ACCESS_KEY_ID=admin12345678
export AWS_SECRET_ACCESS_KEY=admin12345678安装resticsudo yum -y install yum-plugin-coprsudo yum copr enable copart/resticsudo yum -y install restic配置自动补全
restic generate --bash-completion restic.bash_completion
source restic.bash_completion初始化备份仓库
restic -r s3:http://ip/backup init查看仓库状态
restic -r s3:http://ip/backup stats【可选】加入环境变量,免去每次输入密码
export RESTIC_PASSWORD=*********
export RESTIC_REPOSITORY=s3:http://ip/backup
查看状态:restic stats执行备份test目录操作
restic -r s3:http://ip/backup backup test#参数说明:
默认备份目录下所有文件
--exclude 排除某些文件
--file-from 指定备份的文件列表对比备份的差异
restic diff 55572d0c f7d5b7c555572d0c 为snapshot id列举所有的snapshot
restic snapshots
restic -r s3:http://ip/backup snapshots查看快照中的文件列表
restic ls f18cccc5 / restic ls -l f18cccc5查找所有文件
restic find hello*查找指定快照指定文件的内容
restic dump f18cccc5 /backup-demo/hello2.txt挂载快照内容到本地
restic mount /mntmount | grep /mntcat /mnt/snapshots/latest/backup-demo/hello2.txtumount /mnt------------------------------------------------------------
数据恢复
restic restore f18cccc5 -t /tmp/restore_data单个文件恢复
restic dump f18cccc5 /backup-demo/hello2.txt >hello2.txt备份删除
--dry-run参数查看指定策略会删除的快照,但实际不会执行删除操作,用于检验参数是否符合预期比如保留最新的3个快照
restic forget --keep-last=3 --dry-run保留前两小时的备份
restic forget --dry-run --keep-hourly 2备份计划:结合crontab命令执行
Velero Kubernetes应用备份容灾,其他工具Stash
./velero install \--provider aws \--plugins xxx/velero-plugin-for-aws:v1.0.0 \--bucket velero \--secret-file ./aws-iam-creds \--backup-location-config region=test,s3Url=http://192.168.0.1,s3ForcePath \--snapshot-location-config region=test \--image xxx/velero:v1.6.3 \--features=EnableCSI \--use-restic \--dry-run -o yaml--plugins以及--image参数指定镜像仓库地址,仅当使用私有镜像仓库时需要配置。
--use-restic参数开启使用restic备份PV数据卷功能。
早期Kubernetes的volume卷不支持快照,因此备份PV卷时需要安装特定的后端存储卷插件,Kubernetes从v1.12开始CSI引入Snapshot后可以利用Snapshot特性实现备份,指定--features=EnableCSI参数开启,开启该模式的底层存储必须支持snapshot,并且配置了snapshot相关的CRD以及volumesnapshotclass(类似storageclass)数据恢复需要依赖velero-restic-restore-helper工具,如果使用私有镜像仓库,可以通过restic configmap配置私有镜像地址:apiVersion: v1
kind: ConfigMap
metadata:name: restic-confignamespace: velerolabels:velero.io/plugin-config: ""velero.io/restic: RestoreItemAction
data:image: xxx/velero-restic-restore-helper:v1.6.3
备份
# nginx-app-demo.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: nginx-app
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-demonamespace: nginx-app
spec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: ceph-rbd-sata
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginxnamespace: nginx-app
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxannotations:backup.velero.io/backup-volumes: mypvcspec:containers:- image: nginxname: nginxvolumeMounts:- name: mypvcmountPath: /usr/share/nginx/htmlvolumes:- name: mypvcpersistentVolumeClaim:claimName: pvc-demoreadOnly: false
---
apiVersion: v1
kind: Service
metadata:labels:app: nginxname: nginxnamespace: nginx-app
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginx
声明了一个PVC,并挂载到nginx pod的/usr/share/nginx/html
路径。
pod添加了注解backup.velero.io/backup-volumes: mypvc
用于指定需要备份的volume。因为并不是所有的volume都必须备份,实际生产中可根据数据的重要性设置合理的备份策略,因此不建议开启--default-volumes-to-restic
选项,该选项会默认备份所有的volume。
#进入容器写入一些测试数据kubectl exec -t -i nginx-86f99c968-sj8ds -- /bin/bashcd /usr/share/nginx/html/
echo "HelloWorld" >index.html
echo "hello1" >hello1.html
echo "hello2" >hello2.html#创建备份
velero backup create nginx-backup-1 --include-namespaces nginx-app#查看备份信息
velero describe backups nginx-backup-1备份状态为Completed,说明备份完成,记录中会有备份开始时间和完成时间。
备份的资源数和完成数。
备份的volume数(Restic Backups)。------------------------------------------------
备份数据管理、迁移
#s3中查看
aws s3 ls velero/backups/nginx-backup-1/#下载备份
velero backup download nginx-backup-1如上数据只包含Kubernetes声明资源的yaml文件,不包含最重要的volume业务数据。这些数据保存在s3的velero/restic/nginx-app/路径下,而这些数据是加密存储的restic的仓库密码:
kubectl get secrets velero-restic-credentials \-o jsOnpath='{.data.repository-password}' | base64 -d对备份数据的查看
restic -r s3:http://192.168.0.1/velero/restic/nginx-app snapshotsrestic -r s3:http://192.168.0.1/velero/restic/nginx-app ls 14fc2081restic -r s3:http://192.168.0.1/velero/restic/nginx-app dump 14fc2081 /hello2.html数据恢复模拟场景#删除
kubectl delete -f nginx-app-demo.yaml#检查
kubectl get all -n nginx-appkubectl get ns nginx-app#数据恢复
velero restore create --from-backup nginx-backup-1velero restore get#验证
kubectl get pod -n nginx-appkubectl get svc -n nginx-app#业务检查
kubectl exec -t -i -n nginx-app nginx-86f99c968-8zh6m -- ls /usr/share/nginx/html/kubectl get svc -n nginx-appcurl 10.106.140.195------------------------------------
备份计划和策略,配置支持的如下:备份时间,crontab语法。
备份保留时间,通过ttl指定,默认30天。
备份内容,支持指定namespace或者基于label指定具体的备份资源帮助信息:velero create schedule -h示例:
# Create a backup every 6 hours.
velero create schedule NAME --schedule="0 */6 * * *"# Create a backup every 6 hours with the @every notation.
velero create schedule NAME --schedule="@every 6h"# Create a daily backup of the web namespace.
velero create schedule NAME --schedule="@every 24h" --include-namespaces web# Create a weekly backup, each living for 90 days (2160 hours).
velero create schedule NAME --schedule="@every 168h" --ttl 2160h0m0s
minio为开源的对象存储,为velero/restic提供备份存储后端,实际生产时调整为企业对象存储系统。
远端存储为异地存储系统,比如异地磁带库、NBU,或者跨region的异地对象存储系统。
备份流程:
(1)Kubernetes的所有资源包括Pod、Deployment、ConfigMap、Secret、PV卷数据等通过Velero备份到对象存储。(2)通过minio-sync实现实时同步数据到远端同城异地存储系统。
恢复流程:
(1)场景一:集群状态无异常,人为误操作导致数据被删。
直接通过velero恢复指定时间的数据进行恢复即可。
(2)场景二:PV底层的存储系统crash导致数据丢失。
恢复存储系统集群或者极端情况下重搭存储集群,然后使用velero从对象存储中恢复数据。
(3)场景三:极端场景下,整个数据中心或者region crash导致数据丢失。
重建环境,业务数据需要从异地数据中复制到本地,然后借助velero从新建对象存储中进行数据恢复。
(4)场景四:K8S环境迁移。
新建Kubernetes集群,通过velero指定备份点迁移数据到新环境中。
(5)场景五:业务从K8S运行迁移到虚拟机或者物理机运行。
通过Restic从对象存储中把业务数据导出到虚拟机的数据卷中即可。
------------------------------------------------------------------------------------------------
集群备份Kubernetes证书、kubeadm配置的备份可以直接使用前面介绍的restic工具对整个/etc/kubernetes目录进行备份,而etcd的备份官方也有介绍backing-up-an-etcd-clusterETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb备份etcd到Minio对象存储#!/bin/sh
# bootstrap.sh
export ETCDCTL_API=3MASTER_ENDPOINT=$(etcdctl --endpoints=$ETCD_ENDPOINTS \--cacert=/etc/ssl/etcd/ca.crt \--cert=/etc/ssl/etcd/etcd.crt \--key=/etc/ssl/etcd/etcd.key \endpoint status \| awk -F ',' '{printf("%s %s\n", $1,$5)}' \| tr -s ' ' | awk '/true/{print $1}')echo "etcd master endpoint is ${MASTER_ENDPOINT}"BACKUP_FILE=etcd-backup-$(date +%Y%m%d%H%M%S).dbetcdctl --endpoints=$MASTER_ENDPOINT \--cacert=/etc/ssl/etcd/ca.crt \--cert=/etc/ssl/etcd/etcd.crt \--key=/etc/ssl/etcd/etcd.key \snapshot save $BACKUP_FILEaws --endpoint $S3_ENDPOINT s3 cp $BACKUP_FILE s3://$BUCKET_NAMEfor f in $(aws --endpoint $S3_ENDPOINT \s3 ls $BUCKET_NAME | head -n "-${KEEP_LAST_BACKUP_COUNT}" \| awk '{print $4}'); doaws --endpoint $S3_ENDPOINT s3 rm s3://$BUCKET_NAME/$f
done首先获取master节点的endpoint,然后通过master endpoint创建etcd快照。快照生成后通过aws s3命令拷贝到远端对象存储中,最后会删除一些老的备份,只保留指定数量的备份数量做成docker镜像:DockerfileFROM python:alpine
ARG ETCD_VERSION=v3.4.3
RUN apk add --update --no-cache ca-certificates tzdata openssl
RUN wget https://github.com/etcd-io/etcd/releases/download/${ETCD_VERSION}/etcd-${ETCD_VERSION}-linux-amd64.tar.gz \&& tar xzf etcd-${ETCD_VERSION}-linux-amd64.tar.gz \&& mv etcd-${ETCD_VERSION}-linux-amd64/etcdctl /usr/local/bin/etcdctl \&& rm -rf etcd-${ETCD_VERSION}-linux-amd64*
RUN pip3 install awscli
ENV ETCDCTL_API=3
ADD bootstrap.sh /
RUN chmod +x /bootstrap.sh
CMD ["/bootstrap.sh"]把etcd的证书以及Minio的AKSK存储到Kubernetes Secret中
#!/bin/bash
kubectl create secret generic etcd-tls -o yaml \--from-file /etc/kubernetes/pki/etcd/ca.crt \--from-file /etc/kubernetes/pki/etcd/server.crt \--from-file /etc/kubernetes/pki/etcd/server.key \| sed 's/server/etcd/g'
kubectl create secret generic s3-credentials \-o yaml --from-file ~/.aws/credentials通过Kubernetes自带内置的cronjob实现定时备份apiVersion: batch/v1beta1
kind: CronJob
metadata:name: etcd-backupnamespace: etcd-backup
spec:jobTemplate:metadata:name: etcd-backupspec:template:spec:containers:- image: etcd-backup:v3.4.3imagePullPolicy: IfNotPresentname: etcd-backupvolumeMounts:- name: s3-credentialsmountPath: /root/.aws- name: etcd-tlsmountPath: /etc/ssl/etcd- name: localtimemountPath: /etc/localtimereadOnly: trueenv:- name: ETCD_ENDPOINTSvalue: "192.168.1.1:2379,192.168.1.2:2379,192.168.1.3:2379"- name: BUCKET_NAMEvalue: etcd-backup- name: S3_ENDPOINTvalue: "http://192.168.1.53"- name: KEEP_LAST_BACKUP_COUNTvalue: "7"volumes:- name: s3-credentialssecret:secretName: s3-credentials- name: etcd-tlssecret:secretName: etcd-tls- name: localtimehostPath:path: /etc/localtimerestartPolicy: OnFailureschedule: '0 0 * * *'每天0点对etcd进行备份到Minio对象存储
参考资料:
restic: https://restic.readthedocs.io/en/latest/010_introduction.html
https://github.com/restic/restic/releases
Velero: https://velero.io/docs/
Stash: https://stash.run/
backing-up-an-etcd-cluster: https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster