I have been taking Linux Containers for a spin and was advised on IRC that Debian was easier to configure then Ubuntu, so decided to give it a try.
In this post I will demonstrate how to use Debian as a Linux Container. These instructions work for both lenny and squeeze.
This post assumes you have configured your host, see my previous post if you need assistance configuring your host node.
In this example I am installing LAMP and openssh-server as I imagine these are popular options.You are free to install more or less , but these common tools serve as common examples and should allow you to adapt if you need additional or different services.
Basically we need to take 3 steps:
1. Use debootstrap install a (minimal) root file system (rootfs) for a LXC container using Debian (These instructions work for lenny and squeeze).
2. Generate a set of configuration files on the host.
3. Clean up the boot scripts within the container.
Commands in this tutorial are run as root, so to obtain a root shell use sudo -i or su – , depending on your host node.
The working directory for this tutorial is /lxc , so config.lenny, fstab.lenny, and rootfs.lenny are all located in /lxc
Make a rootfs via debootstrap
debootstrap --variant=minbase --arch i386 lenny rootfs.lenny
Change “--arch i386″ to “--arch amd64″ for a 64 bit container.
Configure the container
Add the Debian security repo
Open /lxc/rootfs.lenny/etc/apt/sources.list and add :
deb http://security.debian.org/ lenny/updates main
Modify the rootfs
chroot into rootfs.lenny and configure
chroot /lxc/rootfs.lenny
apt-get update
# set locales
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
apt-get -y --force-yes install locales
# Add a few applications, including openssh-server
apt-get install -y adduser apt-utils iproute netbase nano openssh-blacklist openssh-blacklist-extra openssh-server sudo iputils-ping iptables rsyslog apache2 php5 php5-mysql mysql-server
# Configure the hostname of the container and /etc/hosts
# Change "host_name" to your desired host name
# Change "192.168.0.60" to the ip address you wish to assign to the container
echo "host_name" > /etc/hostname
echo "127.0.0.1 localhost host_name" > /etc/hosts
echo "192.168.0.60 host_name" >> /etc/hosts
# “Fix” mtab
rm /etc/mtab
ln -s /proc/mounts /etc/fstab
#Set a root passwd
passwd
# As an alternate to setting a root password, you may of course add a new user and configure sudo.
#exit chroot
exit
Edit /etc/inittab
Using any editor (nano, vim), open /lxc/rootfs.lenny/etc/inittab and set a new init script.
Change
si::sysinit:/etc/init.d/rcS
To
si::sysinit:/etc/init.d/rcS.lenny
comment out the following two lines:
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6
Save your changes to /lxc/rootfs.lenny/etc/inittab and exit.
Squeeze only – make a few devices
cd into /lxc/rootfs.squeeze/dev and run :
mknod -m 666 tty1 c 4 1
mknod -m 666 tty2 c 4 2
mknod -m 666 tty3 c 4 3
mknod -m 666 tty4 c 4 4
Generate the HOST LXC configuration files
Generate a config file
I call it config.lenny . Make sure the following information is accurate:
container name (lxc.utsname)
network (lxc.network.ipv4)
rootfs (lxc.rootfs)
fstab (lxc.fstab)
lxc.utsname = lenny
lxc.tty = 4
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.name = eth0
lxc.network.mtu = 1500
lxc.network.ipv4 = 192.168.0.60/24
lxc.rootfs = /lxc/rootfs.lenny
lxc.mount = /lxc/fstab.lenny
lxc.cgroup.devices.deny = a
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
# /dev/pts/* - pts namespaces are "coming soon"
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
The following lines are critical !
lxc.network.ipv4 = 192.168.0.60/24
lxc.rootfs = /lxc/rootfs.lenny
lxc.mount = /lxc/fstab.lenny
lxc.cgroup.xxx
lxc.network.ipv4 sets the container ip address (192.168.0.60) and netmask ( /24 ).
lxc.rootfs instructs lxc-create to use pivot root rather then chroot and this is important for containment.
lxc.mount is a replacement for rootfs.lenny/etc/fstab . Use this file to define mount points in your container. This sample configuration file is the minimum, you may use bind to add shared directories.
lxc.cgroup.foo These lines define the resources available to the container (via cgroup).
Generate a fstab file
I call it fstab.lenny . Make sure the following information is accurate:
/lxc/fstab.lenny
none /lxc/rootfs.lenny/dev/pts devpts defaults 0 0
none /lxc/rootfs.lenny/proc proc defaults 0 0
none /lxc/rootfs.lenny/sys sysfs defaults 0 0
none /lxc/rootfs.lenny/var/lock tmpfs defaults 0 0
none /lxc/rootfs.lenny/var/run tmpfs defaults 0 0
/etc/resolv.conf /lxc/rootfs.lenny/etc/resolv.conf none bind 0 0
Clean up the init scripts
Using any editor, add the following to /lxc/rootfs.lenny/etc/init.d/rcS.lenny
#!/bin/bash
# Whatever is needed to clean out old daemon/service pids from your container
rm -f $(find /var/run -name ‘*pid’)
rm -f /var/lock/subsys/*
# you could use a dhcp client here
# or you could get your system network scripts to work
# (Which I’ve ran into troubles with in containers)
# (Edit gateway address, domain, and nameserver as need be)
/etc/init.d/rsyslog start &
route add default gw 192.168.0.1
This script is modified from Here .
Make the init script executable :
chmod a+x /lxc/rootfs.lenny/etc/init.d/rcS.lenny
Remove unnecessary boot scripts
Linux containers do not “boot” in the same was as a standard installation, they are managed from the host node with lxc-start and with lxc-stop. Until they are adapted for LXC, many of the boot scripts hang, fail, or cause error messages. Removing unnecessary scripts in rootfs.lenny will speed up start time.
All we need is to start a very basic init.
lenny : remove all but the following;
apache2
mysql
rc
rcS.lenny
rc.local
ssh
sudo
rsyslog
urandom
Modify (add / remove) the init.d scripts as needed if you have more or less servers to start. If they do not start automatically, add them to rcS.lenny (rsyslog for example).
Create and start the container
Create the container:
lxc-create -f /lxc/conf.lenny -n lenny
Start the container:
lxc-start -n lenny
You should now be able to access the container with either lxc-console or ssh
ssh root@192.168.0.60
lxc-console -n lenny
Assuming you get no error messages , you may start the container with the -d option
lxc-start -d -n lenny
Stop the container
lxc-stop -n lenny
Destroy the container
lxc-destroy -n lenny
Pingback: Shadows of epiphany » Blog Archive » LXC Configure Debian Containers | Just linux!
Pingback: Bodhi.Zazen: LXC Configure Debian Containers | TuxWire : The Linux Blog Aggregator
lxc.network.ipv4 = 192.168.0.60/24
or
lxc.network.ipv4 = 192.168.0.10/24
lxc.network.ipv4 sets the container ip address (192.168.0.10) and netmask ( /24 ).
I don’t understans. What ip address we must add to the host and to the linux container?
Please, helm me :)))
@Denis – It sounds as if you do not understand “basic networking”.
Assuming you have a router, you have a private IP range. Home networks are typically 192.168.0.0 – 192.168.0.256
See : http://www.computerhope.com/jargon/n/netmask.htm (Class C)
So you assign a unique ip address to you host and a uniqu ip address to your LXC guest. Personally IMO it is easier to use a static ip address rather then DHCP.
So , you can decide for yourself.
Assign 192.168.1.10 to the host
And 192168.1.11 to the guest
Does not matter so long as each computer on your network has a unique IP address.
In the lxc configuration file you set your guest ip address/netmask.
For class C networks it would be 192.168.0.11/24
Here is a brief overview :
http://www.faqintosh.com/risorse/en/guides/net/tcp/basic/
If you do not have a router, you would then be getting an IP address from your ip provider and they should tell you this information (ip address, netmask, etc).
On your host you can see some of this information if you use:
/sbin/ifconfig (output truncated)
eth0 :
inet addr:192.168.0.10 Bcast:192.168.0.255 Mask:255.255.255.0
You may also look at this information by logging into your router.
Thanks.
I know about network configuration :)))
Ah, sweet. I would agree, the syntax of LXC config files was not obvious at first glance to me either.
The syntax in the LXC config file is:
lxc.network.ipv4 = ip_address_guest/net_mask
Example:
lxc.network.ipv4 = = 192.168.0.11/24
When you start your guest with
lxc-start -n guest_name
The ip address and netmask are set as a part of starting the container, and you do NOT need to run a network init script in the guest, just set the default gw.
On Ubuntu, for example, my init script is nothing more then a single route command.
If you wish to shutdown or “reboot” a guest, use a simple script ;
Stop :
service foo stop
“Reboot”
service foo restart
Just list all your services, one per line (including syslog and cron) if you use them.
In this way, your container will start and stop faster, and with less errors then the native init or init.d scripts.
# “Fix” mtab
rm /etc/mtab
ln -s /proc/mounts /etc/fstab
last line should read:
ln -s /proc/mounts /etc/mtab
(see http://blog.bodhizazen.net/linux/lxc-configure-fedora-containers/ )
Using any editor, add the following to /lxc/rootfs.lenny/etc/init.d/rdS.lenny
should be:
rcS.lenny
lxc-start: unknow key lxc.fstab
lxc-start: failed to process ‘lxc.fstab = /lxc/fstab.lenny
‘
lxc.fstab should be
lxc.mount
specify a file location in the fstab format, containing the
mount informations.
# “Fix” mtab
rm /etc/mtab
ln -s /proc/mounts /etc/fstab
last line should read:
ln -s /proc/mounts /etc/mtab
(see http://blog.bodhizazen.net/linux/lxc-configure-fedora-containers/ )
lxc-start: unknow key lxc.fstab
lxc-start: failed to process ‘lxc.fstab = /lxc/fstab.lenny
‘
lxc.fstab should be
lxc.mount
specify a file location in the fstab format, containing the
mount informations.
Comment by Sebastiaan Giebels — September 1, 2010
Small corrections:
rdS.lenny -> rcS.lennuy
ln -s /proc/mounts /etc/fstab -> ln -s /proc/mounts /etc/mtab
Hey found two small mistakes:
1. In the config you have: lxc.network.ipv4 = 192.168.0.60/24
But when you explain what it is you have the ip as 192.1681.10
“lxc.network.ipv4 sets the container ip address (192.168.0.10) and netmask ( /24 ).”
2. “Using any editor, add the following to /lxc/rootfs.lenny/etc/init.d/rdS.lenny”
That should be init.d/rcS….
Small but would hate for someone to be stuck due to minor pointers!
thank you stlsaint for the feedback, I updated my post.
Hi!
First, many thanks for sharing your lxc example. This helped me a lot.
But there is one thing I did not get, yet:
You created 4 ttys…:
mknod -m 666 tty1 c 4 1
mknod -m 666 tty2 c 4 2
mknod -m 666 tty3 c 4 3
mknod -m 666 tty4 c 4 4
…and commenting out tty5 and tty6 in the inittab I assume you want to use tty1 to tty4 inside the container.
But in the config file you only allow to access tty1 and tty2…:
# consoles
[...]
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
…denying the rest:
lxc.cgroup.devices.deny = a
Is there a special reason for not allowing to access tty3 and tty4?
@Patrick
No reason. Honestly you probably need only one tty if you wish you can almost certainly disable the rest.
Pingback: LXC
Pingback: RaspBerry PiでLXC(Linux Container) | 電脳あざらしの泳ぎ Raspberry Pi 別館