1. 博客/

批量export Docker镜像脚本

·395 字·2 分钟
Docker

背景
#

公司容器管理平台需要周期性对weblogic镜像进行打补丁升级操作,由于docker的分层管理机制,weblogic镜像体积会越来越大,影响后续的维护部署。我就写了一个批量export镜像并推送至镜像仓库的脚本,来精简镜像大小

脚本运行示例
#

1533196232151

脚本执行步骤
#

  1. 准备镜像列表文件

    $ cat images_list.txt                                                 <-- 需要export的镜像
    registry:8088/nginx:latest
    registry:8088/kubernetes-dashboard-amd64:v1.5.0
    
    #export之前镜像仓库中的镜像tag
    $ curl registry:8088/v2/nginx/tags/list
    {"name":"nginx","tags":["latest"]}
    $ curl registry:8088/v2/kubernetes-dashboard-amd64/tags/list
    {"name":"kubernetes-dashboard-amd64","tags":["v1.5.0"]}
    
  2. 运行脚本

    $ sh export-images.sh -h
    -------------------------------------------------------------------------
    Usage:
            export_images.sh -f IMAGES_FILE -t IMAGE_TAG [-p THREAD_NUM] [-h]
    Description:
            IMAGES_FILE: the list of images need to be exported
            IMAGE_TAG: the target tag of exported images
            THREAD_NUM: the target thread numbers
    -------------------------------------------------------------------------
    
    $ sh export-images.sh -f images_list.txt -t test -p 2
    开始执行任务
    registry:8088/kubernetes-dashboard-amd64:test pushed
    registry:8088/nginx:test pushed
    任务执行结束
    
    #export之后镜像仓库中的镜像tag,增加了test
    $ curl registry:8088/v2/nginx/tags/list                     
    {"name":"nginx","tags":["latest","test"]}
    $ curl registry:8088/v2/kubernetes-dashboard-amd64/tags/list
    {"name":"kubernetes-dashboard-amd64","tags":["v1.5.0","test"]}
    
  3. 查看脚本运行日志

    $ cat export_images.log  
    Trying to pull repository registry:8088/kubernetes-dashboard-amd64 ... 
    v1.5.0: Pulling from registry:8088/kubernetes-dashboard-amd64
    Digest: sha256:ddd3454819c089517b434a3ea42abf3c184fce9bf45704abf22513082d900eba
    Status: Image is up to date for registry:8088/kubernetes-dashboard-amd64:v1.5.0
    .....中间省略.....
    Sending build context to Docker daemon 2.048 kB
    Step 1/5 : FROM registry:8088/kubernetes-dashboard-amd64:tmp
     ---> 17b601e3c483
    .....中间省略.....
    Successfully built 8712115d0f0b
    Login Succeeded
    The push refers to a repository [registry:8088/nginx]
    .....中间省略.....
    registry:8088/kubernetes-dashboard-amd64:test pushed
    Untagged: registry:8088/kubernetes-dashboard-amd64:tmp
    Untagged: registry:8088/kubernetes-dashboard-amd64:test
    Untagged: registry:8088/kubernetes-dashboard-amd64@sha256:5c601d866b5a6b135fc6654417c4f8726661ce6903f00fc96ffe8127cdc272a0
    .....中间省略.....
    Deleted: sha256:cc940a53e84603ed3886909d8150f456fc93d25abf85d5ea07099d92e33640d9
    .....后面省略.....
    

shell脚本
#

$ cat export-images.sh 
#!/bin/bash
#Author:Feixiang Fu
#set -x

#指定镜像仓库的验证用户及密码
user_name=fufeixiang
passwd=123456

tty=$(tty)
usage(){
        echo "--------------------------------------------------------------"
        echo "Usage:"
        echo -e "\texport_images.sh -f IMAGES_FILE -t IMAGE_TAG [-p THREAD_NUM] [-h]"
        echo "Description:"
        echo -e "\tIMAGES_FILE: the list of images need to be exported"
        echo -e "\tIMAGE_TAG: the target tag of exported images"
        echo -e "\tTHREAD_NUM: the target thread numbers"
        echo "--------------------------------------------------------------"
        exit -1
}

function work(){
        i=$RANDOM
        docker pull $org_image
        #随机容器名称
        docker run -d --name container$i $org_image sh -c "tail -f /etc/hosts"
        docker export container$i > container${i}.tar
        docker import container${i}.tar $image_name:tmp
        docker rm -f container$i
        rm -rf container${i}.tar
        mkdir build-$i
cat <<EOF  > build-$i/Dockerfile
FROM $image_name:tmp
WORKDIR /app/bin
ENTRYPOINT ["/usr/bin/dumb-init","--"]
USER dcos
CMD ["sh", "/app/bin/startServer.sh"]
EOF
        #export镜像之后,entrypoint/cmd等会丢失,需要重新定制
        docker build -t $image_name:$tag build-$i/
        docker login -u $user_name -p $passwd $image_addr
        if [ "$?" -eq 0 ];then
            docker push $image_name:$tag && echo -e "\e[32m${image_name}:${tag} pushed\e[0m" |tee $tty
        else
            echo -e "\e[31m账户${user_name}密码不匹配,${image_name}:${tag} push failed\e[0m" |tee $tty
        fi
        #清理import的镜像及build的新镜像
       docker rmi $image_name:tmp $image_name:$tag
}

[ -z "$*" ] && usage && exit 1
while getopts 'f:t:p:h' opt;do
        case $opt in
                f) IMAGES_FILE="$OPTARG";;
                t) tag="$OPTARG";;
                p) thread="$OPTARG";;
                h) usage;;
                ?) usage;;
        esac
done
echo "开始执行任务"
#支持多进程模式
mkfifo tmp.fifo
exec 6<> tmp.fifo
thread=${thread:-1}
for ((j=0;j<$thread;j++));
do
    echo
done >&6
while read line || [ -n "$line" ];do
   org_image=${line%% *}
   image_name=${line%:*}
   #user_name=`echo $line|cut -d" " -f2`
   #passwd=${line##* } 
   image_addr=${line%%/*}
   read -u6 
   { 
    work >> export_images.log
    echo >&6
   } & 
done < $IMAGES_FILE 
wait
exec 6>&-
rm -rf tmp.fifo build-*/
echo "任务执行结束"

Related

批量自动构建docker镜像的shell脚本
·580 字·3 分钟
Docker Shell
Docker存储驱动direct-lvm的配置
·518 字·3 分钟
Docker Direct-Lvm
Golang自定义json解析类型的实现
·174 字·1 分钟
Go