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: 面向高性能计算的容器

镜像管理进程的模块是 Shifter 提供服务的后台进程。它提供了镜像管理的基本功能,并对外提供服务。如图 2 所示,它的实现包括以下模块:

  • Restful API:提供管理服务的接口。
  • Image Manager:负责维护镜像数据。
  • Celery:管理和执行镜像下载任务。
  • 相关数据库:用于存储管理和系统数据。
图 2. 镜像管理器体系结构

Shifter: 面向高性能计算的容器

如图 2 所示,当接收到下载请求时,镜像管理模块查询本地数据库(MongoDB),如果请求镜像已经下载到本地存储,直接返回成功。如果尚未下载,镜像管理模块创建下载任务,交给 Celery 执行。Celery 创建任务,下载镜像后,将镜像文件解压。解压后的文件集合用于创建 squash 文件系统。Squash 文件系统是一种压缩格式的文件系统,可以有效减少文件存储占用大小。它作为一个单独文件存在,文件内部是一个包含了原始 Docker 镜像内部所有文件的根文件系统。

体系结构本身的设计为镜像管理进程提供了灵活的部署方式。例如图 2,系统 A 中的 Celery Worker 运行在可以直接访问网络文件系统的服务器节点。系统 B 中的 Celery Workers 运行在管理节点上,通过 SCP 将镜像文件拷贝到文件服务器上。这是一种更灵活的部署选择,但是因为数据重复拷贝,效率上会差一点。

镜像管理器是一种简单灵活的实现,它充分利用现有的第三方软件和库,例如 Celery,MongoDB,Redis,Squash 文件系统等。使用少量的功能逻辑代码,有效地实现了镜像的集中管理功能。松耦合带来部署的灵活性、简单性,确保了系统的有效稳定。

图 3. Shifter 容器体系结构

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 通过网络文件系统统一管理本地镜像,本地主机以只读方式映射使用镜像,减少对网络文件系统原数据访问的频率,充分发挥网络存储性能。容器本身通过轻量级的命名空间隔离,减少容器之间的影响,便于和集群管理系统软件的集成使用。不过,在容器的隔离性,存储管理和镜像管理工具上,还有不少的局限,需要进一步增强。

参考资源

相关推荐