Docker的核心底层技术是LXC(Linux Container),Docker在其上面加了薄薄的一层,添加了许多有用的功能。
Docker提供了一种可移植的配置标准化机制,允许你一致性地在不同的机器上运行同一个Container;而LXC本身可能因为不同机器的不同配置而无法方便地移植运行;
Docker的主要目标是“Build, Ship and Run Any App, Anywhere”,即通过对应用组件的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)等生命周期的管理,达到应用组件级别的“一次封装,到处运行”。这里的应用组件,既可以是一个Web应用,也可以是一套数据库服务,甚至是一个操作系统或编译器。
Docker容器本质上是宿主机上的进程。Docker 通过namespace实现了资源隔离,通过cgroups实现资源限制,通过写时复制机制(Copy-on-write)实现了高效的文件操作。
一般,Docker容器需要并且Linux内核也提供了这6种资源的namespace的隔离:
- UTS : 主机与域名
- IPC : 信号量、消息队列和共享内存
- PID : 进程编号
- NETWORK : 网络设备、网络栈、端口等
- Mount : 挂载点(文件系统)
- User : 用户和用户组
- Pid namespace
用户进程是lxc-start进程的子进程,不同用户的进程就是通过pid namespace隔离开的,且不同namespace中可以有相同PID,具有以下特征: 1、每个namespace中的pid是有自己的pid=1的进程(类似/sbin/init进程) 2、每个namespace中的进程只能影响自己的同一个namespace或子namespace中的进程 3、因为/proc包含正在运行的进程,因此而container中的pseudo-filesystem的/proc目录只能看到自己namespace中的进程 4、因为namespace允许嵌套,父进程可以影响子namespace进程,所以子namespace的进程可以在父namespace中看到,但是具有不同的pid
- Net namespace
有了pid namespace ,每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过netnamespace实现的, 每个net namespace有独立的network devices, IP address, IP routing tables, /proc/net目录,这样每个container的网络就能隔离开来, LXC在此基础上有5种网络类型,docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge连接在一起
- IPC namespace Container中进程交互还是采用linux常见的进程间交互方法(interprocess communication-IPC)包括常见的信号量、消息队列、内存共享。然而同VM不同, container的进程交互实际是host具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息,每个IPC资源有一个唯一的32bit ID
- Mnt namespace 类似chroot ,将一个进程放到一个特定的目录执行,mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个namespace中的进程所看到的文件目录被隔离开了,同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace 的mount point
- Uts namespace UTS(UNIX Time sharing System)namespace允许每个container拥有独立地hostname和domain name,使其在网络上被视作一个独立的节点而非Host上的一个进程
- User namespace 每个container可以有不同的user和group id ,也就是说可以container内部的用户在container内部执行程序而非 Host上的用户
cgroups资源隔离
cgroup是Linux内核提供的一种机制,这种机制可以根据需求把一系列 任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。
cgroups不仅可以限制被namespace隔离起来的资源,还可以资源设置权重、计算使用量、操控任务(进程或线程)起停等。
cgroup可以限制、记录任务组成所使用的物理资源(包括CPU、Memoory、IO等)为容器实现虚拟化提供了基本保证。
从本质上来说,cgroups是内核附加在程序上的一系列钩子(Hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。
cgroups提供了以下四大功能:
- 资源限制: 可以对任务使用的资源的总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of memory)提示。
- 优先级分配 :通过分配的CPU时间片数量及磁盘IO带宽大小,实际上就相当于控制了任务运行的优先级。
- 资源统计:cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等,这个功能非常适用于计费。
- 任务控制: cgroups可以对任务执行挂起、恢复等操作。
Docker 分层存储(AUFS)
https://hujb2000.gitbooks.io/docker-flow-evolution/content/cn/basis/aufs.html