Linux容器

使用Cgroup和Namespace就可以实现容器。容器这个技术也称为操作系统虚拟化,是将一个内核所管理的资源划分成多个分组。

在容器中,CPU和内存资源是使用Cgroup来划分的。PID、IPC、网络等资源使用Namespace来划分。

LXC

Linux中实际安装的容器有LXC(Linux Container)。本节将以Fedora 14为例介绍LXC的使用方法。


yum install lxc


要使用网络,还需要安装bridge-utils。


yum install bridge-utils


在使用LXC之前,必须启用cgroup文件系统。使用下列命令挂载cgroup文件系统。


mount-t cgroup cgroup/cgroup


另外,向/etc/fstab添加下列语句,就可以在系统启动时自动挂载cgroup文件系统。


cgroup/cgroup cgroup defaults 0 0


首先,将bash shell进程放进容器。

这里要为容器中使用的文件系统准备一个/lxc目录。


mkdir/lxc

cd/lxc


然后准备作为容器内的根文件系统的目录。


mkdir rootfs

cd rootfs


还需要准备其他必要的目录(这些目录主要使用bind mount)。


mkdir bin dev etc lib lib64 proc sbin sys usr var


然后还要生成LXC的配置文件lxc.conf以及引用的fstab。


vi/lxc/lxc.conf

lxc.utsname=lxc

lxc.rootfs=/lxc/rootfs

lxc.mount=/lxc/fstab

vi/lxc/fstab

/bin/lxc/rootfs/bin none ro, bind 0 0

/sbin/lxc/rootfs/sbin none ro, bind 0 0

/lib/lxc/rootfs/lib none ro, bind 0 0

/lib64/lxc/rootfs/lib64 none ro, bind 0 0

/etc/lxc/rootfs/etc none ro, bind 0 0

/usr/lxc/rootfs/usr none ro, bind 0 0

/dev/lxc/rootfs/dev none rw, bind 0 0

/dev/pts/lxc/rootfs/dev/pts none rw, bind 0 0

/proc/lxc/rootfs/proc proc defaults 0 0

/sys/lxc/rootfs/sys sysfs defaults 0 0


准备工作完成后,使用lxc-create命令生成名为lxc的容器。


lxc-create-n lxc-f/lxc/lxc.conf


使用lxc-ls命令可以确认容器列表。


lxc-ls

lxc


使用lxc-create命令在lxc容器内执行bash。


lxc-execute-n lxc bash


小贴士:在笔者的环境下,出现了终端的按键输入不显示的情况。发生这种情况时可以执行reset命令,终端的操作就会恢复。


bash 4.1#reset(不显示在画面上)


执行ps命令,就可以发现PID是从1开始的,除lxc容器以外看不到其他进程。


bash-4.1#ps aux

USER PID%CPU%MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.1 0.1 14688 664 pts/0 S 21:34 0:00/usr/lib64/

lxc/lxc-init—bash

root 2 0.3 0.3 108440 1760 pts/0 S 21:34 0:00 bash

root 6 0.0 0.2 108120 1104 pts/0 R+21:34 0:00 ps aux


另外,生成的容器可以使用lxc-destroy命令来撤销。


lxc-destroy-n lxc


接下来尝试启用网络,并启动sshd进程。然后,创建用来连接分配到容器的网络接口的网桥(关于网桥请参考Hack#24)。

在这个例子中将IP地址设置为192.168.20.254。


brctl addbr br0

ifconfg br0 192.168.20.254


然后,修改lxc.conf,添加网络设置。


vi/lxc/lxc.conf

lxc.utsname=lxc

lxc.rootfs=/lxc/rootfs

lxc.mount=/lxc/fstab

lxc.network.type=veth

lxc.network.flags=up

lxc.network.link=br0

lxc.network.name=eth0

lxc.network.ipv4=192.168.20.1/24


启动sshd时需要下列目录,要事先创建。当该目录不存在时,从lxc-execute启动sshd时就会失败。


mkdir-p rootfs/var/empty/sshd


接下来生成容器。


lxc-execute-n lxc/usr/sbin/sshd


这时打开其他终端,确认SSH服务器是否正在运行。

首先,使用ping命令确认网络是否已连接。


ping 192.168.20.1

PING 192.168.20.1(192.168.20.1)56(84)bytes of data.

64 bytes from 192.168.20.1:icmp_req=1 ttl=64 time=0.899 ms

64 bytes from 192.168.20.1:icmp_req=2 ttl=64 time=0.174 ms

^C


使用ssh命令,连接分配到容器的IP地址192.168.20.1。


ssh 192.168.20.1

root@192.168.20.1's password:


SSH连接已建立,输入密码后就成功登录。

通过ps命令所显示的进程来确认资源是否已被容器隔离。


-bash-4.1#ps auxw

USER PID%CPU%MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.1 14688 660 pts/0 S+21:43 0:00/usr/lib64/lxc/

lxc-init—/usr/sbin/sshd

root 3 0.0 0.2 75104 1116?Ss 21:43 0:00/usr/sbin/sshd

root 4 1.4 0.8 108816 4068?Ss 21:47 0:00 sshd:root@pts/3

root 6 1.6 0.3 108440 1904 pts/3 Ss 21:47 0:00-bash

root 19 0.0 0.2 108124 1104 pts/3 R+21:47 0:00 ps auxw

-bash-4.1#ifconfg eth0

eth0 Link encap:Ethernet HWaddr 3A:A1:C2:A0:6F:1B

inet addr:192.168.20.1 Bcast:192.168.20.0 Mask:255.255.255.0

inet6 addr:fe80:38a1:c2ff:fea0:6f1b/64 Scope:Link

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:280 errors:0 dropped:0 overruns:0 frame:0

TX packets:259 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:31389(30.6 KiB)TX bytes:31373(30.6 KiB)

-bash-4.1#exit

logout


可以在其他终端执行lxc-stop,来关闭装有sshd的容器。


lxc-stop-n lxc


然后运行debian。

使用debootstrap创建用来启动debian的根文件系统。deboot strap使用yum来安装。


yum install debootstrap


创建debian的根文件系统,需要准备/debian。


mkdir/debian

cd/debian


现在执行debootstrap,生成debian lenny的文件系统。


debootstrap—arch=amd64 lenny lenny


然后,准备LXC用的设置。


vi/debian/lenny.conf


lxc. utsname=lenny

lxc. network.type=veth

lxc. network.flags=up


lxc.network.link=br0

lxc.network.name=eth0

lxc.network.ipv4=192.168.20.2/24

lxc.rootfs=/debian/lenny

lxc.mount=/debian/lenny.fstab

vi/debian/lenny.fstab

devpts/debian/lenny/dev/pts devpts defaults 0 0

proc/debian/lenny/proc proc defaults 0 0

sysfs/debian/lenny/sys sysfs defaults 0 0


创建名称为lenny的容器。


lxc-create-n lenny-f lenny.conf


所创建的容器可以通过lxc-start来启动。只到这一步的话,init虽然启动,但不能进行任何操作。这是因为刚执行debootstrap后,安装的仅是最低限度需要的数据包。这里为了让外部能够连接到容器,需要安装sshd。


lxc-start-n lenny bash


debian环境的shell就会在容器内启动。然后使用apt-get安装openssh-server。


lenny:~#apt-get install openssh-server


另外,为了在SSH上进行登录,还需要设置root的密码。


lenny:~#passwd


在容器内启动lenny。


lxc-start-n lenny

INIT:version 2.86 booting

Setting the system clock.

Cannot access the Hardware Clock via any known method.

Use the—debug option to see the details of our search for an access method.

Unable to set System Clock to:Fri Dec 10 22:59:45 UTC 2010(warning).

Activating swap……done.

Setting the system clock.

Cannot access the Hardware Clock via any known method.

Use the—debug option to see the details of our search for an access method.

Unable to set System Clock to:Fri Dec 10 22:59:46 UTC 2010(warning).

Cleaning up ifupdown……

Loading kernel modules……FATAL:Could not load/lib/modules/2.6.35.9-64.fc14.

x86_64/modules.dep:No such file or directory

Checking file systems……fsck 1.41.3(12-Oct-2008)

done.

Setting kernel variables(/etc/sysctl.conf)……done.

Mounting local filesystems……done.

Activating swapfile swap……done.

Setting up networking……

Configuring network interfaces……done.

INIT:Entering runlevel:2

Starting enhanced syslogd:rsyslogd.

Starting OpenBSD Secure Shell server:sshd.

Starting periodic command scheduler:crond.


我们尝试从其他终端使用SSH来连接。


ssh 192.168.20.2

root@192.168.20.2's password:

lenny:~#


在debian环境下实施关闭(shutdown)的话,容器结束。


lenny:~#shutdown-h now


按照前面所述方法使用LXC就可以简单地创建容器。