【模块一】kubernetes容器编排进阶实战之基于velero及minio实现etcd数据备份与恢复
基于velero及minio实现etcd数据备份与恢复
Velero简介及minio环境准备
Velero简介:
-
Velero 是vmware开源的一个云原生的灾难恢复和迁移工具,它本身也是开源的,采用Go语言编写,可以安全的备份、恢复和迁移 Kubernetes集群资源数据,Velero。
-
Velero 是西班牙语意思是帆船,非常符合Kubernetes社区的命名风格,Velero的开发公司Heptio,已被VMware收购。
-
Velero 支持标准的K8S集群,既可以是私有云平台也可以是公有云,除了灾备之外它还能做资源移转,支持把容器应用从一个集群 迁移到另一个集群。
-
Velero 的工作方式就是把kubernetes中的数据备份到对象存储以实现高可用和持久化,默认的备份保存时间为720小时,并在需要 的时候进行下载和恢复。
Velero与etcd快照备份的区别
-
etcd 快照是全局完成备份(类似于MySQL全部备份),即使需要恢复一个资源对象(类似于只恢复MySQL的一个库),但是也需要做全局恢复到备份的状态 (类似于MySQL的全库恢复),即会影响其它namespace中pod运行服务(类似于会影响MySQL其它数据库的数据)。
-
Velero可以有针对性的备份,比如按照namespace单独备份、只备份单独的资源对象等,在恢复的时候可以根据备份只恢复单独namespace或资源对象,而不影响其它namespace中pod运行服务。
-
velero支持ceph、oss等对象存储,etcd 快照是一个为本地文件。
-
velero支持任务计划实现周期备份,但etcd 快照也可以基于cronjob实现。
-
velero支持对AWS EBS创建快照及还原
https://www.qloudx.com/velero-for-kubernetes-backup-restore-stateful-workloads-with-aws-ebs-snapshots/
https://github.com/vmware-tanzu/velero-plugin-for-aws #Elastic Block Store
velero整体架构:
备份流程
#命令
velero backup create myserver-ns-backup-${DATE} --include-namespaces myserver --kubeconfig=./awsuser.kubeconfig --namespace velero-system
-
Velero 客户端调用Kubernetes API Server创建Backup任务。
-
Backup 控制器基于watch 机制通过API Server获取到备份任务。
-
Backup 控制器开始执行备份动作,其会通过请求API Server获取需要备份的数据。
-
Backup 控制器将获取到的数据备份到指定的对象存储server端。
部署环境:
部署minio:
创建数据目录:
[root@k8s-deploy]#docker pull minio/minio:RELEASE.2022-04-12T06-55-35Z
[root@k8s-deploy]#mkdir -p /data/minio
#创建minio容器,如果不指定,则默认用户名与密码为 minioadmin/minioadmin,可以通过环境变量自定义,如下
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 web界面登录
-
访问ip:9999
minio 创建bucket:
-
bucket 名称:velerodata,后期会使用
minio 验证bucket:
部署velero:
-
在master节点部署velero:
-
https://github.com/vmware-tanzu/velero #版本兼容性
-
具体步骤见 部署velero.txt
-
部署velero:
root@k8s-master1:/usr/local/src# wget https://github.com/vmware-tanzu/velero/releases/download/v1.11.0/velero-v1.11.0-linux-amd64.tar.gz
root@k8s-master1:/usr/local/src# tar xvf velero-v1.11.0-linux-amd64.tar.gz
root@k8s-master1:/usr/local/src# cp velero-v1.11.0-linux-amd64/velero /usr/local/bin/
root@k8s-master1:/usr/local/src# velero --help
配置velero认证环境:
#工作目录:
root@k8s-master1:~# mkdir /data/velero -p
root@k8s-master1:~# cd /data/velero
root@k8s-master1:/data/velero#
#访问minio的认证文件:
root@k8s-master1:/data/velero# vim velero-auth.txt
[default]
aws_access_key_id = admin
aws_secret_access_key = 12345678
#准备user-csr文件:
root@k8s-master1:/data/velero# vim awsuser-csr.json
{
"CN": "awsuser",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
#准备证书签发环境:
root@k8s-master1:/data/velero# apt install golang-cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl-certinfo_1.6.1_linux_amd64
root@k8s-master1:/data/velero# mv cfssl-certinfo_1.6.1_linux_amd64 cfssl-certinfo
root@k8s-master1:/data/velero# mv cfssl_1.6.1_linux_amd64 cfssl
root@k8s-master1:/data/velero# mv cfssljson_1.6.1_linux_amd64 cfssljson
root@k8s-master1:/data/velero# cp cfssl-certinfo cfssl cfssljson /usr/local/bin/
root@k8s-master1:/data/velero# chmod a+x /usr/local/bin/cfssl*
#执行证书签:
>= 1.24.x:
root@k8s-deploy:~# scp /etc/kubeasz/clusters/k8s-cluster1/ssl/ca-config.json 172.31.7.101:/data/velero
root@k8s-master1:/data/velero# /usr/local/bin/cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem -ca-key=/etc/kubernetes/ssl/ca-key.pem -config=./ca-config.json -profile=kubernetes ./awsuser-csr.json | cfssljson -bare awsuser
1.23 <=
root@k8s-master1:/data/velero# /usr/local/bin/cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem -ca-key=/etc/kubernetes/ssl/ca-key.pem -config=/etc/kubeasz/clusters/k8s-cluster1/ssl/ca-config.json -profile=kubernetes ./awsuser-csr.json | cfssljson -bare awsuser
#验证证书:
root@k8s-master1:/data/velero# ll awsuser*
-rw-r--r-- 1 root root 220 Apr 14 12:29 awsuser-csr.json
-rw------- 1 root root 1679 Apr 14 12:30 awsuser-key.pem
-rw-r--r-- 1 root root 997 Apr 14 12:30 awsuser.csr
-rw-r--r-- 1 root root 1387 Apr 14 12:30 awsuser.pem
#分发证书到api-server证书路径:
root@k8s-master1:/data/velero# cp awsuser-key.pem /etc/kubernetes/ssl/
root@k8s-master1:/data/velero# cp awsuser.pem /etc/kubernetes/ssl/
#生成集群认证config文件:
# export KUBE_APISERVER="https://10.0.0.188:6443"
# kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=./awsuser.kubeconfig
#设置客户端证书认证:
# kubectl config set-credentials awsuser \
--client-certificate=/etc/kubernetes/ssl/awsuser.pem \
--client-key=/etc/kubernetes/ssl/awsuser-key.pem \
--embed-certs=true \
--kubeconfig=./awsuser.kubeconfig
#设置上下文参数:
# kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=awsuser \
--namespace=velero-system \
--kubeconfig=./awsuser.kubeconfig
#设置默认上下文:
# kubectl config use-context kubernetes --kubeconfig=awsuser.kubeconfig
#k8s集群中创建awsuser账户:
# kubectl create clusterrolebinding awsuser --clusterrole=cluster-admin --user=awsuser
#创建namespace:
# kubectl create ns velero-system
# 执行安装:
velero --kubeconfig ./awsuser.kubeconfig \
install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.5.5 \
--bucket velerodata \
--secret-file ./velero-auth.txt \
--use-volume-snapshots=false \
--namespace velero-system \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://172.31.7.110(minio的ip):9000
#验证安装:
root@k8s-master1:/data/velero# kubectl get pod -n velero-system
root@k8s-master1:/data/velero# kubectl get pod -n velero-system -o wide
root@k8s-node2:~# nerdctl pull velero/velero-plugin-for-aws:v1.5.5
root@k8s-node2:~# nerdctl pull velero/velero:v1.11.0
root@k8s-master1:/data/velero# kubectl get pod -n velero-system
NAME READY STATUS RESTARTS AGE
velero-98bc8c975-q6c5d 1/1 Running 0 2m36s
对default ns进行备份
-
velero backup create default-backup-${DATE}: 这部分命令用于创建一个新的备份。default-backup-${DATE} 是备份的名称,其中 ${DATE} 应该是一个环境变量或者替换为实际的日期值,用于区分不同的备份。
-
--include-cluster-resources=true: 这个选项表示备份将包括集群范围的资源,如 CRDs(自定义资源定义)、集群角色和集群角色绑定等。这对于确保备份包含所有重要的集群级配置非常有用。
-
--include-namespaces default: 这个选项指定了要包含在备份中的命名空间。在这个例子中,只有 default 命名空间会被备份。如果你想要备份多个命名空间,可以用逗号分隔它们,或者使用 --all-namespaces 来备份所有命名空间。
-
--kubeconfig=./awsuser.kubeconfig: 这个选项指定了 kubeconfig 文件的路径,Velero 使用这个文件来访问 Kubernetes 集群。./awsuser.kubeconfig 是 kubeconfig 文件的路径,它应该包含访问集群所需的认证信息。这个文件通常用于配置访问 Kubernetes 集群的客户端。
-
--namespace velero-system: 这个选项指定了 Velero 部署所在的命名空间。在这个例子中,Velero 被部署在 velero-system 命名空间中。这是 Velero 默认的安装命名空间,但根据你的安装配置,它可能会有所不同
总结来说,这条命令创建了一个名为 default-backup-${DATE}
的备份,它包括了集群范围的资源以及 default
命名空间中的资源,使用了指定的 kubeconfig 文件来访问 Kubernetes 集群,并且假定 Velero 被部署在 velero-system
命名空间中。
对default ns进行备份:
root@k8s-master1:/data/velero# pwd
/data/velero
root@k8s-master1:/data/velero# DATE=`date +%Y%m%d%H%M%S`
root@k8s-master1:/data/velero# velero backup create default-backup-${DATE} \
--include-cluster-resources=true \
--include-namespaces default \
--kubeconfig=./awsuser.kubeconfig \
--namespace velero-system
#验证备份:
root@k8s-master1:/data/velero# velero backup describe default-backup-20230505160307 --kubeconfig=./awsuser.kubeconfig --namespace velero-system
minio验证备份数据
删除pod并验证数据恢复
#删除pod:
root@k8s-master1:/data/velero# kubectl delete pod net-test1 -n default
pod "net-test1" deleted
#恢复pod:
root@k8s-master1:/data/velero# velero restore create --from-backup default-backup-20230505160307 --wait --kubeconfig=./awsuser.kubeconfig --namespace velero-system
#验证pod:
root@k8s-master1:/data/velero# kubectl get pod -o wide
root@k8s-master1:/data/velero# kubectl exec -it net-test1 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@net-test1 /]# ping www.jd.com
PING wwwv6.jcloudimg.com (111.31.22.3) 56(84) bytes of data.
64 bytes from 111.31.22.3 (111.31.22.3): icmp_seq=1 ttl=127 time=32.4 ms
64 bytes from 111.31.22.3 (111.31.22.3): icmp_seq=2 ttl=127 time=36.4 ms
对myserver ns进行备份
对myserver ns进行备份:
root@k8s-master1:/data/velero# pwd
/data/velero
root@k8s-master1:/data/velero# DATE=`date +%Y%m%d%H%M%S`
root@k8s-master1:/data/velero# velero backup create myserver-ns-backup-${DATE} \
--include-cluster-resources=true \
--include-namespaces myserver \
--kubeconfig=/root/.kube/config \
--namespace velero-system
Backup request "myserver-ns-backup-20241220123348" submitted successfully.
Run `velero backup describe myserver-ns-backup-20241220123348` or `velero backup logs myserver-ns-backup-20241220123348` for more details.
velero backup create myserver-ns-backup-${DATE} --include-cluster-resources=true --include-namespaces myserver --kubeconfig=/root/.kube/config --namespace velero-system
删除pod并验证恢复
root@k8s-master1:/data/velero# kubectl delete deployment myserver-tomcat-app1-deployment -n myserver
deployment.apps "myserver-tomcat-app1-deployment" deleted
root@k8s-master1:/data/velero# kubectl delete service myserver-tomcat-app1-service -n myserver
service "myserver-tomcat-app1-service" deleted
root@k8s-master1:/data/velero# velero restore create --from-backup myserver-ns-backup-20241220123348 --wait \
--kubeconfig=./awsuser.kubeconfig \
--namespace velero-system
备份指定资源对象
#备份指定namespace中的pod或特定资源:
root@k8s-master1:/data/velero# kubectl run net-test1 --image=centos:7.9.2009 sleep 10000000000 -n myserverroot@k8s-master1:/data/velero# kubectl get pod -n myserver
root@k8s-master1:/data/velero# velero backup create pod-backup-202207222335 --include-cluster-resources=true --ordered-resources 'pods=myserver/net-test1,defafut/net-test1' --namespace velero-system --include-namespaces=myserver,defafut
删除pod并验证恢复:
#删除deployment控制器并验证恢复:
root@k8s-master1:/data/velero# kubectl delete -f /root/nginx-tomcat-case/tomcat.yaml
root@k8s-master1:/data/velero# kubectl get pod -n myserver
root@k8s-master1:/data/velero# velero restore create --from-backup pod-backup-202305051635 --wait \
--kubeconfig=./awsuser.kubeconfig \
--namespace velero-system
批量备份所有namespace:
#批量备份不同的namespace:
root@k8s-master1:~# cat /data/velero/ns-back.sh
#!/bin/bash
NS_NAME=`kubectl get ns | awk '{if (NR>2){print}}' | awk '{print $1}'`
DATE=`date +%Y%m%d%H%M%S`
cd /data/velero/
for i in $NS_NAME;do
velero backup create ${i}-ns-backup-${DATE} \
--include-cluster-resources=true \
--include-namespaces ${i} \
--kubeconfig=/root/.kube/config \
--namespace velero-system
done
root@k8s-master1:~# bash /data/velero/ns-back.sh