k8s备份 ETCD , 使用velero工具进行备份

使用velero工具进行备份

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

Velero 主要提供以下能力:

​ 备份 Kubernetes 集群资源,并在资源丢失情况下进行还原

​ 将集群资源迁移到其他集群

​ 将生产集群复制到开发和测试集群

备份工作流程

复制代码
当运行velero backup create 时:
	1. Velero客户端调用Kubernetes API server以创建Backup对象;
	2. 该BackupController检测到Backup对象被创建并执行验证;
	3. BackupController开始备份过程,它通过向Kubernetes API server查询资源来收集要备份的数据
	4. BackupController调用对象存储服务(例如AWS S3 : MinIO)上载备份文件。

velero backup create支持任何持久卷的磁盘快照,您可以通过指定其他标志来调整快照,

运行velero backup create --help可以查看可用的标志,

可以使用 --snapshot-volumes=false选项禁用快照。
velero结合MinIo实现备份、恢复、迁移

minio介绍

复制代码
它可以用于存储各种类型的数据,如图片、视频、日志文件、备份文件等,
并且能够横向扩展以支持大规模数据存储。
MinIO 被设计为轻量级、高效且易于部署,适合各种规模的应用,从小型项目到企业级应用。
为用户提供高效、可靠的存储服务。

一、安装 minio 服务(对象存储)

新建一台服务器,安装minio,新服务器需要运行如下两步。
环境初始化
复制代码
# 网卡配置
# cat /etc/NetworkManager/system-connections/ens160.nmconnection
[ipv4]
method=manual
address1=192.168.174.139/24,192.168.174.1
dns=114.114.114.114;8.8.8.8
# cat /etc/NetworkManager/system-connections/ens192.nmco**nnection
[connection]
autoconnect=false
# 调用 nmcli 重启设备和连接配置
nmcli d d ens33   # 断开设备
nmcli d r ens33   # 重启设备
nmcli c r ens33   # 重启或重新加载连接配置

# Rocky 系统软件源更换
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak \
/etc/yum.repos.d/[Rr]ocky*.repo
dnf makecache

# 防火墙修改 firewalld 为 iptables
systemctl stop firewalld
systemctl disable firewalld
yum -y install iptables-services
systemctl start iptables
systemctl enable iptables


# 禁用 Selinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
grubby --update-kernel ALL --args selinux=0
# 查看是否禁用,grubby --info DEFAULT
# 回滚内核层禁用操作,grubby --update-kernel ALL --remove-args selinux

# 关闭swap分区
swapoff  -a
sed -i 's:/dev/mapper/rl-swap:#/dev/mapper/rl-swap:g' /etc/fstab

# 安装依赖文件
yum install -y conntrack ipvsadm ipset jq iptables sysstat libseccomp wget vim net-tools
yum -y install net-tools vim lrzsz wget  yum-utils telnet  unzip tar iptables-services
# 设置时区
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond

# 修改主机名
echo k8s-master > /etc/hostname
hostname k8s-minio

vim /etc/hosts
192.168.174.139 k8s-minio
安装 Docker 环境
复制代码
# 加载 bridge
yum install -y epel-release
yum install -y bridge-utils
modprobe br_netfilter
echo 'br_netfilter' >> /etc/modules-load.d/bridge.conf
echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.conf
echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.conf
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
sysctl -p


# 添加 docker-ce yum 源
# 中科大(ustc)
dnf config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
cd /etc/yum.repos.d
# 切换中科大源
sed -e 's|download.docker.com|mirrors.ustc.edu.cn/docker-ce|g' docker-ce.repo  > docker-ustc.repo
mv docker-ce.repo docker-ce.repo.bak
# 安装 docker-ce
yum -y install docker-ce
# 配置 daemon.
cat > /etc/docker/daemon.json <<EOF
{
"data-root": "/data/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "100"
},
"insecure-registries": ["harbor.xinxainghf.com"],
"registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
	"https://docker.cloudmessage.top",
	"https://kfp63jaj.mirror.aliyuncs.com",
    "https://j47dskil.mirror.aliyuncs.com"
       ]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# 重启docker服务
systemctl daemon-reload && systemctl restart docker && systemctl enable docker
docker info
reboot
安装 minio
bash 复制代码
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'
# 注释
docker run \
  --name minio \  # 给容器命名为 "minio"
  -p 9000:9000 \  # 映射容器的 9000 端口到主机的 9000 端口,用于对象存储访问
  -p 9999:9999 \  # 映射容器的 9999 端口到主机的 9999 端口,用于管理控制台访问
  -d \  # 让容器在后台运行
  --restart=always \  # 设置容器在崩溃或重启后自动重新启动
  -e "MINIO_ROOT_USER=admin" \  # 设置 MinIO 的管理员用户名为 "admin"
  -e "MINIO_ROOT_PASSWORD=12345678" \  # 设置 MinIO 的管理员密码为 "12345678"
  -v /data/minio/data:/data \  # 将主机的 /data/minio/data 目录挂载到容器的 /data 目录,持久化数据
  minio/minio:RELEASE.2022-04-12T06-55-35Z \  # 使用指定版本的 MinIO 镜像
  server /data \  # 启动 MinIO 服务器,使用 /data 目录作为数据存储位置
  --console-address '0.0.0.0:9999'  # 设置 MinIO 控制台的访问地址,监听所有网络接口的 9999 端口
复制代码
# 访问 : http://192.168.174.139:9999
admin
12345678

桶里存放各种各样的数据,每个桶绑定不同的用户,供用户访问,默认情况下所有人都可以访问

创建桶,存放velero需要备份的数据

二、初始化 velero

安装 velero 命令
复制代码
# 在 k8s 集群中 master 部署 velero
# velero 官网
https://github.com/vmware-tanzu/velero/releases  # 将velero client 下载下来,解压放置 /usr/bin
# 192.168.174.136
wget https://github.com/vmware-tanzu/velero/releases/download/v1.15.0/velero-v1.15.0-linux-amd64.tar.gz
tar -xf velero-v1.15.0-linux-amd64.tar.gz
cd velero-v1.15.0-linux-amd64
cp -rp velero  /usr/bin

velero version
安装 Velero
bash 复制代码
# 这条命令将 Velero 安装在 Kubernetes 集群中,并配置它使用 MinIO 作为备份存储。Velero 会与 AWS S3 兼容的存储(MinIO)交互进行备份操作,并且会通过 velero-auth.txt 文件提供认证信息。该命令禁用了卷快照功能,并且强制使用路径风格的 S3 URL,适用于类似 MinIO 这样的自托管 S3 兼容存储服务。

# 创建 velero 的账户密码
vim  /data/velero/velero-auth.txt
[default]
aws_access_key_id = admin
aws_secret_access_key = 12345678

# 初始化 velero
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.174.139:9000

# # 不支持 hostPath 卷
# hostPath 卷将容器的数据存储在宿主节点的文件系统中,因此它依赖于特定节点的存储。
# 当使用 Velero 备份时,它会尝试备份集群中所有的资源,但是 hostPath 卷的数据不属于 Kubernetes 集群的持久化存储,而是直接存储在物理宿主机上。这样,Velero 无法对 hostPath 卷的数据进行备份。
# 恢复时,Velero 可能会面临一个问题:无法恢复 hostPath 卷的数据到其他节点,因为数据本身并不在集群的持久存储系统中,而是在具体的宿主节点的文件系统上。

# 手动备份 hostPath 数据
# 避免在生产环境中使用 hostPath

# 注释
--kubeconfig /root/.kube/config
指定 Kubernetes 配置文件的路径(/root/.kube/config),这是 Velero 用于与 Kubernetes 集群交互的凭证文件。

install
表示进行 Velero 的安装操作。

--use-node-agent
使用 Node Agent 来管理节点上的备份和恢复操作。这个选项启用 Velero 在每个节点上运行代理,确保备份和恢复能够高效地操作节点上的数据。

--default-volumes-to-fs-backup
默认情况下,将所有卷备份为文件系统备份,而不是进行快照。启用此选项后,所有存储卷将被当作普通文件进行备份,而不使用块级快照。

--provider aws
指定备份的云存储提供商为 AWS,这意味着 Velero 会使用 AWS S3 或兼容的存储服务进行数据备份。这里配置了 AWS 的 S3 兼容存储,但可以根据实际需求进行配置。

--plugins velero/velero-plugin-for-aws:latest
使用指定的插件(velero/velero-plugin-for-aws:latest)来支持与 AWS 兼容的存储系统进行交互。此插件使Velero能够与S3兼容的存储(例如 MinIO)进行备份和恢复。

--bucket velero
指定存储桶的名称(在这里是 velero)。这是 Velero 用于存储备份的 S3 兼容存储桶名称。

--secret-file /data/velero/velero-auth.txt
指定存储桶的认证文件路径。此文件包含用于访问 AWS S3 存储桶的认证信息(例如 AWS 访问密钥和密钥 ID)。

--use-volume-snapshots=false
禁用卷快照功能。这意味着在备份期间,Velero 不会使用存储卷的快照,而是使用其他方法(如文件系统级别备份)进行备份。

--namespace velero-system
指定 Velero 安装的 Kubernetes 命名空间。在这个命令中,Velero 会被安装在 velero-system 命名空间下。

--backup-location-config
region=minio
配置备份存储的位置,并指定它使用 MinIO 存储作为备份目标。这里的 minio 是用来表示 S3 兼容的存储位置。

s3ForcePathStyle='true'
强制使用路径风格的 S3 存储 API(即存储桶名称在 URL 中作为路径的一部分)。这是为了确保与 MinIO 兼容,MinIO 使用的是路径风格的 URL,而不是域名风格的 URL。

s3Url=http://192.168.66.14:9000
指定 S3 兼容存储的 URL 地址。此处为 MinIO 服务器的地址和端口,http://192.168.66.14:9000 指的是本地部署的 MinIO 实例的地址。


# 运行结果如下:
kubectl  get pod -n velero-system
NAME                     READY   STATUS    RESTARTS   AGE
node-agent-d9q2w         1/1     Running   0          49s
node-agent-g2tjx         1/1     Running   0          49s
velero-5d4858ff6-r4g5v   1/1     Running   0          49s

# 输出为 yaml 格式
kubectl  get BackupStorageLocation -n velero-system -o yaml

三、备份还原数据

1、实验演示
复制代码
# 创建一个pod,并绑定PVC,测试在pod中创建一个文件,然后删除并恢复,且创建文件还存在

vim pod-pvc.yaml
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: wangyanglinux/myapp:v1.0
      volumeMounts:
        - name: my-persistent-storage
          mountPath: /usr/local/nginx/html
  volumes:
    - name: my-persistent-storage
      persistentVolumeClaim:
        claimName: my-pvc
 
kubectl apply -f  pod-pvc.yaml
  
kubectl  exec -it my-pod -- /bin/bash
my-pod:/# cd /usr/local/nginx/html/
my-pod:/usr/local/nginx/html# ls
hostname.html
my-pod:/usr/local/nginx/html# dd if=/dev/zero  of=1.txt bs=1MB count=100   # 创建一个100mb空文件
100+0 records in
100+0 records out
my-pod:/usr/local/nginx/html# du -sh *
95.4M	1.txt
4.0K	hostname.html
准备备份
复制代码
# 设置时间变量
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-2024-12-17-17-08-02" submitted successfully.
Run `velero backup describe default-backup-2024-12-17-17-08-02` or `velero backup logs default-backup-2024-12-17-17-08-02` for more details.

# 查看 备份信息
velero backup get -n velero-system

# 解释:
velero backup create default-backup-${DATE}
该命令创建一个 Velero 备份,备份名称为 default-backup-${DATE}

--include-namespaces default
该选项指定只备份 default 命名空间中的资源。你可以通过此选项选择一个或多个命名空间,Velero 会仅备份指定命名空间中的资源。
不指定此选项,默认备份所有

--kubeconfig=/root/.kube/config
该选项指定了 Kubernetes 配置文件的路径,指明使用的 kubeconfig 文件,通常用于非默认路径的配置文件。

--namespace velero-system
选项用于指定 Velero 使用的命名空间,即恢复过程会使用这个命名空间的配置,通常,Velero 的所有资源(如 backup, restore, pod 等)都位于这个命名空间中。

--ttl 24h0m0s(注释)
--ttl 选项用于设置备份的生存时间(TTL,Time To Live)。默认情况下,Velero 会将备份保留 30 天。如果未指定 TTL,默认的生存时间是 30 天。如果你希望备份在 24 小时后自动删除,可以使用 --ttl 24h0m0s。
刷新minio页面,已经显示数据了,点击查看

backup 保存元数据信息

Kopia 用于备份文件系统中的数据

恢复备份
复制代码
# 先将pod删除
kubectl delete -f pvc-pod.yaml 
persistentvolumeclaim "my-pvc" deleted
pod "my-pod" deleted

# 查看备份信息
velero backup get -n velero-system
NAME                                 STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
default-backup-2024-12-17-17-08-02   Completed   0        0          2024-12-17 17:08:05 +0800 CST   29d       default            <none>

# 还原
velero restore create --from-backup default-backup-2024-12-17-17-08-02  --wait --kubeconfig=/root/.kube/config --namespace velero-system
# 输出如下:
Restore request "default-backup-2024-12-17-17-08-02-20241217172733" submitted successfully.
Waiting for restore to complete. You may safely press ctrl-c to stop waiting - your restore will continue in the background.
............
Restore completed with status: Completed. You may check for more information using the commands `velero restore describe default-backup-2024-12-17-17-08-02-20241217172733` and `velero restore logs default-backup-2024-12-17-17-08-02-20241217172733`.

kubectl  get pod
NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          30s

[root@k8s-master 12-pod]# kubectl exec -it my-pod -- /bin/bash
Defaulted container "my-container" out of: my-container, restore-wait (init)
my-pod:/# ls /usr/local/nginx/html/
1.txt          hostname.html
my-pod:/# du -sh  /usr/local/nginx/html/*
95.4M	/usr/local/nginx/html/1.txt
4.0K	/usr/local/nginx/html/hostname.html
2、常用命令
复制代码
a、为与标签选择器匹配的任何对象创建备份 app=nginx    ==   备份所有命名空间中带有 app=nginx 标签的资源
# velero backup create nginx-backup --selector app=nginx --kubeconfig=/root/.kube/config --namespace velero-system

b、备份除与标签匹配的对象之外的 backup=ignore 所有对象  ==  创建一个名为 nginx-backup 的备份,备份所有标签键 backup 的值 不是 ignore 的资源。
# velero backup create nginx-backup --selector 'backup notin (ignore)' --kubeconfig=/root/.kube/config --namespace velero-system

c、定时备份数据,每分钟 备份 default 命名空间中的资源
# velero schedule create schedule-backup --schedule="* * * * *" --include-namespaces=default --default-volumes-to-fs-backup --kubeconfig=/root/.kube/config --namespace velero-system

# --include-namespaces=default
如果有多个命名空间需要备份,可以用逗号分隔多个命名空间,例如:--include-namespaces=default,kube-system.
# --default-volumes-to-fs-backup:
这是一个额外的参数,表示对于该备份任务中包含的所有持久卷(PVs),默认将它们作为文件系统备份(FS backup)。即备份这些卷的数据时,使用文件系统级别的备份方式。
如果没有这个选项,Velero 默认使用其他方式(比如使用 block 级别的备份)。

d、备份任务每天执行一次,且仅包括带有标签 app=nginx 的 Kubernetes 资源
# velero schedule create nginx-daily --schedule="@daily" --selector app=nginx  --kubeconfig=/root/.kube/config --namespace velero-system

注释:
# velero schedule create nginx-daily:
这部分表示创建一个新的备份计划任务
# --schedule="@daily"
这个参数指定了备份任务的执行频率。@daily 是一个简洁的 Cron 表达式,等价于 0 0 * * *,表示每天午夜(00:00)执行备份任务
调整执行频率。例如,@hourly 每小时执行一次备份,@weekly 每周执行一次备份。
# --selector app=nginx:
通过标签选择器(Label Selector)指定备份只包括标签 app=nginx 的资源。
如果想备份多个标签的资源,可以使用 , 连接多个标签,例如:--selector app=nginx,env=production

# 示例改进:
如果你希望备份任务同时包括 nginx 应用程序的持久卷,可以通过额外指定备份卷的选项,例如:
# velero schedule create nginx-daily --schedule="@daily" --selector app=nginx --default-volumes-to-fs-backup
这会在备份过程中同时备份相关的持久卷,并且使用文件系统级别的备份方式

四、卸载 Velero

bash 复制代码
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero
相关推荐
lichenyang4533 天前
Docker 学习笔记(四):Dockerfile,把项目打成自己的镜像
docker·容器
lichenyang4533 天前
Docker 学习笔记(三):Docker 网络、bridge、子网和容器互通
docker·容器
lichenyang4533 天前
Docker 学习笔记(二):docker run 的参数到底在控制什么?
docker·容器
运维开发故事6 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson7 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生8 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭8 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美9 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵10 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程