Docker镜像结构

进了Docker的世界,就像进了少林的藏经阁,武功秘籍是应用尽有。前辈武僧给我们准备了各种基本功法(
基础镜像 base image)。我们来看一下少林的十大武功秘籍吧:(不是罗汉拳、伏虎拳,而是。。)
Docker镜像制作和管理 - 图1
Linux操作系统由内核空间和用户空间组成。内核空间的核心就是内核和bootfs启动时加载系统。用户空间的核心就是rootfs文件系统。通常不同的Linux发行版,即使基于不同的Ubuntu/Debian和CentOS/Fedora,也可以互相在内核层兼容。下图就是在CentOS内核上运行Debian rootfs的例子:
Docker镜像制作和管理 - 图2
图片来自dockerinfo.net,图片版权归属原作者
上例中,底层操作系统是CentOS,用户通过docker pull debian下载了包含Debian rootfs的Docker镜像。这个镜像可以在运行docker run -it debian加载运行时充分利用CentOS底层的内核空间,将rootfs用户空间运行起来。用户通过uname -a仍然可以查询到内核仍然是底层CentOS的版本,但是整个文件系统(/dev、/prod、/bin、/etc、/usr、/tmp等)却采用了Debian的结构。

  1. [root@training1 ~]# uname -a
  2. Linux training1 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
  3. [root@training1 ~]# cat /etc/redhat-release
  4. CentOS Linux release 7.2.1511 (Core)
  5. [root@training1 ~]# docker run -it debian
  6. root@3e666078fe81:/# uname -a
  7. Linux 3e666078fe81 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 GNU/Linux
  8. root@3e666078fe81:/# cat /etc/issue
  9. Debian GNU/Linux 10
  10. l

Docker镜像构建

现在让我们在Debian少林铁头功的基础上再加一点料:
用户修改Dokcerfile:

  1. [root@training1 ~]# cat Dockerfile
  2. FROM debian
  3. ADD emacs /
  4. ADD apache /

之后,运行docker build

  1. [root@training1 ~]# docker build -t debian-emacs-apache .
  2. Sending build context to Docker daemon 54.78kB
  3. Step 1/3 : FROM debian
  4. ---> 85c4fd36a543
  5. Step 2/3 : ADD emacs /
  6. ---> 147bb4cfa4b0
  7. Step 3/3 : ADD apache /
  8. ---> 908246963b33
  9. Successfully built 908246963b33
  10. Successfully tagged debian-emacs-apache:latest

通过docker images命令可以看到新的image产生了,通过docker history命令可以查看到image层层堆叠的效果。我们的少林拳法从铁头功(Debian)、升级到了铁布衫(Add emacs dir)、升级到了金钟罩(Add apache dir)。

  1. [root@training1 ~]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. debian-emacs-apache latest 908246963b33 About a minute ago 114MB
  4. debian latest 85c4fd36a543 4 days ago 114MB
  5. [root@training1 ~]# docker history debian-emacs-apache
  6. IMAGE CREATED CREATED BY SIZE COMMENT
  7. 908246963b33 About a minute ago /bin/sh -c #(nop) ADD dir:35c3010dfae5d26232 0B
  8. 147bb4cfa4b0 About a minute ago /bin/sh -c #(nop) ADD dir:08133be9c242532cbb 0B
  9. 85c4fd36a543 4 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
  10. <missing> 4 days ago /bin/sh -c #(nop) ADD file:99bf629976cd3d79c 114MB

运行docker run -it debian-emacs-apache启动并进入容器,检查一下金钟罩到底是不是好使:

  1. [root@training1 ~]# docker run -it debian-emacs-apache
  2. root@c6eedfad2845:/# ls -ld apache emacs
  3. -rw-r--r-- 1 root root 0 Aug 18 13:55 apache
  4. -rw-r--r-- 1 root root 0 Aug 18 13:55 emacs

可以看到apache和emac目录已经成功地部署在容器中运行的应用上。我们可以尽情地在apache和emacs目录里增删改查,所有效果只会在最上层的容器层生效,并不会影响下面的镜像层。
让我们尝试着打破金钟罩

  1. root@553461c68488:/# rm -rf apache emacs
  2. root@553461c68488:/# ls
  3. bin dev home lib64 mnt proc run srv tmp var
  4. boot etc lib media opt root sbin sys usr

exit退出容器后,让我们再重新基于debian-emacs-apache运行容器

  1. [root@training1 ~]# docker run -it debian-emacs-apache
  2. root@e2f50248b065:/# ls
  3. apache boot emacs home lib64 mnt proc run srv tmp var
  4. bin dev etc lib media opt root sbin sys usr

可以看到我们铁布衫(emacs)和金钟罩(apache)保持依旧,并没有因为容器层的修改而变化。具体架构图参见:
Docker镜像制作和管理 - 图3
图片来自dockerinfo.net,图片版权归属原作者

Dockerfile常用指令

  • FROM

所谓定制镜像,那么就一定是以一个镜像为基础,在其上进行修改定制。而FROM就是指定基础镜像,因此在DockerFile中,FROM是必备指定,并且必需是第一条指令!

  • COPY

COPY指令将从上下文目录中的指定路径下的文件或文件夹复制到新的一层的镜像内的指定路径之下,格式为:
COPY <源路径> … <目标路径>

  • ADD

ADD指令和COPY的格式和性质基本一致,只不过是在COPY的基础上增加了一些功能。如:源路径可以是一个远程URL,Docker引擎会自动帮我们将远程URL的文件下载下来到目标路径下;如果源路径是本地的一个tar压缩文件时,ADD指定在复制到目录路径下会自动将其进行解压。

  • VOLUME

VOLUME指令用于构建镜像时定义匿名卷,将在后续数据持久化中讨论

  • EXPOSE

EXPOSE指令是声明运行时容器服务端口,将在后续网络通信中讨论

  • WORKDIR

使用WORKDIR指令来制定工作目录

  • ENV

ENV指令用于设置环境变量

  • RUN

RUN指令是用来执行命令行命令的,由于命令行的强大功能,RUN指令是定制镜像时最常用的指令之一,将在Dockerfile实战中详细讨论

  • CMD

在启动容器的时候,指定运行的程序及参数,将在Dockerfile实战中详细讨论

  • ENTRYPOINT

ENTRYPOINT指令和CMD指令目的一样,都是指定容器运行程序及参数,将在Dockerfile实战中详细讨论

小结

在本节课程中,我们学习了Docker镜像的结构,镜像制作的命令和原理,以及Dockerfile的一些常用指令。接下来,我们将带着大家进入Dockerfile的Demo,实战一下在少林新学到的拳脚功夫。