Docker/Podman容器自动备份镜像文件脚本教程LinuxServer虚拟化

印迹发布于:2021-12-4 621

一、Docker备份脚本

1、现有容器如下

[root@docker-manager1 overlay]# docker ps

CONTAINER ID   IMAGE             COMMAND                  CREATED      STATUS      PORTS                                                                                         NAMES
3d0b5848dec1   pmsoftware:v3     "bash -c 'sh /opt/..."   3 years ago  Up 5 hours  22/tcp, 139/tcp, 445/tcp, 8081/tcp, 10086/tcp, 0.0.0.0:8085->80/tcp, 0.0.0.0:3506->3306/tcp   PMSoftware

2、通过如下脚本对容器备份为镜像,如果容器出现问题可以随时通过镜像恢复

[root@docker-manager1 overlay]# cat /root/crond_script/docker_backup.sh


#! /bin/bash
# crond script for docker container backup
date_time=`date`
container_name=$1
echo "Start backup with name ${container_name} at ${date_time}"
if [[ $1 == "" ]];then
    echo "Not params found! Exit!"
    exit 0
fi
## fetch container used image name ## 
container_tag=`docker ps -a | grep ${container_name} | awk -F ' ' '{print $2}'`
#container_id=`docker ps -a | grep ${container_name} | awk -F ' ' '{print $1}'`
echo container_tag ${container_tag}
version=`echo ${container_tag} | awk -F ':' '{print $2}'`
version_name=`echo ${container_tag} | awk -F ':' '{print $1}'`
# Now used images version number
currtent_version_num=`echo ${version} | grep -o "[0-9]\+"`
echo "Now docker container used image is ${version_name}:v${currtent_version_num}"
# the latest backup images version number
latest_version_num=`docker images | grep ${version_name} | head -1 | awk -F ' ' '{print $2} ' | grep -o '[0-9]\+'`
# check last images backup
new_num=`expr ${latest_version_num} + 1`
# reset number of new images if current backup number great than 20
if [[ ${new_num} > 20 ]];then
    new_num=`expr ${currtent_version_num} + 1`
fi
flag=`docker images | grep ${version_name} | grep v${latest_version_num}`
if [[ $? == 0 ]];then
        docker rmi ${version_name}:v${latest_version_num}
        echo "Deleting ${version_name}:v${latest_version_num}...."
else
    echo "Not such images found!"
fi
echo "Creating new images ${version_name}:v${new_num}"
docker commit ${container_name} ${version_name}:v${new_num}
if [[ $? == 0 ]];then
    echo "Backup successfully!"
else
    echo "Backup failed!"
fi

3、生成的镜像如下

[root@docker-manager1 overlay]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
pmsoftware                           v4                  937e9fc0e7a6        6 months ago        64.5GB

4、设置定时任务,周期性执行备份动作

[root@docker-manager1 overlay]# crontab -l
0 2 * * 7 /usr/bin/sh /root/crond_script/docker_backup.sh PMSoftware >> /root/crond_script/logs/docker_backup.log


容器备份脚本(实用)
#!/bin/bash
podman rmi wiki_app_$(date -d -3day +%Y%m%d)
echo "删除3天前的旧数据:deleted wiki_app_$(date -d -3day +%Y%m%d),开始备份Wiki容器至镜像:"
podman commit -p de9573cf1c9b wiki_app_$(date +%Y%m%d)
echo "容器成功导出至镜像!开始导出镜像到本地:"
podman save wiki_app_$(date +%Y%m%d) -o wiki_app_$(date +%Y%m%d).tar
echo "已导出至宿主机root文件夹下;开始删除7天前ROOT文件夹的备份数据:"
rm -f /root/wiki_app_$(date -d -7day +%Y%m%d).tar
echo "完成。"

本地备份恢复至镜像:

podman load -i ~/container-backup.tar
二、定时脚本相关

1.在服务器下载安装crontab

yum -y install vixie-cron
yum -y install crontabs

2.编写 shell脚本

#!/bin/bash
#:set fileformat=unix
docker exec -i 容器名称  bash<<'EOF'
if [ ! -d "备份路径" ];then
  mkdir -p 备份路径
fi
mysqldump -u账号 -p密码  数据库名称 > 
备份路径/数据库名称_$(date +%Y%m%d).sql
#删除超过10天的数据
rm -f 备份路径/数据库名称_$(date -d -3day +%Y%m%d).sql
exit
EOF
# 判断目录是不是已经存在,如果不存在则创建
if [ ! -d "备份路径" ];then
  mkdir -p 备份路径
fi
# 将docker中的备份的数据拷贝到宿主机上。
docker cp 容器名称:备份路径/数据库名称_$(date +%Y%m%d).sql 备份路径
#删除超过10天的数据
rm -f 备份路径/数据库名称_$(date -d -3day +%Y%m%d).sql

3. chmod 700  脚本.sh #给予权限

chmod 700 xxxx.sh

4.--如果是通过文件上传的服务器,在服务器上下载一个 需要格式化

1,yum install dos2unix -y
2,dos2unix 文件名.sh

5.增加定时任务

crontab -uroot -e 
1 0 * * *  脚本路径/脚本名称.sh   每天凌晨12点01分执行

 6.重启服务

service crond restart

更多定时任务解析:

https://www.cnblogs.com/joingyb/p/11461522.html
三、快递批量备份Docker镜像

在生产或测试环境中,我们有时候经常需要备份一些docker镜像,如果docker镜像有成千上百个,手动备份工作量就会很巨大,可以写一个备份脚本,实现批量自动备份。

需求:备份的文件名称需要以镜像名+标签方式命名

1.思路分析

我们可以根据下图分析备份方式

绿框是镜像名称,有写镜像名称很长带着多级目录,我们可以通过awk取出最后一个字符串,最后一字符串一定是镜像名的唯一标识

篮筐一列是镜像的版本号,通过awk取出,可以作为文件镜像备份的名称,例如nginx-latest.tar.gz

红框中是镜像的ID号,我们备份的时候可以直接指定ID进行备份

当字段信息取出后,可以将取值命令定义成数组变量,然后通过for循环遍历数组,遍历后字段信息直接就可以互相关联,最终实现批量备份

2.命令实现

1)取出镜像名称

切记awk过滤字段后会把列名也带上,需要使用tail将其去掉

docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $3}'

2)取出镜像名称

docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $1}' | awk -F/ '{print $NF}'

3)取出标签

docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 | awk '{print $2}'

4)定义关联数组

declare image_id=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $3}'`)
declare image_name=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $1}' | awk -F/ '{print $NF}'`)
declare image_version=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 | awk '{print $2}'`)

4)遍历数组

只需要遍历其中一个关联数组,获取数组索引值,就能对所有数组进行遍历,因为三个数组的索引数是一致的,且顺序也是一种,这样才能做到镜像名和标签名一一对应,实现批量备份

for i in ${!image_id[@]}
do
   docker save ${image_id[i]} > ${image_name[i]}_${image_version[i]}.tar.gz
done

3.整合脚本实现批量备份docker镜像

为了输出好看增加了字体颜色变量以及备份成功过后输出提示信息

#!/bin/bash
GREEN_COLOR='\e[032m'   #绿     
RED_COLOR='\e[031m'     #红
YELLOW_COLOR='\e[033m'  #黄
BLACK_COLOR='\e[0m'     #黑
declare image_id=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $3}'`)
declare image_name=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $1}' | awk -F/ '{print $NF}'`)
declare image_version=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 | awk '{print $2}'`)
declare image_nameqc=(`docker images | grep -Ev '^k8s|^harbor|^rancher' | tail -20 |  awk '{print $1}'`)
for i in ${!image_id[@]}
do
        docker save ${image_id[i]} > ${image_name[i]}_${image_version[i]}.tar.gz
        if [ $? -eq 0 ];then
                echo -e "${YELLOW_COLOR}${image_id[i]} ${BLACK_COLOR} in ${YELLOW_COLOR} ${image_nameqc[i]} ${BLACK_COLOR} =====> ${GREEN_COLOR}back finish!!!${BLACK_COLOR} =====> back file is ${RED_COLOR} ${image_name[i]}_${image_version[i]}.tar.gz ${BLACK_COLOR}"
                echo ""
        fi
done


批量导出导出所有镜像

1.批量导出所有镜像到当前目录下

导出 文件命名为:node_images.tar

docker save $(docker images | grep -v REPOSITORY | awk ‘BEGIN{OFS=":";ORS=" "}{print $1,$2}’) -o node_images.tar

2.导入批量打包好的镜像

将上一步导出的文件上传到服务器上,执行下面命令导入 node_images.tar

docker load -i node_images.tar

————————————————

其它相关信息

1、Crontab:Linux定时任务命令详解

2、rclone使用介绍

3、Docker容器的备份、恢复和迁移

更多相关:DockerPodman


http://www.virplus.com/thread-1438.htm
转载请注明:2021-12-4 于 VirPlus 发表

推荐阅读
最新回复 (0)

    ( 登录 ) 后,可以发表评论!

    返回