LXC Configure Debian Containers

February 24th, 2010 by bodhi.zazen

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.fstab = /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.10) 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/rdS.lenny

#!/bin/bash
# Whatever is needed to clearn 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.1.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

StumbleUpon

Posted in Linux

6 Comments »

  1. [...] Originally posted here:  Shadows of epiphany » Blog Archive » LXC Configure Debian Containers [...]

    Pingback by Shadows of epiphany » Blog Archive » LXC Configure Debian Containers | Just linux! — February 24, 2010 @ 2:42 am

  2. [...] Original post: Bodhi.Zazen: LXC Configure Debian Containers [...]

    Pingback by Bodhi.Zazen: LXC Configure Debian Containers | TuxWire : The Linux Blog Aggregator — February 24, 2010 @ 2:13 pm

  3. 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 :)))

    Comment by Denis — May 21, 2010 @ 4:43 am

  4. @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.

    Comment by bodhi.zazen — May 21, 2010 @ 8:54 am

  5. Thanks.
    I know about network configuration :)))

    Comment by Denis — May 21, 2010 @ 11:43 am

  6. 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.

    Comment by bodhi.zazen — May 21, 2010 @ 1:05 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment