镜像备份参考
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
- mountPath: /etc/localtime
name: host-time
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
- hostPath:
path: /etc/localtime
type: ''
name: host-time
schedule: 0 1 * * *
successfulJobsHistoryLimit: 1
suspend: false
数据库备份到NFS
---
apiVersion: v1
data:
backup.sh: >
#!/usr/bin/env bash
echo "========begin========"
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 -e "show databases" | grep -Ev "Database|sys|information_schema|performance_schema|mysql")
for db in $DATABASES; do
if [[ "$db" == *"+"* ]] || [[ "$db" == *"|"* ]]; then
echo "$(date) [info] Jumping over database: $db"
else
echo "$(date) [info] Backuping ${db} ......"
mysqldump --default-character-set=utf8 -q --lock-all-tables --flush-logs -E -R --triggers -B "$db" | gzip > "$BACKUP_FILEDIR/${db}_$DATE.sql.gz"
echo "$(date) [info] Completed backup to $BACKUP_FILEDIR/${db}_$DATE.sql.gz"
echo ""
fi
done
count=$(find "$BACKUP_ROOT" -maxdepth 1 -type f -name "*.gz" | wc -l)
if [[ $count -gt $BACKUP_NUMBER ]]; then
delfile=$(find "$BACKUP_ROOT" -maxdepth 1 -type f -name "*.gz" | sort | head -n 1)
rm -f "$delfile"
echo "Deleted old backup file: $delfile" >> "$BACKUP_ROOT/log.txt"
fi
echo "========end========"
my.cnf: |-
[client]
socket=/var/lib/mysql/mysql.sock
default-character-set=utf8mb4
host=mysql
port=3306
user=root
password='密码'
[mysqldump]
quick
max_allowed_packet=500M
kind: ConfigMap
metadata:
name: pai-database-backup-conf
namespace: pai-cloud
---
apiVersion: batch/v1
kind: CronJob
metadata:
annotations:
k8s.kuboard.cn/displayName: 数据库定时备份
labels:
app: pai-database-backup
name: pai-database-backup
namespace: pai-cloud
spec:
concurrencyPolicy: Forbid
failedJobsHistoryLimit: 1
jobTemplate:
metadata:
labels:
app: pai-database-backup
spec:
backoffLimit: 1
template:
spec:
containers:
- command:
- bash
- /home/backup.sh
image: 'dev.flyrise.cn:8082/library/mysql:8.0.30'
imagePullPolicy: IfNotPresent
name: pai-database-backup
volumeMounts:
- mountPath: /etc/localtime
name: host-time
- mountPath: /home/backup.sh
name: sh
subPath: backup.sh
- mountPath: /etc/my.cnf
name: my-cnf
subPath: my.cnf
- mountPath: /data
name: backup
restartPolicy: Never
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /etc/localtime
type: ''
name: host-time
- configMap:
defaultMode: 511
name: pai-database-backup-conf
name: sh
- configMap:
defaultMode: 420
name: pai-database-backup-conf
name: my-cnf
- name: backup
nfs:
path: /data/nfs/mysql-backup
server: 127.0.0.1
schedule: 0 1 * * *
successfulJobsHistoryLimit: 1
suspend: false
文档更新时间: 2025-01-03 16:58 作者:姚连洲