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/

    其中centosdocker镜像获取地址:

          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 ^^"
cgsl_docker.sh
#! /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_]"
cgsl_doker_reduce.sh

 

 

posted @ 2020-02-26 09:03  马克图  阅读(484)  评论(0编辑  收藏  举报