1.虚拟化技术和容器的区别
虚拟化技术的分类
- 主机级别的虚拟化:虚拟的是整个物理硬件平台
- type-I: 直接在硬件平台上安装虚拟机管理器.不用在物理机上安装宿主操作系统,所有os都跑在虚拟机上.
- type-II: 硬件平台上先安装操作系统,然后在操作系统上安装虚拟机管理器.
- 容器级别的虚拟化.
正常的操作系统是一个内核空间,然后所有应用程序公用一个用户空间,所有进程共用一个namespace,共用所有系统资源.
因为共用所有系统资源和namespace,所以恶意进程容易攻击其他进程,进程之间容易互相干扰造成系统的不稳定.
而docker容器本质上是是宿主机上的进程,但docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制(copy-on-write)实现了高效的文件操作.
2. 容器底层进行隔离的原理
namespace是linux内核对os操作系统的各种资源进行隔离的系统调用.
为了解决所有进程共有一个操作系统的内核空间而互相影响,首先应该进行文件系统和根目录挂载点的隔离,这是对namespace里的mount的隔离.然后为了容器在互联网上的通信,需要有独立的ip,端口和路由,这是对namespace里的network的隔离.同时,容器还需要一个独立的主机名和域名以便在网络中标识自己,这是对namespace里的uts(UNIX Time-sharing System)的隔离.为了防止操作系统内别的进程对容器内进程的影响,通过对namesapace的pid进行隔离.当然也要对用户和用户组进行隔离,不然高权限的用户就会影响到容器的安全,这是namespace对user的隔离.最后,通过namespace可以对ipc,进程间通讯进行隔离.
在同一个namespace下的进程,共享上边的6种资源,而不在同一个namespace的进程,互相是一无所知的,就好像在不同的操作系统内一样.
3. namespace进行容器级别隔离的系统调用.
- 通过
clone()
来创建一个拥有独立namespaces的进程,这是docker使用namespace的基本方法
查看两个进程是否在同一个namespace下,可以查看/proc/pid/ns
文件里的namespace编号 - 通过
setns()
加入一个已经存在的namespace - 通过
unshare()
在原先进程上进行namespace隔离
4. namespace的6种隔离
1、UTS namespace
UTS(UNIX Time-sharing System) namespace提供主机名和域名的隔离,这样每个docker容器就可以拥有独立的主机名和域名,在网络上可以被视作一个独立的节点,而非宿主机上的进程了。
2、IPC namespace
进程间通信(Inter-Process Cmmunication,IPC)涉及的IPC资源包括常见的信号量、消息队列和共享内存。申请IPC资源就申请了一个全局唯一的32位ID,所以IPC namespace中实际上包含系统IPC标识符以及实现POSIX消息队列的文件系统。在同一个IPC namespace下的进程彼此可见。
3、PID namespace
Linux内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace。它创建的新的PID namespace称为child namespace(树的子节点),而原先的PID namespace就是新创建的PID namespace的parent namespace(树的父节点)。通过这种方式,不同的PID namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响,反过来,子节点却不能看到父节点PID namespace中的任何内容。
4、mount namespace
mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持,隔离后,不同mount namespace中的文件结构发生变化也互不影响。
5、network namespace
network namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4、IPv6协议栈、IP路由表、防火墙、/proc/net目录、/sys/class/net目录、套接字(socket)等。一个物理的网络设备最多存在于一个network namespace中,可以通过创建veth pair在不同的network namespace间创建通道,以达到通信目的。
6、user namespace
user namespace主要隔离了安全相关的标识符(identifier)和属性(attribute),包括用户ID、用户组ID、root目录、key(密钥)以及特殊权限。
cgroups资源限制
1、什么是cgroups?
cgroups是Linux内核提供的一种机制,这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。
本质上来说,cgroups是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。
2、5cgroups的作用
- 资源限制:cgroups可以对任务使用的资源总额进行限制,如任务使用资源超出配额就会发出OOM(out of memory)的提示。
- 优先级分配:通过分配的CPU时间片数量及磁盘IO带宽大小控制任务运行的优先级。
- 资源统计:cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等。
- 任务控制:cgroups可以对任务执行挂起、恢复等操作。