Linux容器虚拟技术LXC简明手册

时间:2021-06-30 14:47:16


LXC容器虚拟化

经过一些折腾,初步在自己的工作笔记本上部署了LXC虚拟。这是一个非常轻量级的虚拟解决方案,特别适合硬件有限的测试环境,也是我们系统管理员技术锻练的良好环境。

一些介绍信息,请参考 Linux容器虚拟化技术介绍

安装

以下安装实践是在Gentoo x86_64平台上实现的,如果采用Red Hat系统或Debian,应该只是在软件安装上有区别,但使用配置方法应该相同。

 

安装lxc用户工具

  • 同步portage树
1
emerge --sync
  • 由于当前LXC 软件包被masked (尚不成熟),所以需要手工去除屏蔽。
1
2
echo app-emulation/lxc >> /etc/portage/package.unmask
echo app-emulation/lxc >> /etc/portage/package.keywords
  • 安装
1
emerge -av lxc

当编译安装完成时,可能会看到列出的内核参数有哪些没有被激活。
完整的内核要求如下

# namespaces
CONFIG_NAMESPACES / "Namespaces"
CONFIG_UTS_NS / "Utsname namespace"
CONFIG_IPC_NS / "Ipc namespace"
CONFIG_PID_NS / "Pid namespace"
CONFIG_USER_NS / "User namespace"
CONFIG_NET_NS / "Network namespace"
DEVPTS_MULTIPLE_INSTANCES / "Multiple /dev/pts instances"





# control groups CONFIG_CGROUPS / "Cgroup" CONFIG_CGROUP_NS / "Cgroup namespace" CONFIG_CGROUP_DEVICE / "Cgroup device" CONFIG_CGROUP_SCHED / "Cgroup sched" CONFIG_CGROUP_CPUACCT / "Cgroup cpu account" CONFIG_CGROUP_MEM_RES_CTLR / "Cgroup memory controller" CONFIG_CPUSETS / "Cgroup cpuset" # misc CONFIG_VETH / "Veth pair device" CONFIG_MACVLAN / "Macvlan" CONFIG_VLAN_8021Q / "Vlan"

将以上配置添加到内核编译配置文件中重新编译内核。Red Hat 和 Debian尚没有实践,不过发行版本通常会通过模块方式或预编译支持这些参数,可能不需要调整。

安装Guest操作系统

在网络配置上,是将虚拟机的虚拟交换机br0 和虚拟网卡dummy0 绑定,这样可以不占用公司网络资源作为虚拟内网运行。如果要将虚拟机对外提供服务,则绑定实际物理网卡如eth0

  • 设置网络

配置 /etc/conf.d/net




1
2
3
4
bridge_br0="dummy0"
config_dummy0="null"
config_br0="10.1.11.1/32 brd 10.1.11.255"
routes_br0="10.1.11.0/24 via 10.1.11.1"




然后设置软连接

1
2
cd /etc/init.d
ln -s net.lo net.br0

启动

1
/etc/init.d/net.br0 start
  • 要允许容器中主机访问外部
1
2
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sysctl -w net.ipv4.ip_forward=1

cgroup挂载设置

设置cgroup 挂载(参考 http://lxc.teegra.net/

1
2
mkdir -p /cgroup
mount none -t cgroup /cgroup

为每次启动系统时自动挂载,在/etc/fstab 中添加

1
none            /cgroup     cgroup      defaults    0 0

案例安装

https://www.granite-mtn.net/xwiki/bin/view/Howto/Linux+Containers 提供了各种guest安装的案例,比较简单易用。
https://www.ibm.com/developerworks/linux/library/l-lxc-containers/ 是IBM发起的LXC项目,详细介绍了如何build一个debian系统

安装debian虚拟机

  • 安装debootstrap 工具
1
emerge dev-util/debootstrap
  • 创建一个debian容器

sid 是debian的unstable版本代号,不过debian的unstable相比较很多其他发行版本,已经是很稳定的版本了。只不过debian质量 控制要求很高,stable版本往往选择“久经考验”的软件版本所以不能尝试最新的开源技术,采用debian的unstable版本可以使用最前沿的开 源技术,对于我们日常应用已经足够稳定。对于服务器部署,可以采用stable版本。

1
mkdir -p /lxc/debian
1
debootstrap sid /lxc/debian http://ftp.us.debian.org/debian/

如果要创建大量的container,则可以生成一个tar包以便今后安装

1
debootstrap --make-tarball=sid.packages.tgz sid http://debian.osuosl.org/debian/
  • 配置文件/etc/lxc/lxc-debian.conf
1
2
3
4
5
6
7
8
9
10
11
# Container with network virtualized using a pre-configured bridge named br0 and
# veth pair virtual network devices
lxc.utsname = debian
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:bf
lxc.network.ipv4 = 10.1.11.2/24
lxc.network.name = eth0
lxc.mount = /lxc/debian/fstab
lxc.rootfs = /lxc/debian
  • 配置启动挂载/lxc/debian/fstab
1
2
3
/dev  /lxc/debian/dev none bind 0 0
/dev/pts /lxc/debian/dev/pts  none bind 0 0
#/proc/self/fd/0 /lxc/debian/dev/console none bind 0 0
  • 创建容器
1
lxc-create -n debian -f /etc/lxc/lxc-debian.conf
  • 启动容器
1
lxc-start -n debian

不过,实践中也存在一个问题:没有出现终端。
这个问题我尚未解决,应该和我的Gentoo主机系统的内核有关,我自己的VPS系统也存在这样的问题,还需要查找一下原因。
根据 http://lxc.teegra.net/ 说明, udev 是不能在lxc虚拟容器中工作的。参考 http://wiki.debian.org/udev ,在debian中,udevd 服务,是由于初始化脚本 /etc/rcS.d/udev 启动的,配置文件为 /etc/udev/udev.conf

1
2
cd /lxc/debian/etc/rcS.d
ls -l S02udev
lrwxrwxrwx 1 root root 14 Sep 12 21:34 S02udev -> ../init.d/udev

删除这个启动脚本

1
rm S02udev

有关debian/ubuntu虚拟机安装

http://sourceforge.net/projects/lxc-provider/ 提供了debian和ubuntu的基础container包,可以下载作为debian系列的基础虚拟容器,并进一步安装调试。

安装fedora虚拟机

http://people.redhat.com/~rjones/febootstrap/ 提供了类似Debian debootstrap的工具 febootstrap,可以用来生成fedora基本安装的虚拟机,不过和debootstrap相比,当前尚有一些限制。
根据”About febootstrap”说明有:

    • febootstrap是一个创建Fedora启动文件系统的工具,类似debootstrap ,不需要以root用户身份运行。
    • febootstrap提供了工具来直接创建 initrd.img 映像(initramfs ),并且通过删除一些不需要的文件来减小系统空间占用。

依赖软件:

    • fakeroot
    • fakechroot >= 2.9
    • yum
    • perldoc 只用于生成文档
    • bash
    • gcc
    • libext2fs
    • /sbin/mke2fs 是e2fsprogs的一部分

我使用的是Gentto操作系统,采用如下方法安装依赖

1
emerge sys-apps/fakeroot sys-apps/fakechroot sys-apps/yum

perldoclibext2fsmke2fs 在常规的Gentoo安装中已经具备。




1
2
3
4
5
6
wget http://people.redhat.com/ ~rjones/febootstrap/files/febootstrap-2.9.tar.gz
tar xfz febootstrap-2.9.tar.gz
cd febootstrap-2.9
./configure
make
make install




  • 安装基本系统

我这里安装的是fedora 13 x86_64

1
2
mkdir /lxc/fedora-13
febootstrap fedora-13 /lxc/fedora-13

以上安装fedora的方法仅供参考,我在实践中尚存在问题(执行时python脚本错误),但总体思路应该是正确的,有待后续解决。

采用vserver的虚拟机作为LXC的虚拟机

我以前一直使用VServer作为容器虚拟机,现在转到LXC平台后,准备继承使用以往已经构建好的VServer虚拟机。
在网上,已经有人提出可以使用OpenVZ虚拟机(也是一种容器虚拟机技术)作为LXC的虚拟机,以此类推,我相信也能够使用VServer虚拟机来转换为LXC虚拟机。
经过一些摸索,通过修改启动sysinit 脚本,实现了VServer虚拟机的转换。

  • 原本VServer采用的init脚本和标准的Redhat init脚本不同,我查看了虚拟机中的/etc/inittab ,依样画葫芦,先复制标准init脚本到LXC的init脚本
1
2
cd /lxc/centos/etc/rc.d
cp rc.sysinit rc.sysinit.lxc

由于LXC虚拟机中不能使用udev所以注释掉以下段落(根据 http://lxc.teegra.net/ 说明, udev 是不能在lxc虚拟容器中工作的。)

1
2
3
4
#nashpid=$(pidof nash 2>/dev/null)
#[ -n "$nashpid" ] && kill $nashpid >/dev/null 2>&1
#unset nashpid
#/sbin/start_udev
  • 修改/lxc/centos/etc/inittab ,将启动脚本指向rc.sysinit.lxc
1
2
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit.lxc
  • 启动虚拟机
1
lxc-start -n centos

虽然没有显示出终端(这个问题有待后续解决),但是已经启动了ssh,所以可以通过ssh远程登录系统。

其他需要解决的问题

  • 解决LXC虚拟机无法使用df 命令

实际上,在LXC虚拟机中,是不需要挂载任何文件系统的,所有的文件系统都已经在Host主机上挂载了,在LXC主机中是没有挂载外部设备的权限的。
但是,为了能够在guest中也能使用df ,可以采用手工生成guest虚拟机中的/etc/mtab 文件来反映内核挂载。实际上,可以参考Host主机的/etc/mtab ,将对应希望在guest虚拟机中看到的内容复制过去。例如,在guest中也添加




1
echo "rootfs / rootfs rw 0 0" > /etc/mtab




然后,就可以使用df 命令显示磁盘空间。




1
df -h




Filesystem            Size  Used Avail Use% Mounted on
rootfs                108G   99G  4.1G  97% /

这个命令可以存放在启动脚本中执行,并且可以添加其他内容




1
2
3
4
5
echo "rootfs / rootfs rw 0 0" > /etc/mtab
echo "devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0" >> /etc/mtab
echo "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0" >> /etc/mtab
echo "sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0" >> /etc/mtab
echo "shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0" >> /etc/mtab







1
df -h




Filesystem            Size  Used Avail Use% Mounted on
rootfs                108G   99G  4.1G  97% /
shm                    10M  172K  9.9M   2% /dev/shm
  • LXC和VServer不同,可以在guest虚拟机中设置路由,所以在虚拟机中,可以手工设置缺省网关



1
2
route add default gw 10.1.11.1
netstat -rn




Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.1.11.0       0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0         10.1.11.1       0.0.0.0         UG        0 0          0 eth0
  • LXC和VServer不同,可以在guest虚拟机中设置内核参数,可以修改proc 内核映像系统,以符合安装Oracle数据库。 以下命令添加在/etc/rc.local 中:



1
2
echo "2147483648" > /proc/sys/kernel/shmmax
echo "250 32000 100 128" >  /proc/sys/kernel/sem




复制虚拟机

  • 复制centos 虚拟机



1
(cd /lxc/centos && tar cf - .)|(cd /lxc/oradb1 && tar xfpv -)




  • 修改配置文件/lxc/oradb1/fstab (修改路径)



1
2
3
/dev  /lxc/oradb1/dev none bind 0 0
/dev/pts /lxc/oradb1/dev/pts  none bind 0 0
#/dev/console /lxc/oradb1/dev/console none bind 0 0




  • 复制并创建配置文件/etc/lxc/lxc-oradb1.conf



1
cp /etc/lxc/lxc-centos.conf /etc/lxc/lxc-oradb1.conf




  • 修改配置文件/etc/lxc/lxc-oradb1.conf (修改主机名和IP)



1
2
3
4
5
6
7
8
9
10
11
12
13
# Container with network virtualized using a pre-configured bridge named br0 and
# veth pair virtual network devices
lxc.utsname = oradb1
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:ce
lxc.network.ipv4 = 10.1.11.4/24
lxc.network.name = eth0
lxc.mount = /lxc/oradb1/fstab
lxc.rootfs = /lxc/oradb1
lxc.tty = 3
lxc.pts = 1024




  • 创建虚拟机



1
lxc-create -n oradb1 -f /etc/lxc/lxc-oradb1.conf




  • 启动虚拟机




1
lxc-start -n oradb1