Linux Namespace资源隔离
Linux命名空间是全局资源的一种抽象,将资源发到不同的命名空间中,各个命名空间中的资源时相互隔离的。命名空间有以下几种类别
分类 | 系统调用参数 | 相关内核版本 |
---|---|---|
Mount Namespace | CLONE_NEWNS | Linux 2.4.19 |
UTS Namespace | CLONE_NEWUTS | Linux 2.6.19 |
IPC Namespace | CLONE_NEWIPC | Linux 2.6.19 |
PID Namespace | CLONE_NEWPID | Linux 2.6.24 |
Network Namespace | CLONE_NEWNET | 始于Linux 2.6.24 完成于2.6.29 |
User Namespace | CLONE_NEWUSER | 始于Linux2.6.23 完成于3.8 |
查看进程的namespace
1 | ls -l /proc/<pid>/ns |
CGroup资源限制
通过Namespace可以保证容器之间的隔离,但是无法控制容器可以占用多少资源,如果其中的某一个容器正在执行CPU计算密集型任务,那么就会影响其他容器任务的性能与执行效率,导致多个容器相互影响并且抢占资源。
CGroup(Control Group)就是能够隔离宿主机上的物理资源,例如CPU、内存、磁盘I/O和网络带宽。而我们需要做的就是把容器进程加入到指定的CGroup中。
UnionFS 联合文件系统
Linux Namespace和cgroup分别解决了容器的资源隔离与资源限制,那么容器是很轻量的,通常每台机器中可以运行几十上百个容器,这些容器可能会公用一个image。所以容器在启动的时候,不可能各自将这个image复制一份。Docker在内部使用镜像分层存储以及UnionFS来实现多个容器共用一个镜像。
镜像分层存储:docker镜像是由一系列的层组成的,每层代表Dockerfile中的一条指令,比如下面的Dockerfile文件:
1
2
3
4FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py这个dockerfile文件最终生成镜像的时候会生成四层,这四层是不可写的,而通过镜像实例化容器的过程,其实就是在就是在这四层之上添加了一个可写层,也就是我们通常说的容器层。而对容器层的操作,主要是利用了写时复制(CoW,copy on write)的技术。例如,如果当前操作会改变下面四层的某一层,docker会先将该层拷贝到容器层,然后再在容器层中进行操作。
UnionFS 其实是一种为Linux操作系统设计的,用于把多个文件系统联合到同一个挂载点的文件系统服务。