LXC 虚拟化调研

阿凡达2018-08-14 09:19

一、 LXC概述

LXC是一种较为轻量级的虚拟化技术,可以在单个宿主机节点上运行多个虚拟化单元(containers,容器),containers间通过Kernel Control Groupscgroups Kernel Namespaces技术相互隔离。从概念上而言,LXC可以看做一种改进的chroot技术。只不过一个chroot环境只隔离文件系统,而LXC则通过cgroups提供了更多的资源管理和隔离功能。同时,相对于XenKVM等虚拟化技术,LXC只是提供了操作系统级别的虚拟化技术,containers仍由宿主机内核来控制,而不是像XenKvm那样模拟一个完全独立的硬件环境来运行控制自己的虚拟机。

 

LXC具有如下优点:

通过containers(容器)来隔离应用程序和操作系统。

基于宿主机的kernelLXC可以实时地管理资源分配,因而提供了几乎等同于宿主机的性能

通过cgroups可以较好地来控制管理containers的网络接口及占用资源。

 

同时LXC也具有如下的限制:

所有的LXC容器都是运行在宿主机的内核上,也就是说同一宿主机节点上的LXC容器使用了相同的内核。

目前只支持Linux操作系统

LXC不是如同XenKVM的全虚拟化实现。

目前,在内核User NameSpace技术还不是很完善的情况下,LXC存在较大的安全隐患。

 

当前,网易云平台采用kvm作为底层的虚拟化技术。对部分应用诸如rds数据库等应用来说,kvm虚拟化相对来说比较重量级,对比LXC来说,性能方面有相当程度的下降。若LXC能够满足我们部分应用的虚拟化需求,同时风险可控,也不失为一种良好的解决方案。本文档就是基于此点进行调研分析。


二、LXC虚拟化需求及当前可选方案

从目前线上云平台环境的实际应用来看,云主机(采用KVM虚拟化技术)主要支持如下功能:

创建、删除云主机

重命名、启动、停止、重启云主机

Vnc登录云主机

云主机的规格调整和离线迁移

修改网络带宽、修改安全组

镜像管理

快照、快照恢复及快照管理

浮动ip使用

密钥的注入和使用

挂载、卸载云硬盘

部署负载均衡服务

 

此次LXC虚拟化调研分析主要参照上述功能来对可选的方案进行一个验证、评估及分析工作。从当前社区开发情况来看,支持LXC虚拟化的云平台方案有两种:Openstack + libvirt的组合、Openstack + docker组合。

 

其中,Openstack + libvirt的组合中,采用Libvirt 作为Openstacklxc虚拟化计算驱动。从当前Openstack社区的开发应用情况来看,这是一种主流的实现方式,也是公司当前基于kvm虚拟化构建云平台的实现方案。Libvirt已成为当前主流的虚拟化管理API,基本能够支持当前所有的虚拟化技术(如XenKVM等等),当然也包括LXCLibvirt LXC driver并不依赖sourceforge.net上通常所用的lxc用户态管理工具,而是直接构建了一个用户态工具libvirt_lxc,去调用相关的内核接口来构建管理containers。从libvirt社区开发情况来看,libvirt LXC driver的开发一直都比较活跃。

 

另外一种方案就是Openstack + Docker的组合。Docker项目是dotCloud公司(提供基础云平台服务)主持的一个开源项目,基于sourceforge.netlxc用户态工具,提供自动化部署管理LXC 容器的功能。Docker项目具备如下显著的特性:

文件系统隔离

Cpu及内存等资源的隔离(Cgroups

网络隔离(network namespace

文件系统支持Copy-on-write(需要安装AUFS文件系统)

可实时收集lxc容器的标准输出日志信息。

基于COW文件系统的快照功能

交互式shell

需要标明的是docker是用Go语言写的。

 

如果将上述两种方案做一个类比的话,两者间的关系如下表所示:

方案

云平台

云平台Compute Driver

Lxc 工具

Openstack + libvirt

Openstack

Libvirt

libvirt_lxc

Openstack + docker

Openstack

Docker

lxc

下面将具体对两种方案进行一个初步的验证分析,评估方案的风险和可行性。


三、Openstack + libvirt 方案

环境搭建

利用Devstack搭建Openstack环境,代码版本:

Openstack

社区最新的master分支

Libvirt(apt安装)

0.9.8/1.0.2

 

Nova.conf配置项设置:

libvirt_type = lxc

compute_driver = libvirt.LibvirtDriver

 

测试所用镜像:

http://uec-images.ubuntu.com/releases/precise/release/ubuntu-12.04.2-server-cloudimg-amd64.tar.gz


测试验证

参照当前Openstackkvm虚拟化所支持的功能,在搭建的环境上进行了如下的功能测试:

功能

是否支持

libvirt的版本要求

创建、删除云主机

 

重命名、启动、停止、重启云主机

 

Vnc登录云主机

不支持(但可以通过在虚拟机中配置vncserver方式实现),可以通过console来访问

 

云主机的规格调整和离线迁移

是(单一节点中验证)

 

查看虚拟机状态

不支持,需要新方案

 

修改网络带宽、修改安全组

 

镜像管理

 

快照、快照恢复及快照管理

暂不支持

 

浮动ip使用

 

密钥的注入和使用

 

挂载、卸载云硬盘

支持离线挂载(云主机关机状态下挂载)

Hotplug 挂卸载从libvirtlog来看1.0.2版本中有支持,但测试时存在问题,已向社区作者求助。原因已清楚,是因为AppArmor安全模块对libvirt权限进行了限制。

1.0.1 or 1.0.2

部署负载均衡服务

待测试

 

Cpu QoS

Ecu支持;

范围绑定,在社区最新补丁中有对cpuset的支持(1.0.4

 

网络 QoS

支持

 

实例存储QoS

部分支持,libvirt中只支持对lxc设置blkio.weight参数,原有的方案需进行略微的修正。

从测试结果来看,除了快照和虚拟机状态监控功能外,Openstack + libvirtlxc虚拟化的功能支持还比较完善。快照功能主要问题在于lxc的镜像运行后在宿主机上体现为一个文件系统,而不是kvmcow文件。而虚拟机状态监控,之前的方式是通过脚本在虚拟机中读取/proc信息,然后推送给监控。而现在lxc由于共用宿主机内核,容器中读取的/proc文件显示的是宿主机的proc信息。所以需要通过另外的方式来实现。

 

云硬盘挂载问题解决办法:(but libvirtd will run out of apparmor's control.

ln -s /etc/apparmor.d/usr.sbin.libvirtd /etc/apparmor.d/disable/ & /etc/init.d/apparmor restart


存在问题及风险

包括上述描述的快照及云主机状态监控两个功能问题外,Openstack + libvirt的方案中目前主要存在如下一些问题:

快照功能不支持。

原先的虚拟机状态监控方案存在问题

原先的Vnc登录云主机功能不支持,之前kvm虚拟化的vnc登录是通过qemu来实现的,lxc虚拟化中没有使用qemu。一种可行的方案是在lxc容器中部署vncserver

云硬盘只能支持在云主机关机状态下挂卸载,而且需要libvirt 版本在 1.0.1 or 1.0.2 以上。社区中1.0.2版本中已合入hotplug挂卸载设备的补丁,但测试时有问题,已向社区补丁作者求助。

Openstack采用了社区最新代码,如果在我们现有F版本来支持lxc,可能会需要更多的开发工作。

挂载云硬盘、cpu qos设置等功能,需要libvirt 1.0.4以上版本的支持,而debian package源目前的稳定版本是0.9.12-6。也就是说在debian package没有更新的情况下,需要自己来维护libvirt包。


社区开发情况

当前,Openstack社区的主流就是采用libvirt 作为compute driver,这个在kvm虚拟化中已经得到了充分的验证和实施。采用lxc虚拟化后,主要的问题集中在libvirt对于lxc的支持。而libvirt社区开发情况来看,主要以Daniel P. Berrange为首的开发人员,每天都有新的关于lxc的补丁提交。另外,Daniel P. Berrange也是nova项目的一个core viewer因此,可以说后续Openstack社区和libvirt社区对lxc的支持会持续完善下去。


四、Openstack + Docker 方案

环境搭建

利用devstack搭建openstack环境,Openstack源码采用社区master分支的最新代码。

安装docker:(有源码和包安装两种方式):

源码安装参考: https://github.com/dotcloud/docker#installing-from-source

包安装参考: http://docs.docker.io/en/latest/installation/(需要安装3.8内核升级包)

安装openstack-docker

参考: https://github.com/dotcloud/openstack-docker#how-can-i-use-it

修改nova.conf配置项:

compute_driver = docker.DockerDriver

libvirt_type = lxc

Docker提供的公共镜像:

https://index.docker.io/


测试验证

参照当前Openstackkvm虚拟化所支持的功能,在搭建的环境上进行了如下的功能测试:

功能

是否支持

创建、删除云主机

重命名、启动、停止、重启云主机

Vnc登录云主机

不支持(但可以通过在虚拟机中配置vncserver方式实现)

云主机的规格调整和离线迁移

不支持

查看虚拟机状态

不支持,需要新方案

修改网络带宽、修改安全组

镜像管理

快照、快照恢复及快照管理

浮动ip使用

密钥的注入和使用

不支持

挂载、卸载云硬盘

不支持

部署负载均衡服务

不支持

Cpu QoS

暂不支持,需开发

网络 QoS

支持

实例存储QoS

暂不支持,需开发

从上述功能测试的结果来看,相对于openstack + libvirt的方案,Openstack + dockerlxc虚拟化的支持相对较弱,但有一个比较显著的功能是快照功能,Docker项目基于AUFS文件系统,能够将文件系统的变化保存到一个新的镜像里,也即支持快照功能。另外,Docker项目底层是对sourceforge.netlxc用户态工具的封装。相对于libvirt_lxcsourceforge.net lxc用户态工具相对来说比较成熟。


存在问题及风险

除了上述的功能缺陷外,Openstack + Docker的方案还存在如下问题:

Docker项目需要Linux 3.8以上的内核版本支持

Docker中的快照功能要求安装AUFS文件系统

Docker项目与Openstack项目的融合还不是太成熟,融合OpenstackDockerOpenstack-docker项目已作为一个bp提交给了Openstack社区(https://blueprints.launchpad.net/nova/+spec/new-hypervisor-docker )但代码还在review中,且功能不太完善,ut等都缺乏。


社区开发情况

Docker项目作为dotCloud公司(提供基础云平台服务)主持的一个开源项目,提供自动化部署管理LXC 容器的功能。已经有上千个commits,发布了36个版本,有94个贡献者,Docker项目本身的功能应该来说日趋完善。但相对于libvirtopenstack等社区来说,活跃度还是差了点。另外,对比libvirt来说,Docker一个严重的缺陷就是与Openstack等开源云平台的接洽还不够好,目前还处于逐渐融入Openstack的起步阶段。且该项目Openstack-docker 比较不活跃,预计Docker作为一个虚拟化计算驱动融入Openstack的路程还有一大段距离。

 

五、总结

从上述的方案分析来看,Openstack + libvirt的组合方案目前来说比较可行,除快照功能不好解决外,其他大部分功能都支持,少部分如虚拟机状态监控需要新的方案。

此次调研分析主要关注Openstack平台对lxc虚拟化的支持。Lxc本身可能还存在一些问题,如:(下面表格是很早之前讨论的lxc的几个问题及解决方案的描述)

问题

可能的解决方案

在instance里top看到的是物理机的资源状况

这个问题出现的比较早,很早就有一些补丁有的在用户态做有的在内核态做,一直在争执那种方式比较好,不知道有没有个结果(方应)

Pid namespace可以解决(臧明杰)

max user processes限制会互相影响

这个问题有人在解决fork炸弹的时候有过补丁,其目的就是按lxc来限制进程数,不过ms还没有被接纳(方应)

无解(臧明杰)

磁盘空间限制方式用img方式限制带来的问题

这个也看到过一些折中的解决办法就是1、通过lvm的动态扩容,2、就是把lxc置于一块大盘的某个文件夹中,通过限制文件夹大小来限制;如果做到user namespace里面会更好(方应)

cgroup oom killer的死锁问题

 https://lkml.org/lkml/2012/10/16/168

执行service network restart导致网络挂掉的问题

这个问题可能还是net namespace虚拟化程度不够造成的,相关的现成的解决办法没有关注过 (方应)

instance里执行reboot的问题

(测试了一下,在lxc里面reboot,虚拟机会关机,但无法启动。目前来说,可以在外部通过Openstack来reboot lxc)

没弄清是要禁掉还是要执行,执行的话肯定是不能reboot宿主机的内核的,没有这个权限,不过只reboot自己的话还是可以做的,不过其意义和工具在外面reboot是一样的(方应)

可以使用user namespace限制lxc用户为非root用户(臧明杰)

挂载nfs时某些情况下导致load暴涨的问题

这个问题不是很清楚,因为是一个实际的问题(方应)

至于采用lxc轻量级虚拟化,相对kvm来说,性能方面到底有多大的提升,还需要通过测试去验证。

另外,lxc使用的一个最大风险是安全问题,关于这点,Openstack社区中,Daniel P. Berrange有一个比较清晰的描述,为了防止翻译的失误,将原文粘贴如下:

The Libvirt LXC functionality exposed by OpenStack is built on the kernel namespace & cgroup technologies. Until Linux 3.8, there has been no support for separate user namespaces in the kernel. As such, there has been no way to securely isolate containers from each other or the host environment using DAC (discretionary access control). For example, they can escape their resource constraints by modifying cgroups settings, or attack the host via various files in the proc and sysfs filesystems. The use of MAC (mandatory access control) technologies like SELinux or AppArmour can mitigate these problems, but it is not practical to write MAC policies that would allow running full OS installs in LXC under OpenStack.

Although initial user namespace support was merged in Linux 3.8, it is not yet complete, or mature enough to be considered secure. Work is ongoing to finish the kernel namespace support and enhance libvirt LXC to take advantage of it.



网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者管强授权发布。