镜像备份参考
1、提前准备好备份镜像存放地方
2、根据实际情况使用K8S定时任务还是Linux定时任务
3、根据实际节点数量进行备份
备份脚本
docker 方式
ConfigMap
apiVersion: v1
data:
backup.sh: |-
#!/usr/bin/env sh
# 如果不存在 images 目录,则创建
[ -d ./images ] || mkdir ./images
# 获取所有的 Docker 镜像列表,排除 REPOSITORY、rancher 和 <none> 的条目
docker images | grep -v REPOSITORY | grep -v rancher | grep -v "<none>" | while read -r line; do
# 获取镜像名和版本号
name=$(echo "$line" | awk '{print $1}')
version=$(echo "$line" | awk '{print $2}')
# 生成镜像文件名
filename="${name##*/}-$version.tar"
# 检查镜像文件是否已存在
if [ -f "./images/$filename" ]; then
echo "跳过:$filename"
else
echo "导出:$name:$version 为 ./images/$filename"
docker save -o "./images/$filename" "$name:$version"
fi
done
kind: ConfigMap
metadata:
name: pai-image-backup-conf
namespace: pai-cloud
containerd 方式
ConfigMap
apiVersion: v1
data:
backup.sh: |-
#!/usr/bin/env sh
# 如果不存在 images 目录,则创建
[ -d ./images ] || mkdir ./images
# 获取所有的 Docker 镜像列表,排除 REPOSITORY、rancher 和 <none> 的条目
crictl images | grep -v IMAGE | grep -v rancher | grep -v "<none>" | while read -r line; do
# 获取镜像名和版本号
name=$(echo "$line" | awk '{print $1}')
version=$(echo "$line" | awk '{print $2}')
# 生成镜像文件名
filename="${name##*/}-$version.tar"
# 检查镜像文件是否已存在
if [ -f "./images/$filename" ]; then
echo "跳过:$filename"
else
echo "导出:$name:$version 为 ./images/$filename"
ctr -n k8s.io i export "./images/$filename" "$name:$version"
fi
done
kind: ConfigMap
metadata:
name: pai-image-backup-conf
namespace: pai-cloud
定时任务
工作负载
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
k8s.kuboard.cn/displayName: 镜像备份
labels:
k8s.kuboard.cn/name: pai-image-backup
name: pai-image-backup
namespace: pai-cloud
spec:
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
metadata:
creationTimestamp: null
labels:
k8s.kuboard.cn/name: pai-image-backup
spec:
backoffLimit: 1
template:
metadata:
creationTimestamp: null
spec:
containers:
- command:
- sh
- /home/backup.sh
image: 'centos:centos7.9.2009'
imagePullPolicy: IfNotPresent
name: pai-image-backup
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: volume-backup
- mountPath: /home/backup.sh
name: volume-sh
subPath: backup.sh
- mountPath: /etc/localtime
name: host-time
- mountPath: /usr/bin/docker
name: docker
- mountPath: /var/run/
name: dockersock
dnsPolicy: ClusterFirst
restartPolicy: Never
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: volume-backup
nfs:
path: /data/sdb/nfs/imagebackup
server: 192.168.1.100
- configMap:
defaultMode: 420
name: pai-image-backup-conf
name: volume-sh
- hostPath:
path: /etc/localtime
type: ''
name: host-time
- hostPath:
path: /usr/bin/docker
type: File
name: docker
- hostPath:
path: /var/run/
type: Directory
name: dockersock
schedule: 0 2 * * *
successfulJobsHistoryLimit: 3
suspend: false
Kubernets ETCD 数据库备份
可用于集群环境异常时偿试恢复,备份命令如下:
sealos etcd save --name etcd-202310250830.bak
# 默认输出在/opt/sealos/etcd-backup目录下
注意:备份出来的文件存放在安全的异地空间
定时yaml备份到NFS
---
apiVersion: v1
data:
backup.sh: |-
#!/bin/bash
# Set the base directory for storing the backups
base_dir="/data"
log_dir="$base_dir/$(date +'%Y-%m-%d')"
echo "Create the directory $log_dir if it doesn't exist"
mkdir -p $log_dir
echo Backup the deployments
kubectl get deploy -n pai-cloud -oyaml > "$log_dir/deployment.yaml"
echo Backup the services
kubectl get svc -oyaml -n pai-cloud > "$log_dir/service.yaml"
echo Backup the ingresses
kubectl get ing -oyaml -n pai-cloud > "$log_dir/ingress.yaml"
echo Backup the configmaps
kubectl get configmap -n pai-cloud -oyaml > "$log_dir/configmap.yaml"
echo Delete backups older than 1 month
find $base_dir -mindepth 1 -type d -mtime +30 -exec rm -rf {} \;
kind: ConfigMap
metadata:
name: pai-yaml-backup-conf
namespace: pai-cloud
---
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
k8s.kuboard.cn/displayName: 工作负载定时备份
labels:
k8s.kuboard.cn/name: pai-yaml-backup
name: pai-yaml-backup
namespace: pai-cloud
spec:
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
metadata:
labels:
k8s.kuboard.cn/name: pai-yaml-backup
spec:
backoffLimit: 1
template:
spec:
containers:
- command:
- sh
- /home/backup.sh
image: busybox
imagePullPolicy: IfNotPresent
name: pai-yaml-backup
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /home/backup.sh
name: volume-sh
subPath: backup.sh
- mountPath: /data
name: volume-data
- mountPath: /usr/bin/kubectl
name: volume-kubectl
- mountPath: /root/.kube/config
name: volume-config
dnsPolicy: ClusterFirst
hostAliases:
- hostnames:
- apiserver.cluster.local
ip: 192.168.10.2
nodeName: k8s-master-1
restartPolicy: Never
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
items:
- key: backup.sh
path: backup.sh
name: pai-yaml-backup-conf
name: volume-sh
- name: volume-data
nfs:
path: /data/nfs/yaml
server: 192.168.10.34
- hostPath:
path: /usr/bin/kubectl
type: File
name: volume-kubectl
- hostPath:
path: /root/.kube/config
type: File
name: volume-config
schedule: 0 1 * * *
successfulJobsHistoryLimit: 1
suspend: false
数据库备份到NFS
---
apiVersion: v1
data:
backup.sh: >-
#!/usr/bin/env bash
#保存数量
BACKUP_NUMBER=30
#当前日期
DATE=$(date +%Y-%m-%d)
BACKUP_ROOT=/data
if [ ! -n $BACKUP_PATH ] ; then
BACKUP_ROOT=$BACKUP_PATH
fi
BACKUP_FILEDIR=$BACKUP_ROOT/$DATE
#如果文件夹不存在则创建
if [ ! -d $BACKUP_FILEDIR ] ; then
mkdir -p $BACKUP_FILEDIR;
fi
#查询所有数据库
DATABASES=$(mysql -h$DATABASE_HOST -u$DATABASE_USER -p"$DATABASE_PASSWORD"
-P$DATABASE_PORT -e "show databases" | grep -Ev
"Database|sys|information_schema|performance_schema|mysql")
#循环数据库进行备份
for db in $DATABASES
do
echo
if [[ "${db}" =~ "+" ]] || [[ "${db}" =~ "|" ]];then
echo "jump over ${db}"
else
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz $(date) BEGIN----------
mysqldump -h$DATABASE_HOST -u$DATABASE_USER -p"$DATABASE_PASSWORD" -P$DATABASE_PORT --default-character-set=utf8 -q --lock-all-tables --flush-logs -E -R --triggers -B ${db} | gzip > $BACKUP_FILEDIR/${db}_$DATE.sql.gz
echo ${db}
echo ----------$BACKUP_FILEDIR/${db}_$DATE.sql.gz $(date) COMPLETE----------
echo
fi
done
#找出需要删除的备份
delfile=`ls -l -crt $BACKUP_ROOT | awk '{print $9 }' | grep "-" | head -1`
#判断现在的备份数量是否大于$BACKUP_NUMBER
count=`ls -l -crt $BACKUP_ROOT | awk '{print $9 }' | grep "-" | wc -l`
if [ $count -gt $BACKUP_NUMBER ] ; then
#删除最早生成的备份,只保留BACKUP_NUMBER数量的备份
rm -rf $BACKUP_ROOT/$delfile
#写删除文件日志
echo "delete $delfile" >> $BACKUP_ROOT/log.txt
fi
kind: ConfigMap
metadata:
name: pai-database-backup-conf
namespace: pai-cloud
---
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
k8s.kuboard.cn/displayName: 数据库定时备份
labels:
k8s.kuboard.cn/name: pai-database-backup
name: pai-database-backup
namespace: pai-cloud
spec:
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
metadata:
labels:
k8s.kuboard.cn/name: pai-database-backup
spec:
backoffLimit: 1
template:
metadata:
creationTimestamp: null
spec:
containers:
- command:
- bash
- /home/backup.sh
env:
- name: DATABASE_HOST
value: 192.168.10.21
- name: DATABASE_USER
value: root
- name: DATABASE_PORT
value: '3306'
- name: DATABASE_PASSWORD
value: BHYG@root987
image: 'mysql:8.0.30'
imagePullPolicy: IfNotPresent
name: pai-database-backup
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/localtime
name: host-time
- mountPath: /home/backup.sh
name: sh
subPath: backup.sh
- mountPath: /data
name: backup
dnsPolicy: ClusterFirst
nodeName: k8s-master-1
restartPolicy: Never
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /etc/localtime
type: ''
name: host-time
- configMap:
defaultMode: 420
items:
- key: backup.sh
path: backup.sh
name: pai-database-backup-conf
name: sh
- name: backup
nfs:
path: /data/nfs/mysql
server: 192.168.10.34
schedule: 0 1 * * *
successfulJobsHistoryLimit: 1
suspend: false
文档更新时间: 2024-09-02 13:22 作者:姚连洲