K8s的BackUP备份

发布于:2025-04-06 ⋅ 阅读:(34) ⋅ 点赞:(0)

ETCD备份/还原有多种类型,取决于你 k8s 集群的搭建方式

1、kubeadm 安装的单 master 节点数据备份和恢复方式

拷贝 etcdctl 至 master 节点,这样我们就可以使用 etcd 的客户端管理工具了

docker cp $(docker ps  |  grep -v etcd-mirror | grep -w etcd | awk '{print $1}'):/usr/local/bin/etcdctl /usr/bin/

基于 ETCD v3 接口实现数据备份,还有 v2 版本,推荐使用 v3 版本协议

ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379"  --cert="/etc/kubernetes/pki/etcd/server.crt"  --key="/etc/kubernetes/pki/etcd/server.key"  --cacert="/etc/kubernetes/pki/etcd/ca.crt"   snapshot save snap-$(date +%Y%m%d%H%M).db

将数据进行破坏

mv /var/lib/etcd/ /var/lib/etcd-back && mkdir /var/lib/etcd && chmod 700 /var/lib/etcd

还原数据需要保证 apiServer 处于关闭状态,下面这是最简单的方式,kubelete 需要把该目录下所有资源清单以静态 Pod 的方式运行

mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bak

通过 snapshot restore 进行还原

ETCDCTL_API=3 etcdctl --data-dir=/var/lib/etcd \
    --endpoints="https://127.0.0.1:2379" \
    --cert="/etc/kubernetes/pki/etcd/server.crt" \
    --key="/etc/kubernetes/pki/etcd/server.key" \
    --cacert="/etc/kubernetes/pki/etcd/ca.crt" \
    snapshot restore snap-202501152137.db

恢复 apiServer后观察原来的 Pod 之类的资源是否还存在

mv /etc/kubernetes/manifests.bak /etc/kubernetes/manifests

使用上面这种备份方式非常简单,但也存在问题,如果我想要定向备份某一个资源而不是全部那该怎么办呢?

2、Velero 工具

Velero 是由 GO 语言编写的一款用于灾难恢复和迁移工具,可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷。

Velero 主要提供以下能力:

  • 备份 Kubernetes 集群资源,并在资源丢失情况下进行还原
  • 将集群资源迁移到其他集群
  • 将生产集群复制到开发和测试集群
原理:使用了 CRD
在这里插入图片描述

Velero 对象存储同步:Velero 将对象存储视为事实来源,它不断检查以确保始终存在正确的备份资源。如果存储桶中有格式正确的备份文件,但 Kubernetes API 中没有对应的备份资源,Velero 会将信息从对象存储同步到 Kubernetes。同理,如果 Kubernetes API 中显示存在对应的备份资源,但存储桶中没有格式正确的备份文件,那么就认为资源备份失败或是产生错误,将其清理掉。

3、Velero 服务部署

部署 Minio 作为对象存储服务,存储备份信息

docker run --name minio -p 9000:9000 -p 9999:9999 -d \
    --restart=always -e "MINIO_ROOT_USER=admin" \
    -e "MINIO_ROOT_PASSWORD=12345678" \
    -v /data/minio/data:/data \
    minio/minio:RELEASE.2022-04-12T06-55-35Z \
    server /data --console-address '0.0.0.0:9999'

初始化 Minio

只需要添加一个 velero 的桶即可
在这里插入图片描述

初始化 velero

https://github.com/vmware-tanzu/velero/releases/tag/v1.13.2 安装 velero client,解压放置/usr/local/bin

wget https://github.com/vmware-tanzu/velero/releases/download/v1.13.2/velero-v1.13.2-linux-amd64.tar.gz
tar -zxvf velero-v1.13.2-linux-amd64.tar.gz
mv velero-v1.13.2-linux-amd64/velero /usr/local/bin

提前创建好数据目录

mkdir -p /data/velero

编写一份数据:/data/velero/velero-auth.txt 文件,相当于其所需的身份认证信息

[default]
aws_access_key_id = admin
aws_secret_access_key = 12345678

初始化设置并安装 ⛵

velero --kubeconfig /root/.kube/config install --use-node-agent --default-volumes-to-fs-backup \
    --provider aws --plugins velero/velero-plugin-for-aws:latest --bucket velero \
    --secret-file /data/velero/velero-auth.txt --use-volume-snapshots=false \
    --namespace velero-system --backup-location-config \
    region=minio,s3ForcePathStyle='true',s3Url=http://192.168.150.145:9000
    # 不支持 hostPath 卷

部署完毕后进行验证

[root@k8s-master ~]# kubectl get pod -n velero-system
NAME                      READY   STATUS    RESTARTS   AGE
node-agent-r9sq5          1/1     Running   0          8m54s
node-agent-xhzvh          1/1     Running   0          8m54s
velero-6467766456-s7j2f   1/1     Running   0          8m54s
[root@k8s-master ~]# velero version -n velero-system
Client:
        Version: v1.13.2
        Git commit: 4d961fb6fec384ed7f3c1b7c65c818106107f5a6
Server:
        Version: v1.13.2

4、备份还原数据

实验演示资源清单

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx:1.27.3-alpine
      volumeMounts:
        - name: my-persistent-storage
          mountPath: /usr/local/nginx/html
  volumes:
    - name: my-persistent-storage
      persistentVolumeClaim:
        claimName: my-pvc

进入容器内部在挂载目录下生成一个 100MB 的文件,内容全是 0 字节

/usr/share/nginx/html # dd if=/dev/zero of=1.txt bs=1MB count=100
100+0 records in
100+0 records out
100000000 bytes (95.4MB) copied, 1.383662 seconds, 68.9MB/s

开始进行备份动作,指定备份 default 命名空间

DATE=`date +%Y%m%d%H%M%S`
velero backup create default-backup-${DATE} \
    --include-namespaces default \
    --kubeconfig=/root/.kube/config \
    --namespace velero-system
    # --ttl 24h0m0s 如果未指定,将应用 30 天的默认 TTL 值

给出如下提示

Backup request "default-backup-20250116004042" submitted successfully.
Run `velero backup describe default-backup-20250116004042` or `velero backup logs default-backup-20250116004042` for more details.

执行命令并观察结果,可以看到相关的备份信息,并且可以在 Minio 中看到备份的存储结果

[root@k8s-master backup]# velero backup get -n velero-system
NAME                            STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
default-backup-20250116004042   Completed   0        0          2025-01-16 00:40:42 +0800 CST   29d       default            <none>

删除创建的资源及 Pod 所使用的 PV

kubectl delete -f 1.backup.yaml
rm -rf /nfsdata/share/default/my-pvc/*

确认文件消失后再执行恢复操作,如果一直监控当前命名空间 Pod 的恢复状态会发现存在 Init 状态,也就是说恢复数据的操作是一个 init 容器去做的,另外如果去观察 Minio 中备份文件的大小会发现仅有 4MB 左右的大小,这是因为 100MB 的数据文件是通过大量重复字段创建的,所以经过压缩算法压缩后的效果非常好

velero restore create \
    --from-backup default-backup-20250116004042 \
    --wait \
    --kubeconfig=/root/.kube/config \
    --namespace velero-system