镜像备份参考

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   作者:姚连洲