本系列第一篇文章,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 的实现原理和使用方法。

Docker 实战教程之从入门到提高(二)相关推荐

  1. Docker 实战教程之从入门到提高 (五)

    本系列的前四篇文章,我们学习了如何在 Ubuntu 操作系统安装 Docker,并且通过实战练习,了解了 Docker 和宿主机操作系统文件目录互相隔离的实现原理,以及 Docker Volume 的 ...

  2. Docker 实战教程之从入门到提高 (四)

    本系列的前三篇文章,我们学习了如何在 Ubuntu 操作系统安装 Docker,并且通过实战练习,了解了 Docker 和宿主机操作系统文件目录互相隔离的实现原理,以及 Docker Volume 的 ...

  3. SAP OData 开发实战教程:从入门到提高

    文章目录 SEGW - Gateway Service Builder 使用 Restful ABAP Programming 编程模型(简称 RAP) 开发 OData 服务 使用 SAP Clou ...

  4. 尚硅谷Docker实战教程-笔记02【安装docker、镜像加速器配置】

    尚硅谷大数据技术-教程-学习路线-笔记汇总表[课程资料下载] 视频地址:尚硅谷Docker实战教程(docker教程天花板)_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01[理念简介 ...

  5. 视频教程-SpringBoot实战教程:SpringBoot入门及前后端分离项目开发-Java

    SpringBoot实战教程:SpringBoot入门及前后端分离项目开发 十三,CSDN达人课课程作者,CSDN 博客作者,现就职于某网络科技公司任职高级 Java 开发工程师,13blog.sit ...

  6. Docker实战教程

    Centos配置 查看centos系统版本命令: cat /etc/centos-release 配置阿里云yum源 1.下载安装wget yum install -y wget2.备份默认的yum ...

  7. 尚硅谷Docker实战教程学习总结文档

    目录 Docker与微服务实战(2022版) 1.基础篇(零基础小白) 1.1.Docker简介 1.1.1.怎么去学习Docker 1.1.2.是什么 1.1.2.1.为什么会有docker的出现? ...

  8. Gephi实战教程:从入门到精通

    Gephi是图数据可视化中比较好用的工具,但是国内关于Gephi的使用教程其实很少,而且很多教程中的内容都是错误的,本人在使用过程中也遇到很多问题,所以写了几篇文章记录下来,希望能帮到大家. 以下教程 ...

  9. FME案例实战教程:聚焦实战应用,摆脱思路束缚,您值得拥有

    一.教程链接 (一)FME案例实战教程链接 1.FME案例实战教程(完整版) ☚强烈推荐☚ 2.FME案例实战教程(A组) 3.FME案例实战教程(B组) 4.FME案例实战教程(C组) (二)FME ...

最新文章

  1. css限制字体三行_CSS美化网页
  2. No loop matching the specified signature and casting
  3. Linux-locate/slocate命令
  4. FileOutStream
  5. 什么是真正的APM?
  6. java 对list增删_List 中正确的增删操作
  7. php分页类smary,php新闻内容分页实例(smarty 模板)
  8. mysql sql sysdate_MySQL与Oracle SQL语言差异比较一览
  9. C#序列化与反序列化方式简单总结
  10. C语言 · 字符串输入输出函数
  11. 每天2小时,吃透 985博士总结的这套保姆级TensorFlow + PyTorch笔记(20G高清/PPT/代码)
  12. pytorch 存取模型(待补充)
  13. linux 查看tongweb进程,TongWeb日志如何查看?
  14. 【算法笔记】Diadem Metric
  15. MySQL指南之SQL语句基础
  16. CRISPR最新:新CRISPR技术靶向更复杂的人类基因组代码
  17. 使用cython加速代码运行
  18. 模型预测控制器(MPC)系列: 1.建立车辆横向动力学模型
  19. 使用a标签时不用href=““调转页面
  20. 中国居民收入调查数据库CHIPS

热门文章

  1. mysql中的extract()函数
  2. 在ubuntu系统中删除软件的三种最佳方法
  3. 报表怎样实现滚动的公告效果?
  4. 路飞学城-python爬虫密训-第三章
  5. 测试过程中常用的linux命令之【查找指定的文件内容】
  6. ORBSLAM2在Ubuntu14.04上详细配置流程
  7. Hibernate连接mysql数据库并自动创建表
  8. PLSQL developer 连接64位oracle 11.2G
  9. extern “C”
  10. MyEclipse导入新项目后,不能发布到Tomcat