Docker in LXC踩坑

LXC-Docker

我们知道Docker是如今炙手可热的应用级容器,而LXC可以看作是系统级的容器。那么问题来了,是否可以在一个系统级的容器里面运行一个应用级的容器呢?答案是可以的,不过过程并没有想象的那么容易,百般折腾后部署成功了,在这个过程中也发现了一些问题。

遇到的问题

  1. Docker无法启动
  2. Docker中无法pull镜像
  3. 配置文件中配置项升级后不兼容
  4. 容器内Redis无法启动

Docker无法启动

在LXC容器中安装Docker后始终无法启动,最后发现是系统的问题,这里不是宿主机的系统有问题,而是LXC的系统。测试发现Ubuntu系统可以正常启动Docker,而CentOS则不行

Docker中无法pull镜像

使用docker pull命令拉取镜像,当镜像下载完成后会提示failed to register layer: ApplyLayer exit status 1 stdout: stderr: permission denied导致无法完成镜像的下载。造成这个问题的原因是没有解除apparmor限制,在启动lxc容器之后,需要执行下列命令:

NOTE: $HOST修改为对应的容器主机名

1
2
3
4
5
cat >>/var/lib/lxc/$HOST/config <<EnD
lxc.aa_profile = unconfined
lxc.cgroup.devices.allow = a
lxc.cap.drop =
EnD

NOTE: lxc.aa_profile = unconfined应该更正为lxc.apparmor.profile = unconfined,下文会提到

然后修改/etc/pve/lxc/$HOST.conf文件,在文件末尾加上以下内容:

1
2
lxc.hook.mount =
lxc.hook.post-stop =

配置文件中配置项升级后不兼容

LXC配置文件中配置项名称发生了变化,导致启动报错:

1
2
The configuration file contains legacy configuration keys.
Please update your configuration file!

好在LXC为我们提供了自动升级配置文件的工具lxc-update-config,切换到容器对应的配置文件目录下: cd /var/lib/lxc/$HOST。使用命令对配置文件进行升级:

1
lxc-update-config -c config

其中lxc.aa_profile = unconfined被自动更正为了lxc.apparmor.profile = unconfined

Redis无法启动

造成该问题的原因是redis的systemd启动脚本中试图使用一些高级权限,修改/etc/systemd/system/redis.service脚本中下列内容后即可正常使用:

1
2
3
PrivateTmp=no
PrivateDevices=no
ProtectHome=no

性能测试

那在LXC中运行docker性能如何呢?找了几个常见的工具进行性能测试,UnixBench综合测试性能几乎完全一致,fio磁盘测试性能几乎无损耗,性能差距仅1%,Redis-benchmark数据降低约10%(结果仅供参考)

测试工具

  • UnixBench:

UnixBench

  • fio

FIO

  • redis-benchmark

Redis-benchmark

性能测试方案参考:https://serverscope.io/trials/GdEN#network


LXC的缺点

  • LXC社区热度远不如Docker,这导致除了问题能查询的有效资料并不如Docker丰富,当然也没有像Docker那么丰富的镜像资源。
  • LXC还存在跨不同Linux发行版的功能支持不一致,LXC主要在Ubuntu平台上进行维护和开发。例如目前只有Ubuntu上通过apt-get install docker.io安装的Docker能无需加载任何内核补丁正常运行。
  • LXC的官方文档不够详细,学习成本比Docker高。

参考文档

坚持原创技术分享,您的支持将鼓励我继续创作!