restic 安全可靠的备份工具——筑梦之路

支持的后端存储:
本地
sftp (通过ssh)
http rest server (rest-server restic提供的 )
s3 (同时支持minio)
openstack swift
backblaze b2
azure blob storage
google cloud storage
以及其他可以通过rclone 访问的后端存储

restic+minio

minio(docker-compose搭建单机版)

cat docker-compose.yml
version: '3.0'
services:
  tbc-minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - /data/minio/data:/data
      - /data/minio/config:/root/.minio
    environment:
      - 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: 30s
      timeout: 20s
      retries: 3
    restart: on-failure

mkdir /data/minio/{data,config} -p

docker-compose up -d

浏览器访问验证:http://ip:9000

配置s3环境变量:

export AWS_ACCESS_KEY_ID=admin12345678
export AWS_SECRET_ACCESS_KEY=admin12345678

安装restic

sudo yum -y install yum-plugin-copr

sudo yum copr enable copart/restic

sudo 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 f7d5b7c5

55572d0c 为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 /mnt

mount | grep /mnt

cat /mnt/snapshots/latest/backup-demo/hello2.txt

umount /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,s3ForcePathStyle="true" \
    --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-config
  namespace: velero
  labels:
    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-demo
  namespace: nginx-app
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: ceph-rbd-sata
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: nginx-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
      annotations:
        backup.velero.io/backup-volumes: mypvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
          - name: mypvc
            mountPath: /usr/share/nginx/html
      volumes:
      - name: mypvc
        persistentVolumeClaim:
          claimName: pvc-demo
          readOnly: false
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: nginx-app
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    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/bash

cd /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 snapshots

restic -r s3:http://192.168.0.1/velero/restic/nginx-app ls 14fc2081

restic -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-app

kubectl get ns nginx-app

#数据恢复
velero restore create --from-backup nginx-backup-1

velero restore get

#验证
kubectl get pod -n nginx-app

kubectl 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-app

curl  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

 restic 安全可靠的备份工具——筑梦之路_第1张图片

  • 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-cluster

ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb

备份etcd到Minio对象存储

#!/bin/sh
# bootstrap.sh
export ETCDCTL_API=3

MASTER_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).db

etcdctl --endpoints=$MASTER_ENDPOINT \
  --cacert=/etc/ssl/etcd/ca.crt \
  --cert=/etc/ssl/etcd/etcd.crt \
  --key=/etc/ssl/etcd/etcd.key \
  snapshot save $BACKUP_FILE

aws --endpoint $S3_ENDPOINT s3 cp $BACKUP_FILE s3://$BUCKET_NAME

for f in $(aws --endpoint $S3_ENDPOINT \
    s3 ls $BUCKET_NAME | head -n "-${KEEP_LAST_BACKUP_COUNT}" \
    | awk '{print $4}'); do
    aws --endpoint $S3_ENDPOINT s3 rm s3://$BUCKET_NAME/$f
done

首先获取master节点的endpoint,然后通过master endpoint创建etcd快照。快照生成后通过aws s3命令拷贝到远端对象存储中,最后会删除一些老的备份,只保留指定数量的备份数量

做成docker镜像:Dockerfile

FROM 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-backup
  namespace: etcd-backup
spec:
  jobTemplate:
    metadata:
      name: etcd-backup
    spec:
      template:
        spec:
          containers:
          - image: etcd-backup:v3.4.3
            imagePullPolicy: IfNotPresent
            name: etcd-backup
            volumeMounts:
            - name: s3-credentials
              mountPath: /root/.aws
            - name: etcd-tls
              mountPath: /etc/ssl/etcd
            - name: localtime
              mountPath: /etc/localtime
              readOnly: true
            env:
            - name: ETCD_ENDPOINTS
              value: "192.168.1.1:2379,192.168.1.2:2379,192.168.1.3:2379"
            - name: BUCKET_NAME
              value: etcd-backup
            - name: S3_ENDPOINT
              value: "http://192.168.1.53"
            - name: KEEP_LAST_BACKUP_COUNT
              value: "7"
          volumes:
          - name: s3-credentials
            secret:
              secretName: s3-credentials
          - name: etcd-tls
            secret:
              secretName: etcd-tls
          - name: localtime
            hostPath:
              path: /etc/localtime
          restartPolicy: OnFailure
  schedule: '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

你可能感兴趣的:(linux系统运维,数据库技术,云计算,docker,linux,服务器)