docker 的 镜像生成系列
1. 镜像根据容器 commit 生成
通过 docker run xxx 命令开启一个容器,然后在容器里做需求的操作,一般是安装环境、命令之类的,
然后在宿主机上,
通过 docker commit -a '作者信息' -m '提交信息' ‘刚刚的容器ID’ ‘新镜像名’:标签 生成新的镜像,
然后 docker push ‘新镜像名’:标签 传到镜像库。
2. 把容器导出成容器文件,再导入为镜像。【这种生成的镜像没有commit 信息】
导出: docker export '容器ID' > 文件名【一般是tar,或tar,gz】
导入: docker import 文件名 镜像名:标签 或者 cat 文件名 | docker import - 镜像名:标签
3. 把镜像导出成镜像文件,再导入为新镜像。【这个适用于镜像内部网络转移,这种操作情况下并没有产生新的镜像,只是把镜像变成镜像文件】
导出为镜像包: docker save ‘源镜像名:标签’ > 镜像文件.tar // docker save -o '镜像文件.tar' ‘源镜像名:标签’
导入为镜像: docker load -i 镜像文件.tar
4. dockerfile 文件的操作
Dockerfile 是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取 Dockerfile 中的指令自动生成映像。
docker build 命令用于从 Dockerfile 构建映像。可以在 docker build 命令中使用 -f 标志指向文件系统中任何位置的 Dockerfile。
命令: docker build -t '新镜像名:标签' -f 'dockerfile的 文件全路径' --no-cache
参考: https://www.cnblogs.com/panwenbin-logs/p/8007348.html
4. 1 dockerfile 操作 一般需要基础镜像 ,这个 可以在docker官网获取 ,还可以获取 dockerfile 文件。
可以从docker的官网获取官方的各种docker镜像:
https://hub.docker.com/explore/
其中centos的docker镜像获取地址:
https://hub.docker.com/_/centos/ 【点击一个跳转到 git 官网下去下载】
5. 自己做一个 基础镜像。
docker镜像是一个独立的文件系统,需要在其中安装好指定的用户态程序(对于基础镜像而言,就是bash)和依赖,除此之外,
为了后续方便用户扩展镜像,还需要安装yum(包括yum源配置文件)、rpm命令。
制作镜像的文件系统时,利用yum可以帮助我们完成依赖的处理,然后我们将文件系统打包。
最后按照docker的语法,创建Dockfile,并在其中指定基础镜像运行的用户态程序bash。
【脚本】
cgsl_docker.sh脚本是一键式制作docker镜像的工具,并且保留中间的过程的文件系统tar包和Dockerfile,并提供裁剪镜像的可选功能。
该脚本支持yum源和本地iso两种方式制作镜像,制作出的镜像内部已经配置了对应的yum源 或 iso源,方便后续容器和镜像的扩展。
用法如下:
./cgsl_docker.sh --iso x.iso --file rpmlistfile [--reduce]
./cgsl_docker.sh --url x.x.x.x/x/... --file rpmlistfile [--reduce]
--iso 指定本地iso路径
--url 指定网络yum源
--file 指定rpm列表文件,文件每一行写一个rpm包名
--reduce 可选参数,如果设置,则调用./cgsl_docker_reduce.sh 裁剪文件
运行产物介绍,1234为随机数:
1)在本机docker仓库中创建镜像scratch_1234
2)在脚本当前目录生成过程文件。
dockfile_1234 <<Dockfile
scratch_1234/ <<镜像文件系统目录
scratch_1234.tar <<镜像文件系统目录压缩包
scratch_1234.sh <<手工执行,可以为镜像scratch_1234启动容器
#! /bin/bash #USAGE="USAGE: \n\t$(basename "$0") --iso x.iso --file rpmlistfile \n\t$(basename "$0") --url x.x.x.x/x/... --file rpmlistfile" usage () { echo "USAGE:" echo -e "\tcgsl_docker.sh --iso x.iso --file rpmlistfile [--reduce]" echo -e "\tcgsl_docker.sh --url x.x.x.x/x/... --file rpmlistfile [--reduce]" } if [ $# -ne 4 ] && [ $# -ne 5 ]; then usage exit 1 fi ISO_= URL_= PWD_=`pwd` REDUCE_=0 RANDOM_NUM_=`echo $RANDOM` RPM_LIST_FILE_= ## for iso source if [ "$1" == "--iso" ] && [ -f $2 ] && [ "$3" == "--file" ] && [ -f $4 ];then ISO_=$2 RPM_LIST_FILE_=$4 ## for url source elif [ "$1" == "--url" ] && [ -n "$2" ] && [ "$3" == "--file" ] && [ -f $4 ];then URL_=$2 RPM_LIST_FILE_=$4 else echo "parameter error!!!" usage exit 1 fi if [ "$5" == "--reduce" ];then REDUCE_=1 RANDOM_NUM_=${RANDOM_NUM_}-reduce fi SCRATCH_DIR="${PWD_}/scratch_${RANDOM_NUM_}" MNT_DIR="${PWD_}/mnt_${RANDOM_NUM_}" DOCKFILE="${PWD_}/dockfile_${RANDOM_NUM_}" IMAGE_DIR="${PWD_}/image_${RANDOM_NUM_}" iso_mnt () { mount $1 $2 if [ "$?" -eq 0 ];then echo "<<<<iso [$1] mount at [$2] ok" else echo "<<<<iso [$1] mount at [$2] failed !!!" exit 1 fi } CGSL_REPO_NAME=CGSL_source create_yum_repo () { mkdir -p ${SCRATCH_DIR}/etc/yum.repos.d/ echo "[${CGSL_REPO_NAME}]" > ${SCRATCH_DIR}/etc/yum.repos.d/${CGSL_REPO_NAME}.repo echo "name=${CGSL_REPO_NAME}" >> ${SCRATCH_DIR}/etc/yum.repos.d/${CGSL_REPO_NAME}.repo echo "$1" >> ${SCRATCH_DIR}/etc/yum.repos.d/${CGSL_REPO_NAME}.repo echo "enabled=1" >> ${SCRATCH_DIR}/etc/yum.repos.d/${CGSL_REPO_NAME}.repo echo "gpgcheck=0" >> ${SCRATCH_DIR}/etc/yum.repos.d/${CGSL_REPO_NAME}.repo } create_dockfile () { touch $DOCKFILE echo "FROM scratch" > $DOCKFILE echo "MAINTAINER The CGSL Project" >> $DOCKFILE echo "ADD $1 /" >> $DOCKFILE echo "LABEL name=\"CGSL Base Image\"" >> $DOCKFILE echo "LABEL vendor="CGSL"" >> $DOCKFILE echo "LABEL license=GPLv2" >> $DOCKFILE echo "CMD [\"/bin/bash\"]" >> $DOCKFILE } reduce_system () { SYSTEM_DIR=$1 if [ ! -d "$SYSTEM_DIR" ];then echo "<<<<<<<<there is no dir [$SYSTEM_DIR] !!!" exit 1 fi ## echo -e "\n>>>>>>>>reduce [/usr/share/locale/] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR bash -c "cd /usr/share/locale/; ls | grep -v en_US| xargs rm -rf" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/usr/share/locale/] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/usr/share/locale/] in [$SYSTEM_DIR] failed !!!" exit fi ## echo -e "\n>>>>>>>>reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR bash -c "rm -f /usr/lib/locale/locale-archive;localedef -i en_US -f UTF-8 en_US.UTF-8" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR] failed !!!" exit fi ## echo -e "\n>>>>>>>>reduce [/var/cache/yum/] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR bash -c "rm -rf /var/cache/yum/*" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/var/cache/yum/] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/var/cache/yum/] in [$SYSTEM_DIR] failed !!!" exit fi } ## create filesystem dir ## echo -e "\n>>>>docker image root filesystem dir[${SCRATCH_DIR}]" mkdir $SCRATCH_DIR ## init rpm db echo -e ">>>>\ninit rpm db" mkdir -p ${SCRATCH_DIR}/var/lib/rpm rpm --root ${SCRATCH_DIR} --initdb ## create repo file if [ -n "$ISO_" ];then ## mount iso echo -e "\n>>>>mount [$ISO_] at [$MNT_DIR]" mkdir $MNT_DIR iso_mnt $ISO_ ${MNT_DIR} ## echo -e "\n>>>>create yum repos file: [baseurl=file://${MNT_DIR}/]" create_yum_repo "baseurl=file://${MNT_DIR}/" ## mkdir -p ${SCRATCH_DIR}${MNT_DIR} elif [ -n "URL_" ];then ## echo -e "\n>>>>create yum repos file: [baseurl=$URL_]" create_yum_repo "baseurl=${URL_}" fi ## install rpm list echo -e "\n>>>>install rpm of $RPM_LIST_FILE_" while read rpm_name do cd ${SCRATCH_DIR}/etc/yum.repos.d/ ls | grep -v ${CGSL_REPO_NAME} | xargs rm -f cd $PWD_ echo -e "\n>>>>>>>>install [$rpm_name]" yum -y --installroot=${SCRATCH_DIR} install $rpm_name if [ $? -eq 0 ];then echo "<<<<<<<<install [$rpm_name] ok" else echo "<<<<<<<<install [$rpm_name] failed !!!" exit 1 fi done < $RPM_LIST_FILE_ echo "<<<<install rpm from $RPM_LIST_FILE_ ok" ## repair rpm db echo -e "\n>>>>repair rpmdb for [${SCRATCH_DIR}]" chroot ${SCRATCH_DIR} /bin/bash -c "PATH=${PATH}:/bin/;cd /var/lib/rpm;rm -f __db*;rpm --rebuilddb" if [ $? -eq 0 ];then echo "<<<<repair rpmdb for [${SCRATCH_DIR}] ok" else echo "<<<<repair rpmdb for [${SCRATCH_DIR}] failed !!!" exit 1 fi ## repair /etc/klinux-* cd ${SCRATCH_DIR} for i in `find | grep "klinux-release\|klinux-build"` do name=`basename $i`; if [ ! -e ./etc/$name ];then echo -e "\n>>>>repair /etc/$name for [${SCRATCH_DIR}]" ln -s ${i#.} ./etc/$name if [ $? -eq 0 ];then echo "<<<<repair /etc/$name for [${SCRATCH_DIR}] ok" else echo "<<<<repair /etc/$name for [${SCRATCH_DIR}] failed !!!" exit 1 fi fi done cd $PWD_ ## reduce system dir if [ $REDUCE_ -eq 1 ];then ./cgsl_docker_reduce.sh ${SCRATCH_DIR} fi ## tar filesystem dir tar cf ${SCRATCH_DIR}.tar --numeric-owner -c -C ${SCRATCH_DIR} . if [ "$?" -eq 0 ];then echo -e "\n>>>>tar ${SCRATCH_DIR} to ${SCRATCH_DIR}.tar ok" else echo -e "\n>>>>tar ${SCRATCH_DIR} to ${SCRATCH_DIR}.tar failed !!!" exit 1 fi ## create dock file echo -e "\n>>>>create dockfile [`basename ${DOCKFILE}`]" create_dockfile `basename ${SCRATCH_DIR}.tar` ## create dock image mkdir ${IMAGE_DIR} mv ${DOCKFILE} ${IMAGE_DIR} mv ${SCRATCH_DIR}.tar ${IMAGE_DIR} cd ${IMAGE_DIR} echo -e "\n>>>>build docker images[`basename ${SCRATCH_DIR}`] form dockfile[`basename ${DOCKFILE}`]" docker build -t `basename ${SCRATCH_DIR}` -f `basename ${DOCKFILE}` . if [ "$?" -eq 0 ];then echo "<<<<build docker images[`basename ${SCRATCH_DIR}`] ok" else echo "<<<<build docker images[`basename ${SCRATCH_DIR}`] failed !!!" exit 1 fi cd "$PWD_" ## create run script echo -e "\n>>>>create docker run script [`basename ${SCRATCH_DIR}`.sh]" echo "#!/bin/bash" > `basename ${SCRATCH_DIR}`.sh if [ -n "$ISO_" ];then echo "docker run -ti -v ${MNT_DIR}:${MNT_DIR} `basename ${SCRATCH_DIR}`" >> `basename ${SCRATCH_DIR}`.sh elif [ -n "$URL_" ];then echo "docker run -ti `basename ${SCRATCH_DIR}`" >> `basename ${SCRATCH_DIR}`.sh fi chmod +x `basename ${SCRATCH_DIR}`.sh echo "<<<<please run [`basename ${SCRATCH_DIR}`.sh] to start you container of images[`basename ${SCRATCH_DIR}`]" echo -e "\n<<<<the end ^^"
#! /bin/bash USAGE="USAGE: \n\t$(basename "$0") dir" if [ $# -ne 1 ]; then echo -e "$USAGE" exit 1 fi TARGET_DIR=$1 reduce_system () { SYSTEM_DIR=$1 if [ ! -d "$SYSTEM_DIR" ];then echo "<<<<<<<<there is no dir [$SYSTEM_DIR] !!!" exit 1 fi ## echo -e "\n>>>>>>>>reduce [/usr/share/locale/] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR /bin/bash -c "PATH=${PATH}:/bin/;cd /usr/share/locale/; ls | grep -v en_US| xargs rm -rf" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/usr/share/locale/] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/usr/share/locale/] in [$SYSTEM_DIR] failed !!!" exit fi ## echo -e "\n>>>>>>>>reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR /bin/bash -c "PATH=${PATH}:/bin/;rm -f /usr/lib/locale/locale-archive;localedef -i en_US -f UTF-8 en_US.UTF-8" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/usr/lib/locale/locale-archive] in [$SYSTEM_DIR] failed !!!" exit fi ## echo -e "\n>>>>>>>>reduce [/var/cache/yum/] in [$SYSTEM_DIR]" chroot $SYSTEM_DIR /bin/bash -c "PATH=${PATH}:/bin/;rm -rf /var/cache/yum/*" if [ $? -eq 0 ];then echo "<<<<<<<<reduce [/var/cache/yum/] in [$SYSTEM_DIR] ok" else echo "<<<<<<<<reduce [/var/cache/yum/] in [$SYSTEM_DIR] failed !!!" exit fi } ## reduce system dir SIZE_ORG=`du -sh $TARGET_DIR | awk '{print $1}'` echo -e "\n>>>>reduce system dir[${TARGET_DIR}]" reduce_system $TARGET_DIR SIZE_=`du -sh $TARGET_DIR | awk '{print $1}'` echo "<<<<reduce system dir[${TARGET_DIR}] ok. form [$SIZE_ORG] to [$SIZE_]"