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

当我第一次听到有关容器时,个人第一反应是:这啥玩意?它是一个进程吗?Docker是什么?容器就是Docker吗?救救可怜的孩子吧!
容器这个词指的并非某种至关精确的事物,一般来讲,几个Linux内核的特性(namespcescgroups)能让进程之间彼此隔离,而当你使用了这些特性获得了互相隔离的进程时,你能够将其称之为‘容器’。基本上,这些特性能让你伪装拥有了一个相似虚拟机的东西,可是它们根本就不是虚拟机,它们仅仅不过是运行在同一Linux内核中的进程罢了,让咱们更深刻一点吧。docker

命名空间

好的,先假设咱们想要获得一个相似虚拟机同样的东西。有一个特性必定想获得:个人进程应该跟其余的进程隔离开,是这样吧。
Linux提供了这样的特性:namespaces。这有一堆不一样的特性:
• 在pid空间中你变成了PID 1,同时你的子进程变成了其余进程,而全部的其余程序消失了。
• 在网络命名空间中你可以运行在任意不重复的端口上
• 在mount命名空间中你可以mount或者umount文件系统,只要不跟主机的文件系统冲突。因此你能够有彻底不一样的mount设备集(一般更少)
事实证实建立namespces是至关容易的,你仅仅只须要运行一个叫unshare的程序(以相同名称的系统调用名命名)如今咱们建立一个新的PID命名空间,同时在里面运行bash。安全

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

发生了什么?ruby

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的进程:bash

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,先使用它来限制内存ui

$ sudo cgcreate -a bork -g memory:mycoolgrou

来看看里面有什么spa

$ 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对任何人来讲应该够用了code

$ 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内核特性为蓝本构建起来的。
image.png

相关文章
相关标签/搜索