- 博客/
批量自动构建docker镜像的shell脚本
·580 字·3 分钟
Docker
Shell
背景#
目前,由于公司多个相互隔离环境并存,各个环境都部署有容器管理平台,当有docker image更新的时候,就需要在每个环境都修改Dockerfile并执行docker build & docker push到公共镜像仓库的操作,为了减少重复性的工作,我就写了一个自动构建镜像的脚本,只需要在一个环境中准备好构建镜像的Dockerfile及依赖文件,执行脚本完成构建和推送,然后打包构建镜像的文件夹并传输到另一环境,执行脚本就可以自动完成
脚本运行示例#
构建脚本的目录结构#
01.20171229文件夹 <—> 要构建镜像的tag
构建镜像步骤#
创建目录#
$ cd /data/dcos
$ mkdir -p buildimages/01.20171229 log
$ cd buildimages/01.20171229
#创建各个需要build镜像的文件夹
$ mkdir centos7.2_tomcat7.0.72-all rhel7.2_tomcat7.0.63-jdk1.6.0_45 ...
修改configfile#
$ vim /data/dcos/buildimages/configfile
TargetRegistry:192.168.196.128:5000 --> 当前环境镜像仓库地址
Registry_user:admin --> 仓库登录用户名
Registry_passwd:admin --> 仓库认证密码
准备Dockerfile和依赖文件#
#示例
$ ls centos7.2_tomcat7.0.72-all
Dockerfile startServer.sh
构建镜像#
$ bash /data/dcos/buildimages/build.sh 01.20171229 -->脚本要跟参数01.20171229
日志文件#
$ less /data/dcos/buildimages/log/01.20171229.log -->以tag命名的日志文件
Trying to pull repository 192.168.196.128:5000/admin/centos7.2_tomcat7.0.72-all ...
01.20171221: Pulling from 192.168.196.128:5000/admin/centos7.2_tomcat7.0.72-all
4f4fb700ef54: Pulling fs layer
d8405e7a6b27: Pulling fs layer
02389d9a455d: Pulling fs layer
...中间省略...
a3eef13e30fb: Pull complete
2833ecd114e0: Pull complete
f8b56d99c9b0: Pull complete
adb966dc304e: Pull complete
Digest: sha256:861302f6da8e083b112d92fa153fc4dcde677f6d3e598ab22eea4289e312b08c
Sending build context to Docker daemon 5.12 kB^M
Step 1 : FROM 192.168.196.128:5000/admin/centos7.2_tomcat7.0.72-all:01.20171221
---> 09ce979d3860
Step 2 : USER root
---> Running in 9a072cdbee5e
---> cc3b6b1d9bf1
Removing intermediate container 9a072cdbee5e
Step 3 : COPY startServer.sh /app/bin/startServer.sh
---> 0d743c01403c
Removing intermediate container fbdd0d775d09
Step 4 : RUN chmod +x /app/bin/startServer.sh && chown -R dcos:docker /app/bin/startServer.sh
---> Running in 03b6f5d1d467
---> 0f6055d1b9c5
Removing intermediate container 03b6f5d1d467
Step 5 : USER dcos
---> Running in 6ac2a787ae71
---> ae33c0899e2a
Removing intermediate container 6ac2a787ae71
Successfully built ae33c0899e2a
The push refers to a repository [192.168.196.128:5000/admin/centos7.2_tomcat7.0.72-all]
e623fa631602: Preparing
473647768f24: Preparing
96bd6e1cc68c: Preparing
...中间省略...
473647768f24: Pushed
e623fa631602: Pushed
01.20171229: digest: sha256:1a5c012f2d7b4a627c5dc1aca22350d652676adf53adfde0d471943f4d390d4b size: 6798
压缩构建镜像的目录#
$ tar cvf 01.20171229.tar /data/dcos/buildimages/01.20171229
跨环境自动构建镜像#
传输01.20171229.tar
文件并解压#
$ cd /data/dcos/buildimages
$ tar xf 01.20171229.tar
查看并确认configfile#
#示例
$ vim /data/dcos/buildimages/configfile
TargetRegistry:192.168.196.128:5000 --> 当前环境镜像仓库地址
Registry_user:admin
Registry_passwd:admin
构建镜像#
$ bash /data/dcos/buildimages/build.sh 01.20171229
shell脚本#
#!/bin/bash
#Date:2018-01-03
#version:3.0
#Author:Feixiang Fu
#Description:Auto-build images based on configfile && Auto-push images
. /etc/init.d/functions
[ -z "$*" ] && echo "usage: "buildim.sh VERSIONDIR" (VERSIONDIR is the target image tag)" && exit 1
dir=/data/dcos/buildimages
build_dir=$dir/$1
if [ ! -d $build_dir ]; then
action "目标目录${1}不存在" false
exit 1
fi
addr=`cat $dir/configfile | awk -F: '/^TargetRegistry/{print $2":"$3}'`
user=`cat $dir/configfile | awk -F: '/^Registry_user/{print $2}'`
passwd=`cat $dir/configfile | awk -F: '/^Registry_passwd/{print $2}'`
cd $build_dir
imagesdir_num=`ls -d $build_dir/*/|wc -l`
if [ $imagesdir_num -eq 0 ] ; then
action "${1}目录下没有要构建的镜像文件夹" false
exit 1
fi
docker login -u $user -p $passwd $addr &> /dev/null
if [ $? -eq 0 ] ; then
action "登陆镜像仓库${addr}成功"
else
action "登陆镜像仓库${addr}失败" false
exit 1
fi
declare -a localim
buildim(){
cd $build_dir/$1 &> /dev/null
if [ $? -ne 0 ] ;then
echo "${1}为普通文件,略过"
continue
fi
if [ -f ./Dockerfile ] ;then
sed -i -r "s#(FROM\s+)[^/]+(\/.*)#\1${addr}\2#" Dockerfile
baseimage=`cat Dockerfile |grep FROM|cut -d" " -f2`
baseimage_num=`docker images|awk '{print $1":"$2}'|grep "$baseimage"|wc -l`
baseimage_name=`echo "$baseimage" | awk -F/ '{print $3}' `
if [ $baseimage_num -eq 0 ] ; then
echo -e "正在拉取\e[33m${baseimage_name}\e[0m"
docker pull $baseimage >> $dir/log/${2}.log 2>&1
if [ $? -eq 0 ]; then
action "拉取${baseimage_name}成功"
localim[${#localim[*]}]=$baseimage
else
action "拉取${baseimage_name}失败" false
continue
fi
fi
path=`echo $baseimage |cut -d: -f1,2`
newimage_name=`echo $baseimage_name|sed -r "s/([^:]+:).*/\1$2/"`
echo -e "正在构建\e[33m${newimage_name}\e[0m"
docker build -t $path:$2 ./ >> $dir/log/${2}.log 2>&1
if [ $? -eq 0 ] ;then
action "${newimage_name}构建成功"
localim[${#localim[*]}]=$path:$2
else
action "${newimage_name}构建失败" false
continue
fi
echo -e "正在推送\e[33m${newimage_name}\e[0m"
docker push $path:$2 >> $dir/log/${2}.log 2>&1
if [ $? -eq 0 ] ;then
action "${newimage_name}推送成功"
else
action "${newimage_name}推送失败" false
fi
else
action "${1}目录下无Dockerfile" false
fi
}
for i in `ls $build_dir` ; do
echo -e "\e[32m-------------------------------------------------------------------\e[0m"
buildim $i $1
done
echo -e "\e[32m-------------------------------------------------------------------\e[0m"
echo "正在清理本地镜像文件"
for j in `seq $((${#localim[*]}-1)) -1 0` ;do
localim_name=$(echo "${localim[$j]}"| awk -F/ '{print $3}')
docker rmi ${localim[$j]} >> $dir/log/${1}.log 2>&1
if [ $? -eq 0 ] ;then
action "${localim_name}清理成功"
else
action "${localim_name}清理失败" false
fi
done
echo -e "\e[32m-------------------------------------------------------------------\e[0m"
[ -f $dir/log/${1}.log ] && echo "logfile: $dir/log/${1}.log"