一、Redhat系列操作系统下的Docker

   Redhat系列操作系统(redhat、centos、fedora)与ubuntu是目前最为流行的两款Linux操作系统。由于ubuntu更为桌面化,通常生产环境中更多使用Redhat系OS。但是由于Redhat系内核版本较低,对虚拟化的支持总是落后一步。例如本文要分析的Docker,就是先支持ubuntu,直到2013年年底才支持redhat系OS。这就造成了一个略显尴尬的现实,虽然(截止目前)ubuntu对Docker支持更好,但是很多时候我们还是要在Redhat环境下使用Docker。

   目前,Redhat已与Docker深度合作,解决兼容性、安全等Docker的核心问题。考虑到二者的技术实力,我觉得他们的合作前景是比较乐观的。不过目前,如果在Redhat或Centos下实际操作Docker,会发现坑还是比较多的。今天,我就来尝试介绍其中的一个坑——Redhat下Docker、LXC、CGroup的协同配置。


二、Docker、LXC、CGroup三者的关系

   根据Docker布道师Jerome Petazzoni的说法,Docker约等于LXC+AUFS(之前只支持ubuntu时)。其中LXC负责资源管理,AUFS负责镜像管理;而LXC又包括cgroup、namespace、chroot等组件,并通过cgroup进行资源管理。所以只从资源管理这条线来看的话,Docker、LXC、CGroup三者的关系是:Cgroup在最底层落实资源管理,LXC在cgroup上封装了一层,Docker又在LXC封装了一层,关系图如图1.b所示。

Redhat下Docker、LXC、CGroup的协同配置_ cgroupRedhat下Docker、LXC、CGroup的协同配置_ Centos_02

(a)                                   (b)

图1 Docker-LXC-CGroup结构图


三、Docker、LXC、CGroup三者的协同部署与配置

   由于Docker、LXC、Cgroup的关系为嵌套依赖,所以如果需要实际部署使用Docker,需要搞定三者的协同配置。Docker没什么可说的,直接使用最新版本即可。LXC则有不同版本,且不同版本的运行情况明显不同。常用稳定版本有http://sourceforge.net/projects/lxc/files/lxc/网站上的0.7.5、0.9.0,除此之外,还有git上lxc的最新版本 https://github.com/lxc/lxc,目前为1.0.0beta2(未正式发布)。cgroup也有不同的挂载方法:“多挂载点”和“单挂载点”。了解cgroup的朋友都知道,cgroup有不同的子系统,例如cpu、memory、cpuset等等,“多挂载点”就是指不同子系统的文件挂载在不同的目录下,每个子系统各有一个挂载点,目录结构如图2所示。cgroup对应服务cgconfig默认使用的就是“多挂载点”的方法。“单挂载点”则是指所有子系统的文件都挂载在同一个目录下,所有子系统都统一挂载在一个挂载点,目录结构如图3所示。

Redhat下Docker、LXC、CGroup的协同配置_ LXC_03

图2 多挂载点目录示意图

Redhat下Docker、LXC、CGroup的协同配置_ Centos_04

图3 单挂载点目录示意图

   结合上述不同版本和不同挂载方法,Docker、LXC、CGroup在Redhat/CentOS上的部署方法汇总如表1所示。

表1

Docker

LXC

Cgroup

运行情况



0.7

0.7.5

单挂载点

正常

多挂载点

报错,形如 lxc-execute: nons_cgroup option specified lxc-execute: failed to spawn 'xxx' lxc-execute: Nosuch file or directory - failed to remove cgroup '/cgroup/cpuset/xxx'

0.9.0

单挂载点

报错,形如 lxc-execute: Error creating  cgroups   lxc-execute: failed to spawn 'xxx'。结合Docker运行将导致docker阻塞(卡主)

多挂载点

看似正常运行,但无法实现资源管理。cgrouplxc上层参数异常,无法通过lxc-cgroup等命令设置参数

1.0.0Beta2

Git最新版,未正式发布

单挂载点

正常

多挂载点

报错,形如 lxc-execute: Device or resource busy -  cgroup_rmdir: failed to delete /cgroup/ns/

lxc-execute:  failed creating cgroups lxc-execute: failed to spawn 'lxc1'

   先看表1前四行,其实在正式使用Docker之前,我已发现了这些问题。不过由于LXC的中文资料较少(介绍性资料有一些,实战性、有些深度的就比较少了),LXC英文社区又比较冷清,所以只发现一些朋友和我遇到了同样的问题,却没有靠谱的解决方法。好在“lxc-0.7.5 + cgroup单挂载点”是可以work的,我就是用这种配置方法进行工作。

   后来使用Docker,由于docker-0.7.2默认使用lxc-0.9.0.2,无法正常运行,我又重新捡起了这个问题。由于Docker社区比较热,在一篇来来往往十几个回合的帖子里找到了另一种解决方案,方法就是更新lxc。经实际测试,“Docker + lxc-1.0.0Beta2 + cgroup单挂载点”的方法可以正常运行。

Redhat下Docker、LXC、CGroup的协同配置_ Centos_05



四、Centos下Docker、LXC、CGroup的安装配置方法

   第三部分汇总了不同部署方法的运行情况,本节(第四部分)着重梳理下可行方法的步骤。实验证明,“Docker + lxc-0.7.5 + 单挂载点”与“Docker + lxc-1.0.0Beta2 + 单挂载点”方法均可行。

   实验环境:Centos6.3 + 内核2.6.32

   1、按照官方文档(http://docs.docker.io/en/latest/installation/rhel/),在Centos上安装docker。

   2、更新lxc。

   在lxc网站(http://sourceforge.net/projects/lxc/files/lxc/)下载lxc-0.7.5,或者在git(https://github.com/lxc/lxc)上 ,下载最新版的lxc,我下载时是1.0.0Beta2。下载后进行安装。由于Docker按照绝对路径/usr/bin/lxc-xxxx调用lxc命令,所以要把最新的lxc安装到/usr/bin目录下,或者安装后cp到/usr/bin/下。

   3、重新挂载cgroup。

   cgroup会默认采用“多挂载点”方式,并开机启动,所以首先禁用相应服务cgconfig,操作如下:

sudo service cgconfig stop
sudo chkconfig cgconfig off

   然后采用“单挂载点方式”重新挂载cgroup。可以直接手动挂载,这样当次挂载成功。

mount -t cgroup none /cgroup

   也可以编辑/etc/fstab/,之后每次开机后都会自动挂载。输入下列内容,重启就OK了。

none  /cgroup  cgroup  defaults  0 0

   在Redhat/Centos环境下安装Docker的具体方法,也可参见本人的另一篇博客《在Redhat/Centos下安装Docker(不升级内核)