静茹docker容器的几种方法_Docker底层技术

Docker核心解决的问题是利用LXC来实现类似VM的功能,从而利用更加节省的硬件资源来提供给用户更多的计算资源。同VM的方式不同, LXC并不是一套硬件虚拟化的方法,是无法归属到全虚拟化、部分虚拟化和半虚拟化中的任意一个,而是一个操作系统级虚拟化方法,我们理解起来可能并不像VM那样直观。我们可以通过Docker要解决什么问题出发,看看Docker是怎样实现用户虚拟化需求的。

Docker容器的内核版本与宿主机的内核版本是一致的,而容器的主机名却是独立的,容器主机名缺省使用容器的ID。通过运行ps -ef命令,可以发现容器进程是隔离的,在容器内部是无法看到宿主机的进程,容器拥有自己的PID为1的进程;容器的网络也是隔离的,容器拥有独立的IP;容器的文件系统也是隔离的,容器拥有自己的系统和文件目录,在容器内修改文件并不能影响宿主机上对应目录的文件。

Docker实现以上的隔离机制都不是Docker的新技术,而是通过Linux kernel现有的技术实现的,主要包括:

  • 资源控制(CGroups)
  • 访问控制(Namespace)
  • 文件系统隔离(UnionFS)

1 资源控制

资源控制Control Groups(CGroups)能够隔离宿主机器上的物理资源,并对共享资源进行隔离、限制和审计,比如CPU、内存、磁盘I/O和网络带宽。每个CGroup可以是一组被相同的标准和参数所限制的进程,在不同的CGroup之间是存在层级关系的,它们可以从父级CGroup继承一些用于资源限制使用的标准和参数。只有控制了分配到容器的资源,才能避免多个容器在同时运行时对系统资源的争用。

Linux的CGroup可以为一组进程分配资源,通过对资源进行分配,CGroup可以提供以下几种功能:

  • 资源限制,可以对任务使用的资源总额进行限制
  • 优先级分配,通过分配CPU时间及磁盘I/O控制任务运行的优先级
  • 资源统计,可以统计资源的使用量
  • 任务控制,可以实现任务挂起、恢复等控制操作

子系统是CGroups中一个重要的概念,子系统可以理解为资源控制器,每种子系统就是一个资源的分配器,可以独立的控制一种资源。例如CPU子系统就是控制CPU分配的。每一个CGroup下面都有tasks文件,tasks文件中存储着属于当前控制组的所有进程的pid,如图1所示,如果用户需要控制Docker某个容器的资源占用情况,可以在Docker的控制组下面找到对应的子系统,并改变对应文件的内容。当然Docker提供了相应的指令在运行容器时由Docker进程去完成相应文件内容的变更;当我们关闭容器时,Docker子系统对应的文件夹会被Docker进程同步移除。

a3e36e969aa975ed9d4d59df948fb5d1.png

图1-资源控制

目前Docker使用了以下几种子系统:

  • blkio,可以为块设备设定I/O限制
  • cpu,可以控制任务对CPU的使用
  • cpuacct,记录CPU的使用情况
  • cpuset,为任务分配独立的CPU和内存
  • devices,开启或关闭对设备的访问
  • freezer,可以挂起或恢复任务
  • memory,可以设定任务对内存的使用上限,并自动记录内存资源使用情况
  • perf_event,可以进行统一的性能检测

2 访问控制

命名空间Namespaces可以有效地帮助Docker分离进程树、网络接口、挂载点以及进程间的通信等资源。每个容器都有自己单独的命名空间,运行在其中的应用都好像是在对立的操作系统中运行一样,命名空间保证了容器之间相互不会影响和被影响。

CGroups实现了资源的分配,而命名空间实现了系统资源的隔离。

Linux命名空间机制提供了以下几种不同的命名空间:

  • pid命名空间,用于隔离进程
  • net命名空间,用于隔离网络
  • ipc命名空间,用于隔离进程间通信
  • mnt命名空间,用于隔离挂载点
  • uts命名空间,用于隔离主机名和域名
  • user命名空间,用于隔离用户组

下面通过两个例子来介绍命名空间。一个是基于用户组的隔离,系统可以为UID为n的用户,虚拟出一个namespace,在这个namespace里面,用户具备root权限,然后在宿主机上该用户仍然是一个普通用户;另一个是基于进程的隔离,如图2所示在每个虚拟出的namespace内部,每个用户都拥有一个属于自己的进程ID为1的init进程,以及它的子进程。

678afc66ffc16cbf25413b8e86bbb6a9.png

图2-进程命名空间示意图

子进程命名空间的进程映射到父进程命名空间的进程上,在进程命名空间隔离下,子进程命名空间无法知道父进程命名空间的进程,而父进程命名空间可以知道子进程命名空间的所有进程。

3 文件系统隔离

联合文件系统UnionFS是Linux操作系统中用于支持将多个不同的文件目录挂载到同一个目录的技术。Docker支持的UnionFS包括AUFS、OverlayFS、devicemapper、vfs以及btrfs等。

Docker采用了分层构建的机制,最底层使用的bootfs,在这之上则是rootfs。bootfs包含了操作系统boot loader和kernel,主要用于系统引导,一旦完成引导,整个Linux内核加载到内存后会将bootfs层卸载,相同内核版本的不同Linux发行版的bootfs都是相同的,用户是不会修改这个文件系统的;rootfs是Docker容器的根文件系统,包含了典型的目录结构,如/dev、/proc、/bin、/etc、/lib、/usr和/tmp,这个文件系统在不同的Linux发行版中是不同的,用户可以对这些文件进行修改,当Linux系统启动时,rootfs首先会被加载为只读模式,当启动完成后被修改为读写模式。不同的Linux发行版,实现UnionFS所用到的技术也可能是不一致的,我们可以通过docker info命令查看当前系统上使用的是哪一类UnionFS实现技术。

下图3展示的是基于AUFS实现的联合文件系统示意图,启动容器时,Docker会在镜像上附加一层可写层,也被称作容器层,而在这一层之下都是只读的,所有对于容器运行时的修改都是在容器层完成的,也即是对这个容器层的修改。容器和镜像的最大区别在于,所有的镜像都是只读的,而每个容器则实际上就是镜像加上容器层,因而同一个镜像可以对应多个容器。

d68dab1d4029583497531d550eab345a.png

图3-Docker文件系统

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值