- 最原始的隔离容器
- 只改变进程的文件系统(从而使得进程的环境发生变化),不改变其他
- 可以看到其他进程,打开网络,发送消息
- 经常配合用户权限控制系统做jail
- 但是在jail内的应用能够了解自己并没有root权限(例如无法新建用户)
- 多种对象隔离,例如IPC,网络
- 一个进程只能属于一个ns,一个ns可以拥有多个进程
- 进程的子进程默认属于同一个ns
- 有些东西不在隔离范围内
如果将用户隔离在ns内,删除CAP_SYS_ADMIN,删除对主机设备的访问,删除mount能力(以及其他适当权限)。即使是root用户也无法访问主机。因此,namespace配合chroot可以完美的切换用户环境。用户感知自己是root,可以做root权限的很多行为,例如添加删除用户。只有和系统有关的行为无法进行,例如加载内核模块。
隔离种类
- uts: 简单来说等价于hostname
- ipc: 共享内存,信号两,消息队列等
- pid: 进程编号
- mount: 可挂载的文件系统
- user: 用户/uid映射系统
- network: 网络设备隔离
虽然namespace可以隔离用户,但是却不能隔离用户的资源使用量。
cgroup主要是将环境所需资源尽量限制在一个范围内。
主要功能:
- 限制资源使用:例如内存使用上限,CPU亲缘性
- 控制优先级:例如CPU优先级
- 记账:例如内存水平和CPU使用情况
- 控制:挂起和继续
无法控制:
- 目前为止,最大CPU用量无法控制,只能控制CPU亲缘性。
- 就我测试的结果,内存用量和ps统计的值略有偏差。
结合namespace和cgroup做的虚拟机,和openvz类似。
docker在linux下使用lxc作为其底层,在windows下据说可以使用其他底层。
aufs是一个多层的混合文件系统(Union file system)。
- 多层的文件系统栈,可写的在最上
- 当读取文件时,从上到下查找
- 当写入文件时,写入最上层的可写系统。
- 如果可写系统内不存在原始文件,首先复制。
因此写入的数据会覆盖原始数据,形成一个可读写文件系统的假象。
经常被用来给只读设备加上临时的可写特性,例如Live CDs。
特性:
- 可以指定多个可读文件系统(有顺序)
- 可以指定一个可写文件系统
- 最高可达127层
- 原生文件级的读写效率
- 在文件查找时和复制原始文件到可写系统时有开销
docker是基于lxc和aufs实现的容器系统,其主要目标是专注于将环境带到不同的机器上。
换句话说,如果不是和环境有关的问题,并不需要使用docker。
- 镜像: 一个可运行的环境(例如文件系统),但尚未有任何程序载入内存。
- 容器: 载入内存的镜像,其中包含一个或多个镜像(层叠)。
- 仓库: 某个网络上的位置,通常是docker hub,也可以指定一个自己的服务器(register server)。
- tag: 标签,用来标记仓库中的某个特定版本。
每个镜像是一个文件系统,可以依赖于另一个文件系统。在实际使用的时候,将镜像和其依赖链组成aufs链条。因此新的镜像内容会覆盖老的(如果存在同名)。
将镜像内的任何一个程序载入内存运行,即成为容器。一个容器内至少需要包含一个进程,可以包含多个。
将镜像(和其依赖的链条)上传到某个文件服务器,该文件服务器即是仓库。一个仓库可以包含多个镜像,一般使用镜像的hash值的一部分作为镜像的ID。
为了简化仓库存取,为每个ID取的别名。
用以下指令启动一个容器。
docker run [-i] [-d] [仓库]:[tag] cmds
- -i: 交互模式。一般配合-t使用。
- -d: daemon模式。在后台启动程序并且detach。
PS. 如果镜像不存在,会从远程下载。
用以下指令终止容器。
docker stop [容器id]
用以下指令重新启动一个终止了的容器。
docker start [容器id]
以下指令停止一个容器再重新启动。
docker restart [容器id]
docker ps [-a]
- -a: 查看所有容器,包括已经终止的。
docker rm
PS. 容器必须已经终止,否则需要用-f强制终止后删除。
docker attach
docker pull [仓库]:[tag]
docker images
可以从现有镜像,启动为一个容器进行修改,最后再提交。
docker commit [容器ID] [仓库]:[tag]
也可以准备一个dockerfile,自动的从现有镜像修改提交。
docker build
也可以从本地文件导入。
cat files.tar.gz | docker import - [仓库]:[tag]
docker save -o filename.tar [仓库]:[tag]
docker load --input filename.tar
docker rmi [仓库]:[tag]
docker push
docker tag
重要的不是docker自身有什么优劣,而是和虚拟化相比有什么优劣。
- 高效的执行效率
- 灵活的主机内调度(其实就是隔离不完备)
- 差量传输更新(只需要更新依赖链上没有下载的部分)
- 没有成熟的管理工具
- 案例不够多
- 没有分布式存储系统
- 更弱的隔离
- 大型系统复杂的依赖
- docker发布一键安装
- 差量传输更新,方便升级
- 易于部署集群
- 易于最大利用集群资源
- 由于所有应用都是为同一个使用者服务,因此不存在单个应用“压死”其他应用的问题
用于做paas的通用中间层,解决调试和标准的问题。
- 在本地用docker调试和打包,远程可以在PaaS云上执行
- 由于环境标准化,用户不再担心被“锁定”在一家PaaS上
缺点:
- 由于缺乏隔离,因此在单台机器上的应用会影响到同机应用,为了解决性能问题,引发频繁迁移
- 同样由于缺乏隔离,因此无法限定最大使用量,只能限定请求数量
- docker并不完美,目前还缺少很多东西
- 一般不建议在企业环境中直接使用docker,而是将其作为工具的底层使用
- 即使目前并不使用,你也应当关注docker。因为将来他很可能改变和你有关的技术生态
- 增加分布式文件系统支持
- 增加灵活的网络支持(SDN)
- 官方的管理工具
- 基于docker的云平台系统
- 基于docker的发行版
- 基于docker的系统