Shifter: 面向高性能计算的容器
容器技术是一种操作系统层的虚拟化技术。它通过命名空间和 Cgroup 进行资源的隔离和控制,共享操作系统内核,分享系统资源。相比虚拟机,容器提供了一种更轻量级的虚拟化技术,它具有更高的资源利用率和更快的执行性能。Docker 作为一种容器技术,引入了应用镜像管理机制,适应快速的软件开发,部署和维护,推动了容器技术的普及和发展。
Shifter 容器的介绍
用于高性能计算的容器
在高性能计算领域,应用软件通常有大量的系统依赖和复杂的环境配置:各种的软件包,不同版本的库和操作系统的发布版本等。这让系统的部署和维护都面临巨大的挑战。传统的虚拟化技术可以解决部署和维护的问题,但是由于在计算上增加了额外的虚拟化负载,无法最大化利用机器的物理资源用于有效计算。而容器技术可以解决这些问题。
Docker 的镜像管理机制可以帮助用户将复杂的软件环境打包,便于管理和维护。容器的轻量级隔离性增强了系统的安全,而不会降低系统的计算性能。尽管如此,Docker 容器在高性能计算领域的采用也存在一些问题。Docker 的资源管理功能与集群管理软件的功能有重叠,Docker 独立的后台管理进程和集群系统的进程管理功能也有冲突。这使得高性能集群系统中采用 Docker 有诸多不便。例如采集容器消耗的资源和对容器状态的控制,都需要进一步的集成到资源管理系统。而 Docker 的用户权限提升问题又给生产环境引入了不安全的因素。
Shifter 是为了利用容器技术的优势,同时解决 Docker 在高性能计算环境下的问题而产生。它是美国国家能源研究科学计算中心 (NERSC) 开发的开源容器技术。通过复用现有容器技术(Docker) 的系统镜像,给高性能计算应用提供更有效的容器解决方案。
Shifter 的体系结构
Shifter 由两部分组成:命令行工具 (shifter, shifterimg) 和镜像管理器 (image gateway) 后台进程。命令行工具负责管理镜像和容器操作。镜像管理器根据镜像管理操作的请求,负责容器镜像的查找,下载和维护。
当 shifterimg 发出下载镜像请求,镜像管理器将从 Docker Registry 下载镜像到本地网络文件系统。在任何一个挂载网络文件系统的机器上,shifter 加载对应镜像,启动容器,运行应用程序。如图 1 所示。
图 1. Shifter 体系结构
镜像管理进程的模块是 Shifter 提供服务的后台进程。它提供了镜像管理的基本功能,并对外提供服务。如图 2 所示,它的实现包括以下模块:
- Restful API:提供管理服务的接口。
- Image Manager:负责维护镜像数据。
- Celery:管理和执行镜像下载任务。
- 相关数据库:用于存储管理和系统数据。
图 2. 镜像管理器体系结构
如图 2 所示,当接收到下载请求时,镜像管理模块查询本地数据库(MongoDB),如果请求镜像已经下载到本地存储,直接返回成功。如果尚未下载,镜像管理模块创建下载任务,交给 Celery 执行。Celery 创建任务,下载镜像后,将镜像文件解压。解压后的文件集合用于创建 squash 文件系统。Squash 文件系统是一种压缩格式的文件系统,可以有效减少文件存储占用大小。它作为一个单独文件存在,文件内部是一个包含了原始 Docker 镜像内部所有文件的根文件系统。
体系结构本身的设计为镜像管理进程提供了灵活的部署方式。例如图 2,系统 A 中的 Celery Worker 运行在可以直接访问网络文件系统的服务器节点。系统 B 中的 Celery Workers 运行在管理节点上,通过 SCP 将镜像文件拷贝到文件服务器上。这是一种更灵活的部署选择,但是因为数据重复拷贝,效率上会差一点。
镜像管理器是一种简单灵活的实现,它充分利用现有的第三方软件和库,例如 Celery,MongoDB,Redis,Squash 文件系统等。使用少量的功能逻辑代码,有效地实现了镜像的集中管理功能。松耦合带来部署的灵活性、简单性,确保了系统的有效稳定。
图 3. Shifter 容器体系结构
Shifter 容器主要依赖于 Linux 提供的系统接口。如图 3 所示, Shifter 容器构建在 kernel 上,应用程序运行于容器里的根文件系统环境。当 Shifter 构建一个容器时:
- 建立自己的文件系统命名空间(Linux namespace)。
- 将镜像文件系统以及用户请求的目录挂载到容器里。Shifter 直接从镜像存储目录加载镜像文件,以只读方式将镜像文件作为回环 (loopback) 设备挂载到容器中。镜像文件一般存储在网络文件系统中,这种挂载方式可以有效利用操作系统的文件缓存机制,加快访问文件系统中的数据。
- 为了保持应用运行环境一致性,环境变量也会被传递到容器。
- 通过 chroot()系统调用,将系统运行时环境切换到已经挂载的镜像文件系统中,完成容器启动,开始运行应用程序。
- 输出数据将会被写入主机映射到容器的目录里面,固化到磁盘中。
对于容器,由于 Shifter 是为高性能批处理作业系统设计的,它的运行时容器环境和一般意义上的容器,比如 Docker,在概念上有点不同。在隔离性上,Shifter 只使用了挂载点(mount points)命名空间,做了基本的文件系统隔离。容器相关的资源管理和资源控制都交给作业管理系统来处理。另外,Shifter 基于基本的隔离和 chroot()系统调用来实现容器,相比于 Docker 容器,这可以让它运行在很多旧的 Linux 发布版本中。这在注重系统稳定性,更新系统谨慎的高性能计算领域是很有用的。Shifter 的用户管理机制也很简单,运行容器的用户即是容器内操作的用户,容器内不存在权限提升问题。
Shifter 容器的安装和使用
在 Linux 中安装 Shifter
我们以 Ubuntu 系统为例,说明它的安装过程。
1.安装编译依赖
Shifter 需要进行编译安装。它依赖于基本的编译工具 gcc 和 make,同时需要工具集 libtool 和 autoconf。原代码编译依赖于库:libcap-dev, libmunge-dev, libcurl4-openssl-dev 和 libjson-c-dev.
清单 1. 获取依赖组件
1 | $ apt-get install libtool autoconf libcap-dev libmunge-dev libcurl4-openssl-dev libjson-c-dev |
2.下载源代码并编译安装 我们可以从https://github.com/NERSC/shifter下载最新的源代码并编译,安装。
清单 2. Shifter 源码安装
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ git clone https://github.com/NERSC/shifter Cloning into 'shifter'... remote: Counting objects: 6512, done. remote: Compressing objects: 100% (91/91), done. remote: Total 6512 (delta 49), reused 0 (delta 0), pack-reused 6421 Receiving objects: 100% (6512/6512), 1.46 MiB | 1.10 MiB/s, done. Resolving deltas: 100% (4241/4241), done. Checking connectivity... done. $ cd shifter $ ./autogen.sh $ ./configure $ make $ make install |
3.安装第三方支撑软件
Shifter 需要第三方软件的配合运行,这部分依赖主要用于支持镜像管理器。
清单 3. 安装第三方软件
1 2 3 4 | $ apt-get install mongodb munge redis-server redis-tools squashfs-tools $ apt-get install python-pymongo python-celery python-flask python-redis $ lsmod | grep squashfs squashfs 48362 0 |
4.配置 Shifter 系统
配置文件模版已经安装在系统里,我们通过拷贝,创建本地配置文件/usr/local/etc/定制镜像管理和容器管理行。
清单 4. 创建配置文件
1 2 | $ cp imagemanager.json.example imagemanager.json $ cp udiRoot.conf.example udiRoot.conf |
基本的安装过程到这里就结束了。接下来,还要做简单的配置:
- 创建系统镜像存储目录:
默认为/images。但是一般使用网络文件系统路径,便于多节点共享镜像文件。后台进程和 shifter 命令行都会使用这个目录存储和访问容器镜像。
- 配置 udiRoot.conf,设置 imageGateway 的地址和端口:
镜像管理工具 shifterimg 通过这个配置访问后台进程。
使用 Shifter 容器运行程序
在启动镜像管理器后,Shifter 的命令行可以让我们直接将程序运行在容器中。
1.启动镜像管理器服务
在命令行环境下,可以直接运行命令行启动镜像管理器后台进程和 Celery 工作者进程,如清单 4 所示。
清单 4. 启动镜像管理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $ python imagegwapi.py 2016-09-08 05:12:52,973 [shifter_imagegw.api] INFO : initializing with /usr/local/etc/imagemanager.json INFO:shifter_imagegw.api:initializing with /usr/local/etc/imagemanager.json < shifter_imagegw.imagemngr.imagemngr instance at 0x7f663871b638> 2016-09-08 05:12:53,266 [shifter_imagegw.api] INFO : initializing with /usr/local/etc/imagemanager.json INFO:shifter_imagegw.api:initializing with /usr/local/etc/imagemanager.json < shifter_imagegw.imagemngr.imagemngr instance at 0x7f261ce04638> $ celery worker -A shifter_imagegw.imageworker -Q mycluster -------------- celery@ host01 v3.1.6 (Cipater) ---- **** ----- --- * *** * -- Linux-3.16.0-30-generic-x86_64-with-Ubuntu-14.04-trusty -- * - **** --- - ** ---------- [config] - ** ---------- .> broker: redis://127.0.0.1:6379// - ** ---------- .> app: tasks:0x7f3532809250 - ** ---------- .> concurrency: 2 (prefork) - *** --- * --- .> events: OFF (enable -E to monitor this worker) -- ******* ---- --- ***** ----- [queues] -------------- .> mycluster exchange=mycluster(direct) key=mycluster [2016-09-08 04:36:34,004: WARNING/MainProcess] celery@host01 ready. |
2.获取所需镜像,执行程序
通过 shifterimg 命令,从 dockerhub 服务器上下载镜像到本地镜像管理系统。Shifter 命令启动容器,运行程序,如清单 5 所示。
清单 5. 启动容器
1 2 3 4 5 6 7 8 9 10 11 12 | $ shifterimg pull busybox 2016-09-23T01:50:54 Pulling Image: docker:busybox, status: READY $ shifterimg lookup busybox b05baf071fd542c3146f08e5f20ad63e76fa4b4bd91f274c4838ddc41f3409f8 $ shifter --image busybox sh / $ ls -l bin/busybox -rwxr-xr-x 369 root 0 1010960 Jun 23 20:13 bin/busybox / $ exit $ $ ls -l bin/busybox ls: cannot access bin/busybox: No such file or directory |
Shifter 提供基本的卷 (volume) 管理功能,可以将主机目录映射到容器中。但是目前难以自动将网络存储映射进容器。我们可以利用 Shifter 提供的可定制回调脚本 sitePreMountHook 来处理。用户可以通过自定义脚本,将网络文件系统挂载到容器里面。
LSF 中使用 Shifter
Shifter 是一个命令行工具,因此可以直接在作业提交中使用,作为作业命令行的一部分。
清单 6. 提交作业
1 2 | $ bsub shifter --image=busybox ./job.sh Job < 1 > is submitted to default queue < normal >. |
LSF 提供了一种更透明的容器使用方式。系统管理员配置 Shifter 的应用描述文件 (application profile)定制应用所使用的容器镜像名。用户直接提交作业到应用描述就可以将应用运行在容器里面。
清单 7. 查看 Application Profile 并提交作业
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ bapp -l container APPLICATION NAME: container -- Container application profile to running jobs in Shifter with ubuntu image STATISTICS: NJOBS PEND RUN SSUSP USUSP RSV 0 0 0 0 0 0 PARAMETERS: CONTAINER: shifter [image (ubuntu)] $ bsub -app container ./job.sh Job < 1 > is submitted to default queue < normal >. |
这种对用户的透明性为管理员提供了灵活管理方式。管理员可以根据需要,为作业配置不同的容器实现。LSF 不仅仅支持 Shifter,同时提供了 Docker 和 Singularity 的支持,只需要配置相应的应用描述就可以了。
结论
Shifter 是一种适用于高性能计算环境的开源容器技术。它简单易用,通过重用 Docker 镜像,提供了便捷的软件部署能力和丰富的现存软件镜像集。Shifter 通过网络文件系统统一管理本地镜像,本地主机以只读方式映射使用镜像,减少对网络文件系统原数据访问的频率,充分发挥网络存储性能。容器本身通过轻量级的命名空间隔离,减少容器之间的影响,便于和集群管理系统软件的集成使用。不过,在容器的隔离性,存储管理和镜像管理工具上,还有不少的局限,需要进一步增强。
参考资源
- 查看Shifter 论文,了解更多 Shifter 的设计思路和性能测试结果
- 查看Shifter 源码,了解更多 Shifter 的实现技术和细节
- 参考 IBM Spectrum LSF文档,了解更多 LSF 的最新功能
- 查看Docker 文档,了解 Docker 的功能
- 查看celery 官方网站,了解更多 celery 的信息和使用方法
- 查看 wikipedia,了解基本的loop device和chroot的概念