容器基础(四): 自定义简单容器镜像
为什么需要容器镜像
1. Mount Namespace一定是伴随着挂载操作(mount)才能生效。即使开启了 Mount Namespace,在执行挂载操作前, 新创建的容器也会直接继承宿主机的各个挂载点, 容器进程看到的文件系统跟宿主机完全一样。 2. 为了能让容器启动后看到的文件系统是独立的,和宿主机不同, 借助chroot/pivot_root, 可以把程序的根目录挂载到一个目录(rootfs)上,从而让程序看到一个和宿主机"不一样"的文件系统。
如何自定义一个文件系统
简单的方法就是参考一个Linux目录结构,生成对应目录,然后把需要的命令和动态库拷贝到自定义文件系统。或者可以把busybox放到自定义文件系统,这样可以不用拷贝命令。
使用脚本生成一个根文件系统rootfs如下所示(脚本会生成必要的目录并且拷贝常用的一些命令到rootfs):
1 #!/bin/sh 2 # 不同机器命令的路径可能不同, 只是一个简单脚本, 根据需要手动改 3 rootfs_path=/var/lib/sdocker/rootfs 4 rootfs_command=("/bin/bash" "/bin/ls" "/bin/ps" \ 5 "/bin/ss" "/bin/hostname" "/bin/ip" \ 6 "/bin/mount" "/bin/cat" "/usr/bin/vim") 7 8 function create_directory() 9 { 10 if [ ! -z "${1}" -a ! -d "${1}" ]; then 11 mkdir -p "${1}" 12 fi 13 } 14 15 function create_rootfs_directory() 16 { 17 # create sub-directory of rootfs 18 local rootfs_dirs=(bin dev etc lib64 media opt root sbin sys usr boot env home lib mnt proc run srv tmp var) 19 for dirs in ${rootfs_dirs[@]}; do 20 create_directory $rootfs_path/$dirs 21 done 22 } 23 24 function copy_command() 25 { 26 # copy all files needed by command 27 for cmd in ${rootfs_command[@]}; do 28 echo "[+] copy command $cmd" 29 local cmd_dir=${rootfs_path}$(dirname $cmd) 30 create_directory $cmd_dir 31 cp $cmd $cmd_dir 32 echo " -> copy file: $cmd" 33 34 dependence_list="$(ldd $cmd | egrep -o '/.*lib.*\.[0-9]+')" 35 for deps in ${dependence_list}; do 36 deps_dir=${rootfs_path}$(dirname $deps) 37 create_directory $deps_dir 38 cp $deps $deps_dir 39 echo " -> copy file: $deps" 40 done 41 done 42 } 43 44 function main() 45 { 46 create_directory $rootfs_path 47 create_rootfs_directory 48 copy_command 49 } 50 51 main
➜ namespace ./gen_rootfs.sh [+] copy command /bin/bash -> copy file: /bin/bash -> copy file: /lib/x86_64-linux-gnu/libncurses.so.5 -> copy file: /lib/x86_64-linux-gnu/libtinfo.so.5 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib64/ld-linux-x86-64.so.2 [+] copy command /bin/ls -> copy file: /bin/ls -> copy file: /lib/x86_64-linux-gnu/libselinux.so.1 -> copy file: /lib/x86_64-linux-gnu/libacl.so.1 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib/x86_64-linux-gnu/libpcre.so.3 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib64/ld-linux-x86-64.so.2 -> copy file: /lib/x86_64-linux-gnu/libattr.so.1 -> copy file: /lib/x86_64-linux-gnu/libpthread.so.0 [+] copy command /bin/ps -> copy file: /bin/ps -> copy file: /lib/x86_64-linux-gnu/libprocps.so.3 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib64/ld-linux-x86-64.so.2 [+] copy command /bin/ss -> copy file: /bin/ss -> copy file: /lib/x86_64-linux-gnu/libselinux.so.1 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib/x86_64-linux-gnu/libpcre.so.3 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib64/ld-linux-x86-64.so.2 -> copy file: /lib/x86_64-linux-gnu/libpthread.so.0 [+] copy command /bin/hostname -> copy file: /bin/hostname -> copy file: /lib/x86_64-linux-gnu/libnsl.so.1 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib64/ld-linux-x86-64.so.2 [+] copy command /bin/ip -> copy file: /bin/ip -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib64/ld-linux-x86-64.so.2 [+] copy command /bin/mount -> copy file: /bin/mount -> copy file: /lib/x86_64-linux-gnu/libmount.so.1 -> copy file: /lib/x86_64-linux-gnu/libselinux.so.1 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib/x86_64-linux-gnu/libblkid.so.1 -> copy file: /lib64/ld-linux-x86-64.so.2 -> copy file: /lib/x86_64-linux-gnu/libpcre.so.3 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib/x86_64-linux-gnu/libuuid.so.1 -> copy file: /lib/x86_64-linux-gnu/libpthread.so.0 [+] copy command /bin/cat -> copy file: /bin/cat -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib64/ld-linux-x86-64.so.2 [+] copy command /usr/bin/vim -> copy file: /usr/bin/vim -> copy file: /lib/x86_64-linux-gnu/libm.so.6 -> copy file: /lib/x86_64-linux-gnu/libtinfo.so.5 -> copy file: /lib/x86_64-linux-gnu/libselinux.so.1 -> copy file: /lib/x86_64-linux-gnu/libacl.so.1 -> copy file: /usr/lib/x86_64-linux-gnu/libgpm.so.2 -> copy file: /lib/x86_64-linux-gnu/libdl.so.2 -> copy file: /lib/x86_64-linux-gnu/libc.so.6 -> copy file: /lib/x86_64-linux-gnu/libpcre.so.3 -> copy file: /lib64/ld-linux-x86-64.so.2 -> copy file: /lib/x86_64-linux-gnu/libattr.so.1 -> copy file: /lib/x86_64-linux-gnu/libpthread.so.0 ➜ namespace
总结
1. 文件系统只包括操作系统对应的文件, 配置和目录, 并不包括内核; 所以对于容器而言, 同一台机器上的所有容器, 都共享宿主机操作系统的内核; 2. 对应用而言, 除了一些第三方依赖, 操作系统本身也可以算作是应用的一个最大依赖。由于rootfs 里打包的不只是应用,还包括了整个操作系统的文件和目录,这也就意味着,应用以及它运行所需要的所有依赖,都被封装在了一起, 从而得到了容器被反复宣传至今的一个重要特性: 一致性。 3. 容器的一致性仅限于文件系统,若容器中应用依赖于kernel或cpu等的一些特性,那么一致性就不能满足。
Excellence, is not an act, but a habit.
作者:子厚.
出处:http://www.cnblogs.com/aios/
本文版权归作者和博客园共有,欢迎转载、交流、点赞、评论,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。