在容器云平台中,应用全部运行在基础OS容器镜像之上,所以OS Base镜像的制作至关重要。如果OS Base镜像中功能插件过多而增加了镜像的体积,不仅带来了存储和网络的压力,而且这些功能插件的风险也给容器安全稳定带来了隐患。所以,我们务求制作一款极致精简的OS Base镜像。
本文将讲述构建基础OS容器镜像的几种方案。
Tips:本文中所有操作均在centos7-minimal中操作,相关依赖请自行下载安装。
方案一:supermin5 构建基础镜像
1、supermin5
Supermin 是一个用来创建迷你虚拟环境的工具,有点类似创建的迷你虚拟机环境。
如果机器上没有 supermin5 命令,可以使用下面的命令安装:
$ sudo yum install supermin5 supermin5-devel -y
supermin5 参数选项
$ sudo supermin5 --help
supermin - tool for creating supermin appliances
Copyright (C) 2009-2014 Red Hat Inc.
Usage:
supermin --prepare LIST OF PACKAGES ...
supermin --build INPUT [INPUT ...]
For full instructions, read the supermin(1) man page.
Options:
--build Build a full appliance
--copy-kernel Copy kernel instead of symlinking
--dtb WILDCARD Find device tree matching wildcard
-f chroot|ext2 Set output format
--format -\\\"-
--host-cpu ARCH Set host CPU architecture
--if-newer Only build if needed
--include-packagelist Add a file with the list of packages
--list-drivers Display list of drivers and exit
--lock LOCKFILE Use a lock file
--names Give an error for people needing supermin 4
-o OUTPUTDIR Set output directory
--packager-config CONFIGFILE Set packager config file
--prepare Prepare a supermin appliance
--size Set the size of the ext2 filesystem
--use-installed Use installed files instead of accessing network
-v Enable debugging messages
--verbose -\\\"-
-V Display version and exit
--version -\\\"-
-help Display this list of options
--help Display this list of options
2、使用supermin5构建基础镜像
以下命令使用root用户执行:
$ mkdir -p min-os min-os/tmp
$ cd min-os
# 指定min-os中需要安装的包.
# coreutils是ls,cd,pwd等基础命令的包。
$ supermin5 -v --prepare coreutils -o supermin.d --use-installed
# 构建min-os
$ supermin5 -v --build --format chroot supermin.d -o appliance.d
# 构建min-os中英文支持
$ mv appliance.d/usr/share/locale/zh appliance.d/usr/share/locale/zh_CN appliance.d/usr/share/locale/en appliance.d/usr/share/locale/en_US tmp
$ rm -rf appliance.d/usr/share/locale/*
$ mv tmp/en tmp/en_US tmp/zh tmp/zh_CN appliance.d/usr/share/locale/
$ mv appliance.d/usr/share/i18n/locales/en_US appliance.d/usr/share/i18n/locales/zh_CN tmp
$ rm -rf appliance.d/usr/share/i18n/locales/*
$ mv tmp/en_US tmp/zh_CN appliance.d/usr/share/i18n/locales/
# 基础镜像版本信息
$ echo 7 > appliance.d/etc/yum/vars/releasever
### 进入appliance.d,执行chroot
$ cd appliance.d/
$ chroot .
### 以下为上述命令创建的新环境
### 在这个独立的环境中测试镜像的各项能力
### 做增删改查操作,完成基础镜像修改。
bash-4.2$ ls
### 使用exit命令登出独立环境
bash-4.2$ exit
log out.
$ tar --numeric-owner -cpf centos7-0.tar -C appliance.d .
$ cat centos7-0.tar | docker import - local/centos7-0
$ docker run -it --rm local/centos7-0 /bin/bash
bash-4.2# ls
完成上述步骤后生成镜像大小:51.6M
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
local/centos7-10 latest 8abed4b3ba72 3 hours ago 51.6MB
方案二:编译busybox源码构建最小基础镜像
# 下载最新的busybox源码
$ wget https://busybox.net/downloads/busybox-1.30.1.tar.bz2
$ tar -jxf busybox-1.30.1.tar.bz2
$ cd busybox-1.30.1
1、busybox的编译
make xxxconfig
busybox提供了几种配置:defconfig (缺省配置)、allyesconfig(最大配置)、 allnoconfig(最小配置),一般选择缺省配置即可。 这一步结束后,将生成.config
$ make defconfig
make menuconfig
这一步是可选的,当你认为上述配置中还有不尽如意的地方,可以通过这一步进行微调,加入或去除某些命令。这一步实际上是修改.config
$ make menuconfig
make install
这一步就是根据.config,生成busybox,当然也可以指定其他的编译器, 如arm-linux-gnueabi-。(\\”make CROSS_COMPILE=\\”将用gcc编译PC机上运行的busybox。
$ make install
完成上述步骤,编译成功之后,会看到已经编译完成的busybox二进制文件。留待使用。
$ ls
busybox
$ cp busybox /usr/local/bin/
$ busybox
BusyBox v1.30.1 (2019-02-15 14:34:02 CET) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
or: busybox --install [-s] [DIR]
or: function [arguments]...
2、创建linux系统的基础目录
$ mkdir rootfs
$ cd rootfs/
在上述目录下执行如下脚本:crootfs.sh
#!/bin/sh
for module in `busybox --list-modules`
do
mkdir -p `dirname \\\"$module\\\"`
ln -sf /bin/busybox \\\"$module\\\"
done
3、将编译完成的busybox二进制文件拷贝至 rootfs文件夹下bin目录,生成tar包
$ cp /usr/local/bin/busybox bin/
回到rootfs目录
$ cd rootfs
$ tar cpf rootfs.tar .
4、制作Dockerfile
FROM scratch
MAINTAINER shebinbin
ADD rootfs.tar /
CMD [\\\"/bin/sh\\\"]
制作镜像
$ docker build -t busybox-os:v1 .
5、查看容器镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox-os v1 9bf409ffbbc0 22 hours ago 2.75MB
测试容器镜像
$ docker run --rm -it 9bf409ffbbc0 /bin/sh
方案三:挂载方式/usr/share和/usr/lib64缩小容器镜像大小
通过方案一制作的镜像仍然很大,我们尝试了很多方式来缩小容器镜像大小
bash-4.2# du -sh ./*
0 ./bin
4.0K ./boot
0 ./dev
2.3M ./etc
4.0K ./home
0 ./lib
0 ./lib64
4.0K ./media
4.0K ./mnt
4.0K ./opt
0 ./proc
8.0K ./root
12K ./run
0 ./sbin
4.0K ./srv
0 ./sys
4.0K ./tmp
57M ./usr
416K ./var
bash-4.2#
我们看到usr下很大:
bash-4.2# du -sh ./*
9.3M ./bin
4.0K ./etc
4.0K ./games
4.0K ./include
88K ./lib
24M ./lib64
152K ./libexec
132K ./local
3.7M ./sbin
20M ./share
12K ./src
0 ./tmp
bash-4.2#
usr里面的share和lib64 可以通过挂载宿主机share和lib64来实现。或者设置一个只读文件夹,实现share和lib64的挂载。这样就可以大大缩小镜像的大小。
$ docker run -it --rm -v /mnt/dockerLib/share/:/usr/share/ -v /mnt/dockerLib/lib64:/usr/lib64 8abed4b3ba72 /bin/bash
总结:
方案一构建的镜像仅仅安装了coreutils,根据需求也可以安装如bash、yum、git、python等插件,使用了supermin5组件来完成的,大小在50-60M左右,相对于方案二中的busybox来制作,它的体积相对较大,但在运行应用的时候可以少添加甚至不用添加额外的lib库,而busybox制作的基础镜像在我测试运行java项目时,需要额外添加lib库文件。现在非常受欢迎的alpine容器镜像就是在busybox基础上增加了自己的包管理工具apk等功能创建了风靡一时的小巧镜像,所以busybox方式也不失为一种合适的方案。方案三我在本机上进行了测试,能够正常运行容器,但由于每次运行都得挂载宿主机的只读文件夹,不符合松耦合的理念,但也是可行的方案之一。以上皆是我自己总结的一点点思考,希望能对大家有所帮助,谢谢!
原创文章,作者:EBCloud,如若转载,请注明出处:https://www.sudun.com/ask/33287.html