共计 2807 个字符,预计需要花费 8 分钟才能阅读完成。
本系列第一篇文章,Docker 实战教程之从入门到进步 (一),咱们曾经介绍了如何在 Ubuntu 操作系统中装置 Docker,以及 Proxy 和 Insecure Registry 的配置。
本文持续 Docker 的实战学习。
练习 1:通过一个简略例子学习 Docker 和宿主机操作系统文件目录相互隔离的实现原理
咱们晓得在 Docker 容器里是无法访问到宿主操作系统的文件目录的,但这种隔离是怎么实现的呢?
其实一点也不神奇——利用了 Linux 零碎的外部命令 chroot.
chroot 能将过程的根目录设置成任意指定的目录。
应用 chroot 咱们能创立一个新的过程,并且以 chroot 执行时传入的参数作为新过程的根目录。
因为新过程创立之后就无法访问除了新过程创立时传入 chroot 参数之外的其余文件目录,为了确保这个新过程可能失常工作,咱们必须手动拷贝一些文件到新过程的根目录映射的旧目录下。
做一个如下测试:
新建一个文件夹,执行 chroot . 意思是把文件夹 $HOME/container
当作新建过程的根目录。然而没有胜利,报谬误音讯:
chroot: failed to run command‘/bin/bash’: No such file or directory
执行上面两条命令:
执行命令 ldd $HOME/container/bin/bash
:
该命令为了查看须要有哪些库文件得手动拷贝到文件夹 $/HOME/container/bin/bash
上面:
依据 ldd 的输入,再次执行下图的八条命令:
再次执行 chroot .
,发现这次胜利了:
pwd 发现是在根目录下,ls 也只能发现执行 chroot 时指定的 container 目录下的子目录:
这就是 docker 文件目录隔离的实现原理。
练习 2:用一个理论例子了解 Docker volume 工作原理
要理解 Docker Volume,首先咱们须要了解 Docker 文件系统的工作原理。Docker 镜像是由多个文件系统的只读层叠加而成。当一个容器通过命令 docker run
启动时,Docker 会加载只读镜像层并在镜像栈顶部增加一个读写层。如果运行中的容器批改了现有的一个曾经存在的文件,那该文件将会从读写层上面的只读层复制到读写层,然而该文件的只读版本仍然存在,只不过曾经被读写层中该文件的正本所暗藏。
当删除 Docker 容器,并通过该镜像重新启动时,之前在读写层的更改将会失落。在 Docker 中,只读层及在顶部的读写层的组合被称为 Union File System(联结文件系统),简称 UnionFS
,它用到了一个重要的资源管理技术, 叫写时复制。
写时复制(copy-on-write), 也叫隐式共享,是一种对可批改资源实现高效复制的资源管理技术。对于一个反复资源,若不批改,则无需立即创立一个新的资源,该资源能够被共享应用。当产生批改的时候,才会创立新资源。这会大大减少对于未修改资源复制的耗费。其实 COW 这个概念对编程人员来说一点也不生疏,宽泛用在各种畛域,比方 ABAP 里对于内表 (Internal table) 的拷贝动作,Java 字符串的拷贝实现等等。Docker 基于 UnionFS 去创立 containers.
咱们上面看一个理论例子。
应用命令行 docker run --help
查看这个命令的帮忙文档。-h 的作用是指定容器的主机名。
应用命令行创立一个新的容器:
docker run -it –name jerry-container-test -h CONTAINER -v /data busybox /bin/sh
名称为 jerry-container-test, 用 -v 创立了一个 volume /data
创立结束之后,在容器里执行 cd /data 进入这个目录,这个时候还是空的。
docker ps 查看容器状态:
当初我想晓得主机上为了实现这个 volume,应用了哪个 internal 目录。
用命令 docker inspect jerry-container-test
查看关键字 ”volumes”:
失去了容器里 /data 在主机上实现的目录:
/var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data
当初我在主机上应用touch
命令在这个目录下间接创立一个文件:
sudo touch /var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data/test.s
当初切换到容器里,用 ls 也能看到间接在主机上用 touch 命令在 internal folder 里创立的文件了。
练习 3:利用 Docker volume 批改 Nginx Docker 镜像里的 index.html
通过这个小例子咱们能够进一步加深对 Docker volume
概念的了解和应用办法。
咱们都晓得运行基于 Docker 的 Nginx 镜像后,拜访 localhost 能看到 Nginx 默认的首页,这个首页的地位是 Nginx 镜像内的 /usr/share/nginx/html
目录上面。
假如咱们有个需要,批改 Nginx 默认的首页成上面的内容:
<html>
<head>
<title>Custom Website from my container</title>
</head>
<body>
<h1>This is Jerry's custom website.</h1>
<p>This website is served from my <a href="http://www.docker.com" target="_blank">SAP Docker</a> container.</p>
</body>
</html>
上面是具体办法。
命令行 -v 将主机目录 nginx-html
挂载到 Nginx 容器内的 /usr/share/nginx/html
目录内。
docker run -d -p 1081:80 -v
pwd
/nginx-html:/usr/share/nginx/html –name jerry-custom nginx
应用 vi 将主机目录 nginx-html
上面的 index.html
批改成自定义内容:
通过交互式的形式进入到 docker 容器外部:
docker exec -it jerry-custom /bin/sh
发现 Docker 容器里的 index.html 也主动被批改了,内容和主机目录 nginx-html 上面的统一。
localhost:1081 即可看到批改过后的自定义 Nginx 首页:
总结
本文首先通过一个简略的例子,介绍了 Docker 和宿主机操作系统文件目录相互隔离,是如何通过 Linux 命令 chroot 的实现原理,接着用批改 Nginx Docker 镜像 index.html 的理论例子,论述了 Docker Volume 的实现原理和应用办法。