Virtualization

LXC:Linux 容器工具

posted Mar 3, 2009, 1:34 AM by Liang Suilong

http://www.ibm.com/developerworks/cn/linux/l-lxc-containers/#resources

游览和设置新的容器工具 Linux Containers

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

将打印机的版面设置成横向打印模式

打印本页

将此页作为电子邮件发送

将此页作为电子邮件发送

英文原文

英文原文


级别: 中级

Matt Helsley, Linux 内核工程师, IBM

2009 年 3 月 02 日

容器可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。本文循序渐进地介绍容器工具 Linux® Containers(LXC)。作者在文中演示如何设置和使用它们。

容器有效地将由单个操作系统管理的资 源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心 CPU 本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化(paravirtualization)和系统调用替换中的复杂性。

通 过提供一种创建和进入容器的方式,操作系统让应用程序就像在独立的机器上运行一样,但又能共享很多底层的资源。例如,可以有效地共享公共文件(比如 glibc)的页缓存,因为所有容器都使用相同的内核,而且所有容器还常常共享相同的 libc 库(取决于容器配置)。这种共享常常可以扩展到目录中其他不需要写入内容的文件。

容器在提供隔离的同时,还通过共享这些资源节省开销,这意味着容器比真正的虚拟化的开销要小得多。

容 器技术早就出现。例如,Solaris Zones 和 BSD jails 就是非 Linux 操作系统上的容器。用于 Linux 的容器技术也有丰富的遗产,例如 Linux-Vserver、OpenVZ 和 FreeVPS。虽然这些技术都已经成熟,但是这些解决方案还没有将它们的容器支持集成到主流 Linux 内核。(要了解更多关于这些技术的信息,请查看 参考资料 小节)。

相比之下,Linux Resource Containers 项目(见 参考资料)则通过为主流 Linux 内核作贡献来实现容器。与此同时,这些贡献可能对成熟的 Linux 容器解决方案有用处 — 为更成熟的容器项目提供公共后端。本文简要介绍如何使用由 LXC 项目创建的工具。

为了充分利用本文,您应该熟悉使用命令行运行程序,例如 make、gcc 和 patch。此外,还应该熟悉 tarball(*.tar.gz 文件)的解压。

获取、构建和安装 LXC

LXC 项目由一个 Linux 内核补丁和一些 userspace 工具组成。这些 userspace 工具使用由补丁增加的内核新特性,提供一套简化的工具来维护容器。

在使用 LXC 之前,首先需要下载 Linux 内核源代码,应用适当的 LXC 补丁,然后构建、安装和启动它。最后再下载、构建和安装 LXC 工具。

我使用一个打了补丁的 Linux 2.6.27 内核(见 参考资料)。 虽然 2.6.27 Linux 内核的 lxc 补丁可能不适用于您喜欢的发行版的内核源代码,但是 2.6.27 以后的 Linux 版本可能已经包含该补丁提供的大部分功能。所以,强烈建议使用最新的补丁和主流内核源代码。而且,除了下载内核源代码并添加补丁外,还可以使用 git 获取代码:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/daveh/linux-2.6-lxc.git

在 kernelnewbies.org 可以找到关于如何为内核添加补丁,如何配置、构建安装和启动内核的指导说明(见 参考资料)。

LXC 需要一些特定的内核配置。为 LXC 适当配置内核的最容易的方式是使用 make menuconfig,然后选择 Container support。取决于内核所支持的特性,这样做会进一步选择一组其他配置选项。





回页首


可用的 LXC 环境

除了一个支持容器的内核外,还需要一些工具才能够简单地启动和管理容器。本文的容器管理工具来自 liblxc(从 参考资料 获取链接。另外,还可以使用 libvirt)。这个小节讨论:

  • liblxc 工具
  • iproute2 工具
  • 如何配置网络
  • 如何填充一个容器文件系统(构建定制的 Debian 容器,还是运行 ssh 容器)
  • 如何连接到容器文件系统(SSH、VNC、VT: tty、VT: GUI)

工具:liblxc

下载并解压缩 liblxc (见 参考资料),然后从 liblxc 目录中:

./configure --prefix=/
make
make install

如果您习惯于构建源 RPM,可以从网上下载一个(见 参考资料)。

工具:iproute2

为了在容器中管理网络接口,需要 2.6.26 或更高版本的 iproute2 包(见 参考资料)。如果您的 Linux 发行版没有这个包,请下载并按照说明配置和安装它。

配置网络

很多实用的容器的另一个关键部分是网络访问。目前,桥接(连接多个以太网区段,使它们成为一个单独的以太网区段)是将一个容器连接到网络的最佳方法。为了准备使用 LXC,我们将创建一个桥(见 参考资料),并使用它将我们真正的网络接口与容器的网络接口连接起来。

创建一个名为 br0 的桥:

brctl addbr br0
brctl setfd br0 0

用一个已有网络接口中的 IP(在本例中是 10.0.2.15)连接桥接口:ifconfig br0 10.0.2.15 promisc up。将已有的网络接口(在本例中是 eth0)添加到桥,并取消它与它的 IP 地址的直接关联:

brctl addif br0 eth0
ifconfig eth0 0.0.0.0 up

任何添加到桥 br0 的接口都将对那个 IP 地址作出响应。最后,确保默认的路由用 route add -net default gw 10.0.2.2 br0 将数据包发送到网关。以后,在配置容器时,指定 br0 作为通往外界的链接。

填充容器文件系统

除了网络外,容器常常需要它们自己的文件系统。取决于您的需要,有几种填充容器文件系统的方法。我将讨论其中两种:

  • 构建一个定制的 Debian 容器
  • 运行一个 ssh 容器

使用 debootstrap 命令构建一个定制的 Debian 容器 非常简单:

debootstrap sid rootfs http://debian.osuosl.org/debian/

如果要构建大量的容器,首先将包下载到一个 tarball 中可以节省时间,例如 debootstrap --make-tarball sid.packages.tgz sid http://debian.osuosl.org/debian/。这将产生一个 .tar 文件,这个文件约 71MB(压缩了 52MB),而一个根目录约 200MB。然后开始在 rootfs 中构建根目录:debootstrap --unpack-tarball sid.packages.tgz sid rootfs。(debootstrap 主页上有更多关于构建更小的或更适合的容器的信息)。

这将生成一个宿主容器高度冗余的环境(见 参考资料)。

运行 ssh 容器 可以大大减少容器文件系统占用的磁盘空间。例如,这种方法仅仅使用数 KB 就能在不同容器的 22 端口上运行多个 ssh 守护进程(参考资料 中提供了一个例子)。容器通过使用关键根目录来实现这一点,例如 /bin、/sbin 和 /lib 等的只读绑定挂载共享来自已有 Linux 系统的 sshd 包内容。这里使用一个网络名称空间,并创建基本的读写内容。

用于生成那些轻量级容器的方法与用于生成 chroot 环境的方法基本一样。不同之处在于只读绑定挂载和使用名称空间增强 chroot 环境的隔离性,使之成为有效的容器。

接下来,需要选择一种连接到容器的方法。

连接到容器

接下来的步骤是连接到容器。根据配置容器的不同方式,有几种方法可供选择:

  • SSH
  • VNC(GUI)
  • VT: tty(文本)
  • VT: X(GUI)

如果不需要用于容器的 GUI 接口,那么 通过 SSH 连接 就可以了。在此情况下,一个简单的 ssh 连接就足够了(参见上面的 “运行一个 ssh 容器”)。这种方法的优点是依靠 IP 寻址来支持创建任意数量的容器。

如果 ssh 连接花很长的时间才到达密码提示,那么在 DNS 查找期间 Avahi multicast DNS/Service Discovery 守护进程就可能超时。

通过 Virtual Network Computing(VNC)连接,这种方法可以为容器增加一个 GUI 接口。

使用 vnc4server 启动一个 X 服务器,该服务器只为 VNC 客户机服务。需要安装 vnc4server,以便从容器的 /etc/rc.local 文件运行它,如下所示:echo '/usr/bin/vnc4server :0 -geometry 1024x768 -depth 24' >> rootfs/etc/rc.local。当容器启动时,将创建一个分辨率为 1024×768 的 24 位色的 X 屏幕。接下来的连接很简单,如下所示:

vncviewer <ip>:<display>

如果容器与它的宿主共享 tty,那么 通过 VT: tty(文本)连接 就很有用。在这情况下,可以使用 Linux Virtual Terminals(VT)连接到容器。使用 VT 的简单用法是登录 tty 设备之一,然后这个 tty 设备将与 Linux VT 通信。登录进程被称作 getty。使用 VT 8:

echo '8:2345:respawn:/sbin/getty 38400 tty8'
>> rootfs/etc/inittab

一旦容器被启动,它将在 tty8 上运行 getty,以允许用户登录到容器中。可以通过类似的技巧,使用 LXC 工具重新启动容器。

这种方法不支持容器的图形化界面。而且,由于每次只有一个进程可以连接到 tty8,若要启用多个容器,则需要进一步配置。

通过 VT: X 连接 让您可以运行一个 GUI。在 VT 9 上运行 GNOME Display Manager(gdm),然后编辑 rootfs/usr/share/gdm/defaults.conf,将 FirstVT=7 替换为 FirstVT=9,以及将 VTAllocation=true 替换为 VTAllocation=false

虽然这样便可以使用一个图形化界面,但是仍然只能使用有限的几种 Linux 虚拟终端之一。





回页首


运行 LXC 工具

至此,您正在运行一个适当的内核,安装了 LXC 实用程序,并且有了一个可用的环境,接下来便可以学习管理该环境的实例了。(提示:LXC README 中更加详细地描述了这方面的大部分内容)。

LXC 使用 cgroup 文件系统来管理容器。在使用 LXC 之前,首先必须挂载这个文件系统:mount -t cgroup cgroup /cgroup。可以将 cgroup 文件系统挂载到任何地方。LXC 将使用 /etc/mtab 中挂载的第一个 cgroup 文件系统。

本文的后面将展示一些 LXC 基础知识和杂项内容,并讨论低级访问。

LXC 基础知识

对于使用 LXC 工具的基础知识,我们将看看:

  • 创建容器
  • 获得(或列出)关于已有容器的信息
  • 启动系统和应用程序容器
  • 向容器中运行的进程发信号
  • 暂停、恢复、停止和销毁容器

创建容器就是将一个名称与一个配置文件关联起来。该名称将用于管理容器:

lxc-create -n name -f configfile

这使得多个容器可以同时使用相同的配置文件。在配置文件中,可以指定容器的属性,例如它的主机名、网络、root 文件系统和 fstab。运行 lxc-sshd 脚本(该脚本创建一个配置)之后,ssh 容器配置如下所示:

lxc.utsname = my_ssh_container
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 10.0.2.16/24
lxc.network.name = eth0
lxc.mount = ./fstab
lxc.rootfs = ./rootfs

无论配置文件如何,用 LXC 工具启动的容器有自己的系统进程视图,以及自己的挂载树和可用的进程间通信(IPC)资源视图。

除了这些以外,当一个容器启动时,配置中未提到的任何类型的资源都被认为是与主机共享。这使管理员可以简洁地指定容器与其主机之间的关键不同点,并且使配置具有可移植性。

列出关于已有容器的信息对于管理已有容器非常重要。显示一个特定容器的状态:

lxc-info -n name

显示属于一个容器的进程:

lxc-ps

启动
LXC 根据容器类型的不同而有所不同:一种是系统容器,一种是应用程序容器。系统容器类似于虚拟机。与真正的虚拟化相比,虽然它们的隔离性要低一些,但是开销也降低了。直接原因是每个容器使用相同的 Linux 内核。为了类似于虚拟机,系统容器和 Linux 发行版一样在同一个地方启动,即通过运行 init 程序:

lxc-start -n name init

与系统容器相比,应用程序容器只是创建用于隔离一个应用程序的单独的名称空间。启动一个应用程序容器:

lxc-execute -n name cmd

发信号
将一个信号发送到在一个容器中运行的所有进程:

lxc-kill -n name -s SIGNAL

暂停
暂停一个容器在概念上类似于将 SIGSTOP 信号发送到一个容器中的所有进程。但是,发送虚假的 SIGSTOP 信号可能会迷惑一些程序。所以,LXC 通过 cgroup 接口使用 Linux 进程冻结器(process freezer):

lxc-freeze -n name

恢复
要恢复一个被冻结的容器:

lxc-unfreeze -n name

停止
停止一个容器将导致该容器中启动的所有进程全体死亡,并且清理容器:

lxc-stop -n name

销毁
销毁容器是指删除通过 lxc-create 步骤与名称关联的配置文件和元数据:

lxc-destroy -n name

杂项

下面是您可能想知道的一些其他内容(有些与监视有关)。

查看和调整容器的优先级:

lxc-priority -n name
lxc-priority -n name -p priority

持续观察容器的状态和优先级变化:

lxc-monitor -n name

Ctrl-C 停止监视容器。

还可以等待容器进入以 | 分隔的一组状态之一:

lxc-wait -n name -s states

等待除了 RUNNING 之外的所有状态:

lxc-wait -n name -s 'STOPPED|STARTING|STOPPING|ABORTING|FREEZING|FROZEN'

当然,这样将会立即返回。如果没有遇到意外错误,您应该期望只有当容器进入给定的状态时 lxc-wait 才返回。

低级访问

LXC 使用 cgroup 文件系统管理容器。可以通过 LXC 读和操纵 cgroup 文件系统的一些部分。要管理每个容器对 cpu 的使用,则可以通过读取和调整容器的 cpu.shares 来进行,如下所示:

lxc-cgroup -n name cpu.shares
lxc-cgroup -n name cpu.shares howmany





回页首


结束语

至此,这份指南已向您展示了如何掌握 Linux Containers 工具,您可以开始制作自己的有效资源分区。



参考资料

学习

获得产品和技术
  • SourceForge.net 上的 Linux Resource Containers 项目 是 Linux 内核应用程序容器实现的代码库,它集中了可发送到 linux 内核邮件列表的代码。

  • 下载 2.6.27 Linux kernel2.6.27 Linux 内核的 lxc 补丁

  • liblxc 中获取本文中使用的用于容器管理的主要工具。其中提供了一个 源 RPM

  • libvirt 是一个工具包和 Linux 虚拟化 API,用于提供管理虚拟机和容器实例的常用例程。无论这些实例使用用于虚拟化的 Xen、QEMU 或者 KVM,还是使用用于容器的 LXC 或 OpenVZ,libvirt 都可以正常工作。

  • 获得 2.6.26 或更新版本的 iproute2 包

  • 用可直接从 developerWorks 下载的 IBM 试用软件 构建您的下一个 Linux 开发项目。


讨论


关于作者


Matt Helsley 是 IBM Linux Technology Center 的软件工程师。

虚拟机桥接联网指南

posted Feb 20, 2009, 1:23 AM by Liang Suilong   [ updated Feb 20, 2009, 1:24 AM ]

虚拟机是Linuxer常用的一个软件,因为有些应用在Linux是无法完成,必须在虚拟机内完成。不过虚拟机联网确实是一个比较麻烦的问题。NAT虽然简单,但是不能和宿主机通信确实一个遗憾。所以桥接联网可以算是现在最好的方式。

eth0为静态IP的情况下
首先安装bridge-utils和tunctl
su -c 'yum install bridge-utils tunctl'
然后查看tun模块是否已经被加载
lsmod | grep tun
如果没有,则需要手动加载tun模块
su -c 'modprobe tun'

一切完成以后,则可以开始搭建桥接网络。首先是新建一个名为tap0的虚拟网卡,所有者为当前用户。
su -c ‘tunctl -t tap0 -u $USERNAME’
新建一个名为br0的网桥
su -c 'brctl br0'
使eth0进入promiscuous模式,不过执行此步之前最好记录原来eth0的IP,避免后面出现IP冲突。
su -c 'ifconfig eth0 0.0.0.0 promisc'
将eth0加入br0
su -c 'brctl addif br0 eth0'
设定br0的IP,最好使用原来eth0的IP,假设原来eth0的IP为192.168.1.1
su -c 'ifconfig br0 192.168.1.1 netmask 255.255.255.0'
删除原来旧的网关,设定新的网关,假定网关为192.168.1.1
su -c 'route del default'
su -c 'route add default 192.168.1.1 gw'
将tap0加入br0
su -c ‘brctl addif br0 tap0’

激活tap0
su -c 'ifconfig tap0 up'
设定tun设备的读写权限
su -c 'chmod a+rw /dev/net/tun'
然后在虚拟机的选择tap0作为网卡即可。

eth0为动态IP的情况下
eth0为动态IP的情况跟在静态IP的情况。基本一致。在保证dhclient已经被安装后,只需要把“设定br0的IP”、“删除旧网关”和“设定新网关”这三步替换为如下两步即可。

激活br0
su -c ‘ifconfig br0 up’

获取br0的IP
su -c ‘dhclient br0’
开机后自动搭建桥接网络
因为当机器重启或者关闭以后,设定的桥接网络就会自动被系统移除。所以当机器每一次重启的时候,都搭建一次桥接网络,就显得麻烦了。不过我们可以借用bash脚本来实现开机后自动搭建桥接网络。
以eth0为动态获取IP,桥接两个虚拟网卡为例
在$HOME目录新建一个vmbridge.sh文件,打开后把以下内容复制粘贴下去,并保存
#!/bin/bash
modprobe tun
tunctl -t tap0 -u $USERNAME
tunctl -t tap1 -u $USERNAME
brctl addbr br0
ifconfig eth0 0.0.0.0 promisc
brctl addif br0 eth0
ifconfig br0 up
dhclient br0
brctl addif br0 tap0
brctl addif br0 tap1
ifconfig tap0 up
ifconfig tap1 up
chmod a+rw /dev/net/tun
然后添加vmbridge.sh的执行权限
su -c ‘chmod +x $HOME/vmbridge.sh’
把该脚本添加到rc.local开机脚本去,实现开机自动构建桥接网络
su -c 'echo "$HOME/vmbridge.sh" >> /etc/rc.local'
或者
su -c ‘cat $HOME/vmbridge.sh >> /etc/rc.local’
注意事项
  1. 桥 接后,br0的IP就是宿主机的IP,而虚拟机的IP需要在虚拟机内设定。至于是动态IP还是静态IP,需要根据使用者的需要来设定。因为虚拟机桥接接入 局域网以后,虚拟机就相当于是局域网内的一台实体计算机,与宿主机平行,所以IP的设定要谨慎一些。如果宿主机是静态IP,而虚拟机是动态IP,那么请确 保局域网内有一台DHCP服务器来分配IP。
  2. 设定虚拟机IP的时候,请不要跟br0的IP相同,否则会造成IP冲突,导致宿主机或虚拟机不能连接网络。
  3. 如果出现虚拟机、宿主机和网关能够互相ping通,但虚拟机不能浏览网络等情况,请检查虚拟机的DNS设置。如果出现宿主机或虚拟机断开网络,请检查桥接网络中网桥是否连接好,网关是否设置好。
  4. 本方法适用于XEN、KVM、QEMU和版本较旧的VirtualBox。

VirtualBox使用指南

posted Feb 18, 2009, 10:41 AM by Liang Suilong

VirtualBox是德国一家软件公司InnoTek(现已被Sun收购)所开发的虚拟系统软件,它不仅具有丰富的特色,而且性能 也很优异。更是开源的,成为了一个发布在GPL许可之下的自由软件。VirtualBox 可以在 Linux 和 Windows 主机中运行,并支持在其中安装 Windows (NT 4.0、2000、XP、Server 2003、Vista)、DOS/Windows 3.x、Linux (2.4 和 2.6)、OpenBSD 等系列的客户操作系统。假如你曾经有用过虚拟机软件的经历的话,相信使用 VirtualBox 不在话下。即便你是一个新手,也没有关系。VirtualBox 提供了详细的文档,可以助你在短期内入门。

本文基于的是 Linux版本的VirtualBox-2.1.4

1.安装VirtualBox
打开VirtualBox的下载页面,下载相应版本的VirtualBox。
下载地址是:http://www.virtualbox.org/wiki/Downloads
下载完成后,根据各个Linux发行版的软件包管理方式,安装VirtualBox,以下是Fedora 9和Fedora 10的安装办法
打开终端,输入命令:
su -c ‘yum localinstall --nogpg VirtualBox-2.1.4_42893_fedora9-1.i386.rpm’

稍等片刻。当命令执行结束后再次输入命令
su -c '/etc/init.d/vboxdrv setup'

此步骤为重新编译VirtualBox的内核模块,以适应当前内核使用。执行此命令需要如下这些软件包:make、automake、autoconf、gcc、kernel-devel、dkms。如果未能确认你已经是否安装了这些软件包,请在终端执行一次如下命令。
su -c 'yum install make automake autoconf gcc kernel-devel dkms'

把当前用户加入到vboxusers组
su -c 'usermod -a -G vboxusers $USERNAME'

修正SELinux Permissions
su -c 'chcon -t textrel_shlib_t /usr/lib/virtualbox/VirtualBox.so'

这样,VirtualBox就基本能用了。

2.设置VirtualBox允许加载USB设备
新建一个usbfs组,并指定gid为502
su -c 'groupadd -g 502 usbfs'

把当前用户加入到usbfs组
su -c 'usermod -a -G vboxusers $USERNAME'

为USB设备重新设置权限
su -c 'echo"none /proc/bus/usb usbfs devgid=1002,devmode=774 0 0" >> /etc/fstab'

最后,在虚拟机的设置里启用USB控制器即可。

3.用USB设备启动虚拟机
假定你的USB设备是/dev/sdc
先添加USB的可读写权限
su -c ‘chmod o+rw /dev/sdc’

为USB设备建立虚拟硬盘镜像
su -c ‘VBoxManage internalcommands createrawvmdk -filename ~/.VirtualBox/VDI/UsbDisk.vmdk -rawdisk /dev/sdc -register’

最后,在Virtual Media Manager注册UsbDisk.vmdk,并设置为启动优先盘即可。

4.网络连接设定
A.NAT方式
NAT是最简洁的接入方式,只须点击两下鼠标,即可把虚拟机连接到外网。但是NAT方式并不能使Host机和Guest机通讯,这是NAT的方式的一个弊端。
在虚拟机设置里,点击网络的选项卡,在连接方式选择NAT,确定即可。
发件人 Linux


B.Host Interface方式
这 种方式又称之为桥接接入。以前VirtualBox使用桥接接入是十分麻烦的。但是自从Sun重新编写了VirtualBox的网络部分以后,一切变得简 单。桥接方式的最大好处在于虚拟机能直接接入到局域网,获得一个真实的局域网IP,与宿主机平等,并且能够和宿主机通讯。
现在的方法很简单,只需要把连接方式的选项卡设定为Host Interface,然后在下面Host Interface的选项卡选取你要把虚拟机桥接到哪个网卡,然后确定即可。
发件人 Linux


发件人 Linux

由于Virtualbox还不够完善,把虚拟机桥接到无线网卡,可能会出现失败的情况。具体情况请留意最新版本的VirtualBox用户手册。

C.Interal Network方式

Interal Network方式是把各个虚拟机连接起来的一个方式。由于较少人使用,所以这里就不再详述了。

5.安装增强工具包

安装增强工具包,可以使虚拟机运行得更畅顺,并且可以让你使用VirtualBox特有的无缝模式,摆脱虚拟机的条条框框,虚拟机运行的程序犹如置身于宿主机里。
1.如果虚拟机里安装的是Windows操作系统,则只需要虚拟机窗口上的设备,然后点击“安装增强功能...”,虚拟机系统就会自动弹出一个安装程序。用户按着提示安装,然后重启虚拟机即可。
2.如果虚拟机里安装的是Linux/UNIX系统,则先需要安装内核的相关库、头文件和编译器,然后点击“安装增强功能...”。虚拟机就会自动挂在一张增强功能的虚拟光盘,用户把对应的bin软件包编译了即可。
无缝模式的启动关闭键皆为Host+L,VirtualBox把右边的Ctrl建定义为Host键。

如以后有所更新,则另行通报。

1-3 of 3