文章目录
- namespace
- cgroups
虚拟技术基本要求就是资源隔离,简单的说就是我独占当前所有的资源。比如我在 8080 端口起 web 服务器,不用担心其他进程端口占用。linux 自带 namespace 就能达到这个目的。linux现有的namespace有六种:
docker通过clone()在创建新进程的同时创建namespace。
int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);
介绍其中三种:
- uts namespace
uts(unix time-sharing system)namespace提供了主机名与域名的隔离,这样每个docker容器就可以拥有独立的主机名和域名了,在网络上可以被视为一个独立的节点,而非宿主机上的一个进程。 - ipc namespace
进程间通信(inter-process communication,ipc)涉及的ipc资源包括常见的信号量、消息队列和共享内存。在同一个ipc namespace下的进程彼此可见,不同ipc namespace下的进程则互相不可见。 - pid namespace
pid namespace隔离非常实用,它对进程pid重新标号,即两个不同namespace下的进程可以有相同的pid。每个pid namespace都有自己的计数程序。内核为所有的pid namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace,它创建的心pid namespace被称为child namespace(树的子节点)。
通过这种方式,不同的pid namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。反过来,子节点却不能看到父节点pid namespace中的任何内容。
可以通过三个系统调用的方式
- clone,创建新的进程和新的namespace,新创建的进程 attach 到新创建的 namespace
- unshare,不创建新的进程,创建新的 namespace 并把当前进程 attach 上
- setns, attach 进程到已有的 namespace 上
shell 也提供了一个和系统调用同名的 unshare 命令可以非常简单的创建 namespace。
sudo unshare --fork --pid --mount-proc bash
这样创建了一个新的 pid namespace 并在里面运行了 bash。我们看看当前 namespace 的进程
在这个 namespace 里,就只有两个进程了。
docker 使用cgroups实现资源的配额管理。docker中的 cpu,内存,网络的限制均通过 cgroups 实现。
- 2007年由谷歌工程师研发
- 2008年并入 linux kernel 2.6.24
- c语言实现
cgroups 是 control groups 控制组的意思, 可以通过文件系统来访问这些信息。一般cgroups 挂载在 /sys/fs/cgroup
内核会读取这些信息来调度资源分配给每个进程。