核心应用

  • Post category:云计算

一、命名空间
命名空间(namespace)是Linux内核一强大特性,为容器虚拟化的实现带来极大便利。利用这一特性,每个容器都可以拥有自己独立的命名空间,保证了容器之间彼此互不影响。
在操作系统中,包括内核、文件系统、网络、PID、UID、IPC、内存、CPU、硬盘等资源,所有资源都是应用进程直接共享的。要想实现虚拟化,除了要实现对内存、CPU、网络IO、硬盘IO、存储空间等限制外,还要实现对文件系统、网络、PID、UID、IPC等的相互隔离。前者相对容易实现一些,后者则需要宿主机系统的深入支持。

1、进程命名空间
Linux通过命名空间管理进程号,对于同一进程(即同一个task_struct),在不同的命名空间中,看到的进程号不相同,每个进程命名空间都有一套自己的进程号管理方法。进程命名空间是一个父子关系结构,子空间中的进程对于父空间是可见的。新fork出的进程在父命名空间和子命名空间将分别有一个进程号来对应。

2、网络命名空间
如果有了PID命名空间,那么每个命名空间中的进程就可以相互隔离,但是网络端口还是共享本地系统的端口。
通过网络命名空间,可以实现网络隔离。网络命名空间为进程提供了一个完全独立的网络协议栈的视图,包括网络设备接口、IPv4和IPv6协议栈、IP路由表、防火墙规则、socket等,这样每个容器的网络就能隔离出来。Docker采用虚拟网络设备的方式,将不同网络命名空间的网络设备连接到一起。默认情况下,容器中的虚拟网卡将同本地主机上的Docker0 网桥连接在一起。可以通过brctl show查看docker0 网桥上的虚拟网口。

3、IPC命名空间
容器中进程交互采用了Linux常见的进程间交互方法,包括信号量、消息队列和共享内存等。PID Namespace和IPC Namespace可以组合起来一起使用,同一个IPC命名空间内的进程可以彼此可见,允许进行交互;不同空间的进程则无法交互。

4、挂载命名空间
类似于chroot,将一个进程放到一个特定的目录执行。挂载命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名空间中的进程所看到的文件目录彼此被隔离。

5、UTS命名空间
UTS命名空间允许每个容器拥有独立的主机名和域名,从而可以虚拟出一个独立主机名和网络空间的环境,就跟网络上一台独立的主机一样。默认情况下,Docker容器的主机名就是返回容器的ID。

6、用户命名空间
每个容器可以拥有不同的用户和组ID,也就是说可以在容器内使用特定的内部用户执行程序,而非本地系统上存在的用户。每个容器内部都可以由root账号,但跟宿主机不在一个命名空间。通过使用隔离的用户命名空间可以提高安全性,避免容器内进程获取到额外的权限。

二、控制组
控制组(CGroup)是Linux内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免多个容器同时运行时对宿主机系统的资源竞争。控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制和计费管理。具体看来,控制组提供:

  • 资源限制: 可以将组设置为不超过设定的内存限制。比如:内存子系统可以为进程组设定一个内存使用上限,一旦进程组使用的内存达到限额在申请内存,就会发出OOM警告。
  • 优先级:通过优先级让一组优先得到更多的CPU等资源。
  • 资源审计:通过统计系统实际上把多少资源用到合适的墓地上,可以使用cpuacct子系统记录某个进程组使用的CPU时间。
  • 隔离:为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统。
  • 控制:挂起、恢复和重启动等操作。

安装Docker后,用户可以在/sys/fs/cgroup/memory/docker/目录下看到对Docker组应用的各种限制项,用户可以修改这些文件值来控制组限制Docker应用资源。可以在创建或启动容器时为每个容器指定资源限制,例如使用 -c|–cpu-shares[=0]参数来调整容器使用CPU的权重;使用-m|–memory[=MEMORY]参数来调整容器使用的内存大小。

三、联合文件系统
联合文件系统(UnionFS)是一种轻量级的高性能分层文件系统。它支持将文件系统中的修改信息作为一次提交,并层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,应用看到的是挂载的最终结果。Docker镜像自身就是由多个文件层组成,每一层有唯一的编号(层ID),可以通过docker history查看一个镜像由哪些层组成。

对于Docker镜像来说,这些层的内容都是不可修改的,只读的。而当Docker利用镜像启动一个容器时,将在镜像文件系统的最顶端在挂载一个新的可读写的层给容器。容器中的内容更新将会发生在可读写层。当所操作对象位于较深的某层时,需要先复制到最上层的可读写层。当数据对象较大时,往往意味着IO性能较差。因此,一般推荐将容器修改的数据通过volume方式挂载,而不是直接修改镜像内数据。

Docker所有的存储都在Docker目录下,Ubuntu为例,默认路径是/var/lib/docker。在这个目录下最重要的就是aufs目录,这是aufs文件系统所在,保存了Docker镜像相关数据和信息。该目录下包含layers、diff和mnt三个子目录。

  • layers子目录包含层属性文件,用来保存各个镜像层的元数据
  • diff子目录包含层内容子目录,用来保存所有镜像层的内容数据
  • mnt子目录是各个容器最终的挂载点,所有相关AUFS层在这里挂载到一起,一个运行容器的根文件系统就挂载在这个下面的子目录上

原文链接:https://www.cnblogs.com/hei-lon/p/16627533.html