LXC Configure Debian Containers

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

This entry was posted in Linux and tagged , . Bookmark the permalink.

17 Responses to LXC Configure Debian Containers

  1. Pingback: Shadows of epiphany » Blog Archive » LXC Configure Debian Containers | Just linux!

  2. Pingback: Bodhi.Zazen: LXC Configure Debian Containers | TuxWire : The Linux Blog Aggregator

  3. Denis says:

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

  4. bodhi.zazen says:

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

  5. Denis says:

    Thanks.
    I know about network configuration :)))

  6. bodhi.zazen says:

    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.

  7. # “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/ )

  8. Using any editor, add the following to /lxc/rootfs.lenny/etc/init.d/rdS.lenny

    should be:

    rcS.lenny

  9. Sebastiaan Giebels says:

    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.

  10. # “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

  11. SGI says:

    Small corrections:

    rdS.lenny -> rcS.lennuy
    ln -s /proc/mounts /etc/fstab -> ln -s /proc/mounts /etc/mtab

  12. stlsaint says:

    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!

  13. bodhi.zazen says:

    thank you stlsaint for the feedback, I updated my post.

  14. Patrick says:

    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?

  15. bodhi.zazen says:

    @Patrick

    No reason. Honestly you probably need only one tty if you wish you can almost certainly disable the rest.

  16. Pingback: LXC

  17. Pingback: RaspBerry PiでLXC(Linux Container) | 電脳あざらしの泳ぎ Raspberry Pi 別館

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>