創建自己的Docker基礎鏡像(rhel、centos)

         Docker 的出現爲開發人員和運維人員帶來了極大的便利,在使用Docker容器時,有沒有想過docker鏡像是怎麼來的呢,雖然現在可以從網上的鏡像倉庫下載鏡像,但是第三方提供的鏡像有時候並不符合我們的要求,我們有必要創建自己的基礎鏡像,然後在這個基礎鏡像上面,去構建各種應用鏡像。本文將介紹創建Docker基礎鏡像的兩種方法,分別是:1、通過tar打包現有的操作系統,然後導入Docker鏡像倉庫;2、使用mkimage-yum.sh腳本製作;

基礎環境:

         1、兩種方式我都是在同一臺虛擬機上操作的完成的,首先我們要準備好基礎的操作系統,此次我通過虛擬機安裝的rhel7.4的操作系統,安裝方式是最小化安裝,因爲我們需要將建出來的基礎鏡像儘可能的小。
在這裏插入圖片描述
2、安裝好docker(參考之前的文章https://blog.csdn.net/bjywxc/article/details/103373730)。

方式一:本地直接打包導入方式

1、安裝好最小化系統之後,使用tar進行打包,排除一些不必要的目錄。

tar --numeric-owner --exclude=/proc --exclude=/sys --exclude=/mnt --exclude=/tmp --exclude=/var/cache --exclude=/usr/share/{foomatic,backgrounds,perl5,fonts,cups,qt4,groff,kde4,icons,pixmaps,emacs,gnome-background-properties,sounds,gnome,games,desktop-directories} --exclude=/var/log -zcvf /tmp/rhel7.4-Base.tar.gz /

2、導入到docker鏡像

[root@localhost /]# cat /tmp/rhel7.4-Base.tar.gz| docker import - rhel7.4-tar
sha256:33b316e0e89c08462ef93affa55ed1768045bc73e33d0c6ded6cd837f0da1af8
[root@localhost /]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
rhel7.4-tar         latest              33b316e0e89c        7 seconds ago       978MB

3、運行容器

[root@localhost /]#  docker run -it rhel7.4-tar  /bin/bash
[root@0a56c30bbf0a /]# df -h
文件系統               容量  已用  可用 已用% 掛載點
overlay                 39G  2.8G   36G    8% /
tmpfs                   64M     0   64M    0% /dev
tmpfs                  997M     0  997M    0% /sys/fs/cgroup
shm                     64M     0   64M    0% /dev/shm
/dev/mapper/rhel-root   39G  2.8G   36G    8% /etc/hosts
tmpfs                  997M     0  997M    0% /proc/acpi
tmpfs                  997M     0  997M    0% /proc/scsi
tmpfs                  997M     0  997M    0% /sys/firmware
[root@0a56c30bbf0a /]# more /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.4 (Maipo)

方式二:mkimage-yum.sh腳本方式

1、腳本地址:https://raw.githubusercontent.com/docker/docker/master/contrib/mkimage-yum.sh或者https://github.com/moby/moby/blob/master/contrib/mkimage-yum.sh
2、腳本內容

#!/usr/bin/env bash
#
# Create a base CentOS Docker image.
#
# This script is useful on systems with yum installed (e.g., building
# a CentOS image on CentOS).  See contrib/mkimage-rinse.sh for a way
# to build CentOS images on other systems.

set -e

usage() {
    cat <<EOOPTS
$(basename $0) [OPTIONS] <name>
OPTIONS:
  -p "<packages>"  The list of packages to install in the container.
                   The default is blank. Can use multiple times.
  -g "<groups>"    The groups of packages to install in the container.
                   The default is "Core". Can use multiple times.
  -y <yumconf>     The path to the yum config to install packages from. The
                   default is /etc/yum.conf for Centos/RHEL and /etc/dnf/dnf.conf for Fedora
  -t <tag>         Specify Tag information.
                   default is reffered at /etc/{redhat,system}-release
EOOPTS
    exit 1
}

# option defaults
yum_config=/etc/yum.conf
if [ -f /etc/dnf/dnf.conf ] && command -v dnf &> /dev/null; then
	yum_config=/etc/dnf/dnf.conf
	alias yum=dnf
fi
# for names with spaces, use double quotes (") as install_groups=('Core' '"Compute Node"')
install_groups=()
install_packages=()
version=
while getopts ":y:p:g:t:h" opt; do
    case $opt in
        y)
            yum_config=$OPTARG
            ;;
        h)
            usage
            ;;
        p)
            install_packages+=("$OPTARG")
            ;;
        g)
            install_groups+=("$OPTARG")
            ;;
        t)
            version="$OPTARG"
            ;;
        \?)
            echo "Invalid option: -$OPTARG"
            usage
            ;;
    esac
done
shift $((OPTIND - 1))
name=$1

if [[ -z $name ]]; then
    usage
fi

# default to Core group if not specified otherwise
if [ ${#install_groups[*]} -eq 0 ]; then
   install_groups=('Core')
fi

target=$(mktemp -d --tmpdir $(basename $0).XXXXXX)

set -x

mkdir -m 755 "$target"/dev
mknod -m 600 "$target"/dev/console c 5 1
mknod -m 600 "$target"/dev/initctl p
mknod -m 666 "$target"/dev/full c 1 7
mknod -m 666 "$target"/dev/null c 1 3
mknod -m 666 "$target"/dev/ptmx c 5 2
mknod -m 666 "$target"/dev/random c 1 8
mknod -m 666 "$target"/dev/tty c 5 0
mknod -m 666 "$target"/dev/tty0 c 4 0
mknod -m 666 "$target"/dev/urandom c 1 9
mknod -m 666 "$target"/dev/zero c 1 5

# amazon linux yum will fail without vars set
if [ -d /etc/yum/vars ]; then
	mkdir -p -m 755 "$target"/etc/yum
	cp -a /etc/yum/vars "$target"/etc/yum/
fi

if [[ -n "$install_groups" ]];
then
    yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \
        --setopt=group_package_types=mandatory -y groupinstall "${install_groups[@]}"
fi

if [[ -n "$install_packages" ]];
then
    yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \
        --setopt=group_package_types=mandatory -y install "${install_packages[@]}"
fi

yum -c "$yum_config" --installroot="$target" -y clean all

cat > "$target"/etc/sysconfig/network <<EOF
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOF

# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target".
#  locales
rm -rf "$target"/usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
#  docs and man pages
rm -rf "$target"/usr/share/{man,doc,info,gnome/help}
#  cracklib
rm -rf "$target"/usr/share/cracklib
#  i18n
rm -rf "$target"/usr/share/i18n
#  yum cache
rm -rf "$target"/var/cache/yum
mkdir -p --mode=0755 "$target"/var/cache/yum
#  sln
rm -rf "$target"/sbin/sln
#  ldconfig
rm -rf "$target"/etc/ld.so.cache "$target"/var/cache/ldconfig
mkdir -p --mode=0755 "$target"/var/cache/ldconfig

if [ -z "$version" ]; then
    for file in "$target"/etc/{redhat,system}-release
    do
        if [ -r "$file" ]; then
            version="$(sed 's/^[^0-9\]*\([0-9.]\+\).*$/\1/' "$file")"
            break
        fi
    done
fi

if [ -z "$version" ]; then
    echo >&2 "warning: cannot autodetect OS version, using '$name' as tag"
    version=$name
fi

tar --numeric-owner -c -C "$target" . | docker import - $name:$version

docker run -i -t --rm $name:$version /bin/bash -c 'echo success'

rm -rf "$target"

3、運行腳本創建

[root@localhost /]# chmod 777 mkimage-yum.sh
[root@localhost /]#./mkimage-yum.sh -y /etc/yum.conf rhel7.4-mk 

4、等待執行完成,查看是否創建成功。

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
rhel7.4-mk          7.7.1908            2e4f95289f64        18 minutes ago      281MB
rhel7.4-tar         latest              33b316e0e89c        41 minutes ago      978MB
[root@localhost /]#  docker run -it rhel7.4-mk:7.7.1908  /bin/bash
[root@c9b2fa5d5e50 /]# df -h
Filesystem             Size  Used Avail Use% Mounted on
overlay                 39G  3.1G   36G   8% /
tmpfs                   64M     0   64M   0% /dev
tmpfs                  997M     0  997M   0% /sys/fs/cgroup
shm                     64M     0   64M   0% /dev/shm
/dev/mapper/rhel-root   39G  3.1G   36G   8% /etc/hosts
tmpfs                  997M     0  997M   0% /proc/acpi
tmpfs                  997M     0  997M   0% /proc/scsi
tmpfs                  997M     0  997M   0% /sys/firmware
[root@c9b2fa5d5e50 /]# more /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)

總結:

1、兩種方式都能實現,通過比對可以發現通過tar打包創建的基礎鏡像的體積大約是通過mkimage-yum.sh腳本創建的基礎鏡像的3倍左右,
2、兩個鏡像的版本不一致,tar打包的方式生成的鏡像版本和虛擬機一致rhel7.4,而腳本方式的鏡像版本是centos7.7,猜測是以yum源的版本生成的。
3、兩種方式各有特點,tar方式可以自定義安裝軟件和版本等,體積大;而腳本方式只能安裝官方yum源裏面支持的包,不能自定義,但是體積小。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章