关于docker:什么是容器命名空间和cgroups

36次阅读

共计 2147 个字符,预计需要花费 6 分钟才能阅读完成。

当我第一次听到无关容器时,我的第一反馈是:这啥玩意?它是一个过程吗?Docker 是什么?容器就是 Docker 吗?救救可怜的孩子吧!
容器这个词指的并不是某种相当准确的事物,通常来说,几个 Linux 内核的个性(namespcescgroups)能让过程之间彼此隔离,而当你应用了这些个性失去了相互隔离的过程时,你能够将其称之为‘容器’。基本上,这些个性能让你伪装领有了一个相似虚拟机的货色,然而它们基本就不是虚拟机,它们仅仅不过是运行在同一 Linux 内核中的过程罢了,让咱们更深刻一点吧。

命名空间

好的,先假如咱们想要失去一个相似虚拟机一样的货色。有一个个性肯定想得到:我的过程应该跟其余的过程隔离开,是这样吧。
Linux 提供了这样的个性:namespaces。这有一堆不同的个性:
• 在 pid 空间中你变成了 PID 1,同时你的子过程变成了其余过程,而所有的其余程序隐没了。
• 在网络命名空间中你可能运行在任意不反复的端口上
• 在 mount 命名空间中你可能 mount 或者 umount 文件系统,只有不跟主机的文件系统抵触。所以你能够有齐全不同的 mount 设施集(通常更少)
事实证明创立 namespces 是相当容易的,你仅仅只须要运行一个叫 unshare 的程序(以雷同名称的零碎调用名命名)当初咱们创立一个新的 PID 命名空间,同时在外面运行 bash。

$ sudo unshare --fork --pid --mount-proc bash

产生了什么?

root@kiwi:~# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  28372  4148 pts/6    S    23:01   0:00 bash
root         2  0.0  0.0  44432  3836 pts/6    R+   23:01   0:00 ps aux

Wow,几乎就像发明了一整个世界,这里仅仅只有两个过程在运行:bash 和 ps,太酷了,这些都很容易。
值得注意的是,如果从惯例 PID namespace 的视角去看,我能看到新的 PID namespce 的过程:

root     14121  0.0  0.0  33264  4044 pts/6    S+   23:09   0:00 htop

这个过程的 id 是 14121(惯例 namespace),而在新的 PID namespace 中它的过程 id 是 3,所以它们是同一件事物的两个视角,仅仅是其中一个受到了更多的限度。

进入另一个程序的命名空间

你同样能够进入另一个正在运行的程序的 namespace,要做到这件事你只需应用一个叫 nsenter 的命令,我想这就是 docker exec 运行的原理,可能吧。

cgroups:资源限度

好的,咱们曾经通过与旧世界不同的新过程和套接字创立了一个新的魔幻世界,that’s cool! 如果我想限度一个程序应用多少内存或 CPU,该怎么办?很侥幸。在 2007 年,有人为咱们建设了 cgroup, 它们就像你用 nice 命令解决过程一样,然而比 nice 命令多了一大堆的个性,咱们来创立一个 cgroup,先应用它来限度内存

$ sudo cgcreate -a bork -g memory:mycoolgrou

来看看外面有什么

$ ls -l /sys/fs/cgroup/memory/mycoolgroup/
-rw-r--r-- 1 bork root 0 Okt 10 23:16 memory.kmem.limit_in_bytes
-rw-r--r-- 1 bork root 0 Okt 10 23:14 memory.kmem.max_usage_in_bytes

哦,要设置最大应用内存(单位:byte),好吧,来尝试设置一下,10M 对任何人来说应该够用了

$ sudo echo 10000000 >  /sys/fs/cgroup/memory/mycoolgroup/memory.limit_in_bytes

太棒了,来尝试应用下我的 cgroup!

$ sudo cgexec  -g memory:mycoolgroup bash

我跑了一堆命令它们都运行的很好,直到我尝试编译一个 rust 程序:) :) :)

$ root@kiwi:~/work/ruby-stacktrace# cargo build
error: Could not execute process `rustc -vV` (never executed)

Caused by:
  Cannot allocate memory (os error 12)

太精彩了,终于胜利地限度了程序的内存。

seccomp-bpf

好了,最初一个个性。如果要隔离过程,除了要限度它们的内存和 CPU 使用率之外,还可能要限度它们能够运行的零碎调用!例如网络拜访权限,这可能有助于进步安全性!咱们喜爱平安。seccomp-bpf,这是 Linux 内核的一个性能,能够为过程筛选哪些零碎调用能够应用。

什么是容器?

好的,既然你曾经看到了这两个个性,你可能会想:“Wow,是的,我能够围绕所有这些个性构建一堆脚本,并且有一些很棒的货色!”它将是真正的轻量级利用,并且我的过程将彼此隔离,Wow!有人过来也是这么认为的,他们构建了一个应用这些个性的叫做“Docker 容器”的货色。这就是 Docker 的全副!当然,现在 Docker 具备很多性能,但大多都是以这些根本的 Linux 内核个性为底本构建起来的。

正文完
 0