实现容器的底层技术 - 每天5分钟玩转 Docker 容器技术(30)
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left"> <span style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px">为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术。<br></span><span style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px">cgroup 和 namespace 是最重要的两种技术。cgroup 实现资源限额, namespace 实现资源隔离。</span></p>
<h4 id="cgroup" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.2em; white-space: normal; text-align: left">
<span style="font-size: 36px"><strong>cgroup</strong></span>
</h4>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
cgroup 全称 Control Group。Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。相信你已经猜到了:前面我们看到的<code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">--cpu-shares</span></code>、<code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">-m</span></code>、<code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">--device-write-bps</span></code> 实际上就是在配置 cgroup。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
cgroup 到底长什么样子呢?我们可以在 /sys/fs/cgroup 中找到它。还是用例子来说明,启动一个容器,设置 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">--cpu-shares=512</span></code>:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749785999095463.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
查看容器的 ID:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749786133063354.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
在 /sys/fs/cgroup/cpu/docker 目录中,Linux 会为每个容器创建一个 cgroup 目录,以容器长ID 命名:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749786287073057.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
目录中包含所有与 cpu 相关的 cgroup 配置,文件 cpu.shares 保存的就是 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">--cpu-shares</span></code> 的配置,值为 512。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
同样的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是内存以及 Block IO 的 cgroup 配置。
</p>
<h4 id="namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.2em; white-space: normal; text-align: left">
<strong><span style="font-size: 36px">namespace</span></strong>
</h4>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡。这种方式非常好,它使得容器更像一个独立的计算机。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,<strong style="color: rgba(0, 0, 0, 1)">namespace 实现了容器间资源的隔离</strong>。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User,下面我们分别讨论。
</p>
<h5 id="mount-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">Mount namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
Mount namespace 让容器看上去拥有整个文件系统。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
容器有自己的 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)">/</code> 目录,可以执行 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)">mount</code> 和 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)">umount</code> 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。
</p>
<h5 id="uts-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">UTS namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
简单的说,UTS namespace 让容器有自己的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通过 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">-h</span></code> 或 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)"><span style="background-color: rgba(216, 216, 216, 1)">--hostname</span></code> 参数设置。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749786633018734.jpg">
</p>
<h5 id="ipc-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">IPC namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。
</p>
<h5 id="pid-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">PID namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
我们前面提到过,容器在 host 中以进程的形式运行。例如当前 host 中运行了两个容器:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749786795093686.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
通过 <code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)">ps axf</code> 可以查看容器进程:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749786936086665.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
所有容器的进程都挂在 dockerd 进程下,同时也可以看到容器自己的子进程。 如果我们进入到某个容器,<code style="font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 12.96px; padding: 2px 4px; color: rgba(0, 0, 0, 1); border-radius: 3px; background: rgba(234, 234, 235, 1)">ps</code> 就只能看到自己的进程了:
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749787395024268.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
而且进程的 PID 不同于 host 中对应进程的 PID,容器中 PID=1 的进程当然也不是 host 的 init 进程。也就是说:容器拥有自己独立的一套 PID,这就是 PID namespace 提供的功能。
</p>
<h5 id="network-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">Network namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
Network namespace 让容器拥有自己独立的网卡、IP、路由等资源。我们会在后面网络章节详细讨论。
</p>
<h5 id="user-namespace" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.1em; white-space: normal; text-align: left">
<strong><span style="font-size: 24px">User namespace</span></strong>
</h5>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
User namespace 让容器能够管理自己的用户,host 不能看到容器中创建的用户。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749787567035076.jpg">
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
在容器中创建了用户 cloudman,但 host 中并不会创建相应的用户。
</p>
<h3 id="-" style="font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-weight: 500; line-height: 1.2; margin-top: 1.5em; margin-bottom: 0.5em; font-size: 1.5em; white-space: normal; text-align: left">
<strong><span style="font-size: 36px">小结</span></strong>
</h3>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
本章首先通过大量实验学习了容器的各种操作以及容器状态之间如何转换,然后讨论了限制容器使用 CPU、内存和 Block IO 的方法,最后学习了实现容器的底层技术:cgroup 和 namespace。
</p>
<p style="margin-top: 0; margin-bottom: 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
下面是容器的常用操作命令:
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">create 创建容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">run 运行容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">pause 暂停容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">unpause 取消暂停继续运行容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">stop 发送 SIGTERM 停止容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">kill 发送 SIGKILL 快速停止容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">start 启动容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">restart 重启容器 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">attach attach 到容器启动进程的终端 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">exec 在容器中启动新进程,通常使用 "-it" 参数 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">logs 显示容器启动进程的控制台输出,用 "-f" 持续打印 </span>
</p>
<p style="text-align: left">
<span style="font-size: 14px; background-color: rgba(216, 216, 216, 1)">rm 从磁盘中删除容器</span>
</p>
<p style="box-sizing: border-box; margin: 0 0 1.5em; line-height: 1.6; color: rgba(56, 58, 66, 1); font-family: BlinkMacSystemFont, "Lucida Grande", "Segoe UI", Ubuntu, Cantarell, sans-serif; font-size: 14.4px; white-space: normal; text-align: left">
<br>到这里,我们已经学习完了容器章节。下一节开始讨论容器网络。
</p>
<p>
<img src="http://7xo6kd.com1.z0.glb.clouddn.com/upload-ueditor-image-20170618-1497749787714046449.jpg"><br>
</p><br><br>
来源:https://www.cnblogs.com/CloudMan6/p/7045784.html
頁:
[1]