1 libcontainer
Docker 从 0.9 版本开始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图如下:
2 命名空间 Namespaces
pid namespace
不同用户的进程就是通过 pid namespace 隔离开的, 且不同 namespace 中可以有相同 PID. 具有以下特征:
每个 namespace 中的 pid 是有自己的 pid=1 的进程 (类似 /sbin/init 进程)
每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程
因为 /proc 包含正在运行的进程, 因此在 container 中的 pseudo-filesystem 的 /proc 目录只能看到自己 namespace 中的进程
因为 namespace 允许嵌套, 父 namespace 可以影响子 namespace 的进程, 所以子 namespace 的进程可以在父 namespace 中看到, 但是具有不同的 pid
mnt namespace
类似 chroot, 将一个进程放到一个特定的目录执行. mnt namespace 允许不同 namespace 的进程看到的文件结构不同, 这样每个 namespace 中的进程所看到的文件目录就被隔离开了. 同 chroot 不同, 每个 namespace 中的 container 在 /proc/mounts 的信息只包含所在 namespace 的 mount point.
net namespace
网络隔离是通过 net namespace 实现的, 每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录. 这样每个 container 的网络就能隔离开来. docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge 连接在一起.
uts namespace
UTS ("UNIX Time-sharing System") namespace 允许每个 container 拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程.
ipc namespace
container 中进程交互还是采用 Linux 常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号量, 消息队列和共享内存. 然而同 VM 不同, container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互, 因此需要在 IPC 资源申请时加入 namespace 信息 - 每个 IPC 资源有一个唯一的 32bit ID.
user namespace
每个 container 可以有不同的 user 和 group id, 也就是说可以以 container 内部的用户在 container 内部执行程序而非 Host 上的用户.
有了以上 6 种 namespace 从进程, 网络, IPC, 文件系统, UTS 和用户角度的隔离, 一个 container 就可以对外展现出一个独立计算机的能力, 并且不同 container 从 OS 层面实现了隔离. 然而不同 namespace 之间资源还是相互竞争的, 仍然需要类似 ulimit 来管理每个 container 所能使用的资源 - cgroup.
3 资源配额 cgroups
cgroups 实现了对资源的配额和度量. cgroups 的使用非常简单, 提供类似文件的接口, 在 /cgroup 目录下新建一个文件夹即可新建一个 group, 在此文件夹中新建 task 文件, 并将 pid 写入该文件, 即可实现对该进程的资源控制. 具体的资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项. 另外, cgroups 中的 subsystem 可以随意组合, 一个 subsystem 可以在不同的 group 中, 也可以一个 group 包含多个 subsystem - 也就是说一个 subsystem.
memory
内存相关的限制
cpu
在 cgroup 中, 并不能像硬件虚拟化方案一样能够定义 CPU 能力, 但是能够定义 CPU 轮转的优先级, 因此具有较高 CPU 优先级的进程会更可能得到 CPU 运算. 通过将参数写入 cpu.shares , 即可定义改 cgroup 的 CPU 优先级 - 这里是一个相对权重, 而非绝对值
blkio
block IO 相关的统计和限制, byte/operation 统计和限制 (IOPS 等), 读写速度限制等, 但是这里主要统计的都是同步 IO
devices
设备权限限制
来源: http://www.bubuko.com/infodetail-2732288.html