1、基于容器 制作
(1)获取基础镜像busybox,并启动容器,--name指定容器名称为bs1
(2)在容器内,创建目录,并创建文件index.html(根据业务需求制作)
index.html文件内容自己定义
(3)新开一个终端,执行以下命令查看参数介绍(镜像制作过程中,容器必须处于运行状态)
docker commit -h
(4)制作镜像
# docker commit 的语法格式为:
# docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
docker commit -p -a "caicai <junchao827@foxmail.com>" -m "增加index.html网页" bs1 caicai/httpd:V0-1-1-2
# -a --author 是指定修改的作者
# -c --change list 应用dockerfile 修改CMD命令
# -m --message 则是记录本次修改的内容
# -p Pause container during commit (default true)
(5)为镜像指定tag标签
(6)为镜像执行其他标签(一个镜像可以对应多个标签,但是一个标签只能对应一个镜像)
(7)修改cmd启动命令
假设我们修改前面生成的镜像启动命令为httpd,
1、首先查看现有镜像的cmd命令
docker inspect busybox
cmd命令,默认为/bin/sh
# "Cmd": [
# "/bin/sh",
# "-c",
# "#(nop) ",
# "CMD [\"sh\"]"
# ]
2、启动容器,查看容易默认为sh
docker run --name t2 -it caicai/httpd:V0-1-1-2
3、启动容器,查看httpd使用方法
/ # httpd -h
Usage: httpd [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
-D name : define a name for use in <IfDefine name> directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed vhost settings
-t -D DUMP_RUN_CFG : show parsed run settings
-S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t : run syntax check for config files
-T : start without DocumentRoot(s) check
-X : debug mode (only one worker, do not detach)
3、启动容器,docker commit -c修改cmd命令
docker commit -a "caicai <junchao837@foxmail>" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p t2 caicai/httpd:V0-1-1-3
# -a 指定作者
# -c 修改cmd命令,格式为cmd list
# -p 执行容器
4、运行容器(默认不是交互模式)
5、查看已运行容器(运行命令为/bin/httpd)
6、访问容器
# 通过以下方式获取容器地址,查看Networks对应的ip
docker inspect t3 # t3为容器名
# 访问容器
curl 172.17.0.7
# <h1>Busybox httpd server.</h1> 返回值为/data/html/index.html中内容
6、至此,一个微型web服务镜像就制作成功了
慎用 docker commit
使用 docker commit
命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。
首先,如果仔细观察之前的 docker diff webserver
的结果,你会发现除了真正想要修改的 /usr/share/nginx/html/index.html
文件外,由于命令的执行,还有很多文件被改动或添加了。这还仅仅是最简单的操作,如果是安装软件包、编译构建,那会有大量的无关内容被添加进来,如果不小心清理,将会导致镜像极为臃肿。
此外,使用 docker commit
意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为 黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体在操作的。虽然 docker diff
或许可以告诉得到一些线索,但是远远不到可以确保生成一致镜像的地步。这种黑箱镜像的维护工作是非常痛苦的。
而且,镜像所使用的分层存储,除当前层外,之前的每一层都是不会发生改变的,换句话说,任何修改的结果仅仅是在当前层进行标记、添加、修改,而不会改动上一层。如果使用 docker commit
制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到。这会让镜像更加臃肿。
Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。就是commit最多127次。