第 4 章 容器 - 030 - 实现容器的底层技术

实现容器的底层技术

cgroup 和 namespace 是最重要的两种技术。

  • cgroup 实现资源限额
  • namespace 实现资源隔离

cgroup

  • cgroup 全称 Control Group。

Linux 操作系统通过 cgroup 可以设置进程使用 CPU、内存 和 IO 资源的限额。

  • 前面我们看到的--cpu-shares-m--device-write-bps 实际上就是在配置 cgroup。
  • cgroup 存在 /sys/fs/cgroup 文件中。

举个例子:启动一个容器,设置 --cpu-shares=512

在 /sys/fs/cgroup/cpu/docker 目录中,Linux 会为每个容器创建一个 cgroup 目录,以容器长ID 命名:

 1 [email protected]:~# docker run  --name container_C -it -c 512 progrium/stress --cpu 2
 2 stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
 3 stress: dbug: [1] using backoff sleep of 6000us
 4 stress: dbug: [1] --> hogcpu worker 2 [6] forked
 5 stress: dbug: [1] using backoff sleep of 3000us
 6 stress: dbug: [1] --> hogcpu worker 1 [7] forked
 7
 8 [email protected]:~# docker ps
 9 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
10 2200e14c5e1d        progrium/stress     "/usr/bin/stress --v…"   10 seconds ago      Up 9 seconds                                 container_C
11 f27eb6348026        registry:2          "/entrypoint.sh /etc…"   2 weeks ago         Up 2 weeks          0.0.0.0:5000->5000/tcp   vigilant_swartz
12 [email protected]:~#
13 [email protected]:~# ll /sys/fs/cgroup/cpu/docker/2200e14c5e1db5fafd029405f210fc2b208b62823cfd8cbdd7a50bdfe2cf6522/
14 total 0
15 drwxr-xr-x 2 root root 0 Jan 29 07:32 ./
16 drwxr-xr-x 4 root root 0 Jan  3 11:00 ../
17 -rw-r--r-- 1 root root 0 Jan 29 07:32 cgroup.clone_children
18 -rw-r--r-- 1 root root 0 Jan 29 07:31 cgroup.procs
19 -r--r--r-- 1 root root 0 Jan 29 07:32 cpuacct.stat
20 -rw-r--r-- 1 root root 0 Jan 29 07:32 cpuacct.usage
21 -r--r--r-- 1 root root 0 Jan 29 07:32 cpuacct.usage_percpu
22 -rw-r--r-- 1 root root 0 Jan 29 07:32 cpu.cfs_period_us
23 -rw-r--r-- 1 root root 0 Jan 29 07:32 cpu.cfs_quota_us
24 -rw-r--r-- 1 root root 0 Jan 29 07:31 cpu.shares
25 -r--r--r-- 1 root root 0 Jan 29 07:32 cpu.stat
26 -rw-r--r-- 1 root root 0 Jan 29 07:32 notify_on_release
27 -rw-r--r-- 1 root root 0 Jan 29 07:32 tasks
28 [email protected]:~# cat /sys/fs/cgroup/cpu/docker/2200e14c5e1db5fafd029405f210fc2b208b62823cfd8cbdd7a50bdfe2cf6522/cpu.shares
29 512
30 [email protected]:~#

目录中包含所有与 cpu 相关的 cgroup 配置,文件 cpu.shares 保存的就是 --cpu-shares 的配置,值为 512。

同样的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是内存以及 Block IO 的 cgroup 配置。

namespace

在每个容器中,我们都可以看到文件系统,网卡等资源,这些资源看上去是容器自己的。拿网卡来说,每个容器都会认为自己有一块独立的网卡,即使 host 上只有一块物理网卡。这种方式非常好,它使得容器更像一个独立的计算机。

Linux 实现这种方式的技术是 namespace。namespace 管理着 host 中全局唯一的资源,并可以让每个容器都觉得只有自己在使用它。换句话说,namespace 实现了容器间资源的隔离

Linux 使用了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User,下面我们分别讨论。

Mount namespace

Mount namespace 让容器看上去拥有整个文件系统。

容器有自己的 / 目录,可以执行 mount 和 umount 命令。当然我们知道这些操作只在当前容器中生效,不会影响到 host 和其他容器。

UTS namespace

简单的说,UTS namespace 让容器有自己的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通过 -h 或 --hostname 参数设置。

1 [email protected]:~# docker run -it -h myhost ubuntu
2 [email protected]:/#
3 [email protected]:/# hostname
4 myhost
5 [email protected]:/#

IPC namespace

IPC namespace 让容器拥有自己的共享内存和信号量(semaphore)来实现进程间通信,而不会与 host 和其他容器的 IPC 混在一起。

PID namespace

我们前面提到过,容器在 host 中以进程的形式运行。例如当前 host 中运行了两个容器:

1 [email protected]:~# docker ps
2 CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
3 2200e14c5e1d        progrium/stress     "/usr/bin/stress --v…"   38 minutes ago      Up 38 minutes                                container_C
4 f27eb6348026        registry:2          "/entrypoint.sh /etc…"   2 weeks ago         Up 2 weeks          0.0.0.0:5000->5000/tcp   vigilant_swartz
5 [email protected]:~# 

通过 ps axf 可以查看容器进程:

1  1015 ?        Ssl   11:01 /usr/bin/dockerd -H unix://
2 15084 ?        Sl     0:01  \_ /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.17.0.2 -container-port 5000
3  1023 ?        Ssl    7:15 /usr/bin/containerd
4 15090 ?        Sl     0:44  \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/f27eb6348026862f5744a916f67c4079d36c54fd4609
5 15108 ?        Ssl    1:28  |   \_ registry serve /etc/docker/registry/config.yml
6 24252 ?        Sl     0:00  \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/2200e14c5e1db5fafd029405f210fc2b208b62823cfd
7 24271 pts/0    Ss+    0:00      \_ /usr/bin/stress --verbose --cpu 2
8 24305 pts/0    R+    38:57          \_ /usr/bin/stress --verbose --cpu 2
9 24306 pts/0    R+    38:57          \_ /usr/bin/stress --verbose --cpu 2

所有容器的进程都挂在 dockerd 进程下,同时也可以看到容器自己的子进程。 如果我们进入到某个容器,ps 就只能看到自己的进程了:

 1 [email protected]:~# docker exec -it 2200e14c5e1d bash
 2 [email protected]:/#
 3 [email protected]:/# ps axf
 4   PID TTY      STAT   TIME COMMAND
 5     8 pts/1    Ss     0:00 bash
 6    15 pts/1    R+     0:00  \_ ps axf
 7     1 pts/0    Ss+    0:00 /usr/bin/stress --verbose --cpu 2
 8     6 pts/0    R+    41:49 /usr/bin/stress --verbose --cpu 2
 9     7 pts/0    R+    41:48 /usr/bin/stress --verbose --cpu 2
10 [email protected]:/# 

而且进程的 PID 不同于 host 中对应进程的 PID,容器中 PID=1 的进程当然也不是 host 的 init 进程。也就是说:容器拥有自己独立的一套 PID,这就是 PID namespace 提供的功能。

Network namespace

Network namespace 让容器拥有自己独立的网卡、IP、路由等资源。我们会在后面网络章节详细讨论。

User namespace

User namespace 让容器能够管理自己的用户,host 不能看到容器中创建的用户。

 1 [email protected]:~# docker exec -it 2200e14c5e1d bash
 2 [email protected]:/#
 3 [email protected]:/# useradd aaa
 4 [email protected]:/#
 5 [email protected]:/# id aaa
 6 uid=1000(aaa) gid=1000(aaa) groups=1000(aaa)
 7 [email protected]:/# exit
 8 exit
 9 [email protected]:~#
10 [email protected]:~# id aaa
11 id: ‘aaa’: no such user
12 [email protected]:~#

在容器中创建了用户 aaa,但 host 中并不会创建相应的用户。

小结

本章内容

  1. 容器的各种操作
  2. 容器状态之间如何转换
  3. 限制容器使用 CPU、内存和 Block IO 的方法
  4. 实现容器的底层技术:cgroup 和 namespace

下面是容器的常用操作命令:

  • create      创建容器
  • run         运行容器
  • pause       暂停容器
  • unpause     取消暂停继续运行容器
  • stop        发送 SIGTERM 停止容器
  • kill        发送 SIGKILL 快速停止容器
  • start       启动容器
  • restart     重启容器
  • attach      attach 到容器启动进程的终端
  • exec        在容器中启动新进程,通常使用 "-it" 参数
  • logs        显示容器启动进程的控制台输出,用 "-f" 持续打印
  • rm          从磁盘中删除容器

----------------引用来自------------------

https://mp.weixin.qq.com/s?__biz=MzIwMTM5MjUwMg==&mid=2653587673&idx=1&sn=476207c0186182ecdfa70256fbc9853a&chksm=8d3080c0ba4709d62f1b01d631c3456e2536d44207d1ed40947898f9efd2592cd79460a68e00&scene=21#wechat_redirect

原文地址:https://www.cnblogs.com/gsophy/p/10335682.html

时间: 2024-11-07 20:50:20

第 4 章 容器 - 030 - 实现容器的底层技术的相关文章

第14章 multimap多重映照容器

/* 第14章 multimap多重映照容器 14.1 multimap技术原理 14.2 multimap应用基础 14.3 本章小结 */ // 第14章 multimap多重映照容器 // 14.1 multimap技术原理 ------------------------------------------------------------------------------ // 14.2 multimap应用基础 ----------------------------------

第12章 multiset多重集合容器

/* 第12章 multiset多重集合容器 12.1 multiset技术原理 12.2 multiset应用基础 12.3 本章小结 */ // 第12章 multiset多重集合容器 // 12.1 multiset技术原理 ---------------------------------------------------------------------------- // 12.2 multiset应用基础 ------------------------------------

第七章 端口映射与容器互联

7.1 端口映射实现访问容器 7.1.1 从外部访问容器应用 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的. 当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P或-p参数来指定端口映射.当使用-P标记时,Docker会随机映射一个端口到内部容器开放的网络端口: [[email protected] ~]# docker run -d -P training/webapp python app.py f48059b82c2cbf0109

第 4 章 容器 - 027 - 限制容器对内存的使用

限制容器对内存的使用 一个 docker host 上会运行若干容器,每个容器都需要 CPU.内存和 IO 资源. 对于 KVM,VMware 等虚拟化技术,用户可以控制分配多少 CPU.内存资源给每个虚拟机. 对于容器,Docker 也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能. 内存限额 容器可使用的内存包括两部分: 物理内存 swap Docker 通过下面两组参数来控制容器内存的使用量. -m 或 --memory:设置内存的使用限额,例如 100

第五章 云原生与容器技术

第一节 独角兽成功秘诀 成功秘诀 ·Speed of innovation-天下武功,唯快不破 ·Always-available services-随时.随地可用 ·Web scale-从0到1,快速扩展 ·Mobile-centric user experiences-移动为王又快又好! 第二节 云原生和现代应用12范式 现代应用的十二范式(The Twelve-Factor App) 1.基准代码:一份基准代码,多份部署.基准代码和应用之间总是保持一一对应的关系.所有部署的基准代码相同,但

实现容器的底层技术 - 每天5分钟玩转 Docker 容器技术(30)

为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术.cgroup 和 namespace 是最重要的两种技术.cgroup 实现资源限额, namespace 实现资源隔离. cgroup cgroup 全称 Control Group.Linux 操作系统通过 cgroup 可以设置进程使用 CPU.内存 和 IO 资源的限额.相信你已经猜到了:前面我们看到的--cpu-shares.-m.--device-write-bps 实际上就是在配置 cgroup. cgroup 到底长什么

28-实现容器的底层技术

为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术.cgroup 和 namespace 是最重要的两种技术.cgroup 实现资源限额, namespace 实现资源隔离. cgroup cgroup 全称 Control Group.Linux 操作系统通过 cgroup 可以设置进程使用 CPU.内存 和 IO 资源的限额.相信你已经猜到了:前面我们看到的--cpu-shares.-m.--device-write-bps 实际上就是在配置 cgroup. cgroup 到底长什么

第十三篇:multimap容器和multiset容器中的find操作

前言 multimap容器是map容器的“ 增强版 ”,它允许一个键对应多个值.对于map容器来说,find函数将会返回第一个键值匹配元素所在处的迭代器.那么对于multimap容器来说,find函数将如何运作呢?如果要实现和map容器的find函数同样的功能,则它将返回多个迭代器,这样太复杂了.本文将讲解C++中multimap容器的“ find实现 ”. 解决思路一 摒弃find函数,使用另外两个新函数,它们是专家们为了解决multimap中的“ find操作 ”问题专门设计的: 1. lo

web容器与servlet容器

1. web容器好比   电视机 servlet容器好比   VCD 没有VCD你可以看电视,对吧,但是有了VCD没有电视机,你从哪看起?:) 没有servlet容器,你也可以用web容器直接访问静态页面,比如安装一个apache等,但是如果要显示jsp/servlet,你就要安装一个  servlet容器了,但是光有servlet容器是不够的,因为它要被解析成html输出,所以你仍需要一个web容器. 大多数servlet容器同时提供了web容器的功能,也就是说大多servelt可以独立运行你