In this post I will demonstrate how to use febootstrap to make a root file system (rootfs) for a LXC container using Fedora. This technique is working with Fedora 12 and Fedora 13.
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 febootstrap install a (minimal) root file system (rootfs) for a LXC container using Fedora (These instructions work for Fedora 12 and 13).
2. Generate a set of configuration files on the host.
3. Clean up the boot scripts within the container.
Most of the commands in this tutorial are run as root. To obtain a root shell use:
su -
The working directory for this tutorial is /lxc , so config.fedora , fstab.fedora , and rootfs.fedora are both located in /lxc
Note: Unless you are familiar with selinux, it may be helpful to disable selinux as you learn to use Linux Containers.
setenforce 0
To disable selinux, edit /etc/sysconfig/selinux and change “SELINUX=enforcing” to
SELINUX=disabled
Make a rootfs via febootstrap
# Fedora 12
febootstrap fedora-12 rootfs.fedora
# Fedora 13
febootstrap fedora-13 rootfs.fedora
Configure the rootfs
Fix devices
udev does not run in lxc containers, so you need to manually make the needed devices.
I use this script to configure the devices:
#!/bin/bash
# bodhi.zazen's lxc-config
# Makes default devices needed in lxc containers
# modified from http://lxc.teegra.net/
ROOT=$(pwd)
DEV=${ROOT}/dev
if [ $ROOT = '/' ]; then
printf "\033[22;35m\nDO NOT RUN ON THE HOST NODE\n\n"
tput sgr0
exit 1
fi
if [ ! -d $DEV ]; then
printf "\033[01;33m\nRun this script in rootfs\n\n"
tput sgr0
exit 1
fi
rm -rf ${DEV}
mkdir ${DEV}
mknod -m 666 ${DEV}/null c 1 3
mknod -m 666 ${DEV}/zero c 1 5
mknod -m 666 ${DEV}/random c 1 8
mknod -m 666 ${DEV}/urandom c 1 9
mkdir -m 755 ${DEV}/pts
mkdir -m 1777 ${DEV}/shm
mknod -m 666 ${DEV}/tty c 5 0
mknod -m 666 ${DEV}/tty0 c 4 0
mknod -m 666 ${DEV}/tty1 c 4 1
mknod -m 666 ${DEV}/tty2 c 4 2
mknod -m 666 ${DEV}/tty3 c 4 3
mknod -m 666 ${DEV}/tty4 c 4 4
mknod -m 600 ${DEV}/console c 5 1
mknod -m 666 ${DEV}/full c 1 7
mknod -m 600 ${DEV}/initctl p
mknod -m 666 ${DEV}/ptmx c 5 2
exit 0
The script is very slightly modified from This page and is saved in /usr/local/bin/lxc-config .
Make it executable :
chmod u+x /usr/local/bin/lxc-config
Run the script in rootfs.fedora
cd /lcx/rootfs.fedora
/usr/local/bin/lxc-config
Configure the rootfs
chroot into the container
# copy resolv.conf from the host
cp /etc/resolv.conf /lxc/rootfs.fedora/etc
#chroot into the fedora rootfs
chroot /lxc/rootfs.fedora /bin/bash
# mount proc sys and /dev/pts
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
# Update - imports the gpg key
yum update
# Install additional applications
yum -y reinstall glibc-common
yum install httpd php-mysql mysql-server nano openssh-clients vim
# Generate a few needed files / directories :
touch /etc/fstab
rm /etc/mtab
ln -s /proc/mounts /etc/mtab
#touch /lxc/rootfs.fedora/var/run/syslogd.pid
#mkdir -p /lxc/rootfs.fedora/var/run/{httpd,mysqld}
#touch /lxc/rootfs.fedora/var/run/mysqld/mysqld.pid
#mkdir -p /lxc/rootfs.fedora/var/lock/subsys
#touch /lxc/rootfs.fedora/var/lock/subsys/{atd,ip6tables,iptables,local,network,rsyslogd,sshd}
# unmount proc sys and /dev/pts
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
# Set a root password
passwd
Edit /lxc/rootfs.fedora/etc/sysconfig/init
The very last line of the file reads "ACTIVE_CONSOLES=/dev/tty[1-6]" , change this to
ACTIVE_CONSOLES=/dev/tty[1-4]
edit /lxc/rootfs.fedora/etc/rc.sysinit and comment out the start_udev line
# /sbin/start_udev
Using any editor, edit /lxc/rootfs/etc/sysconfig/network
Add these two lines (adjust hostname):
NETWORKING=yes
HOSTNAME=fedora
Remove tty5 and tty6
Fedora 12
cd rootfs.fedora/etc/event.d
rm tty{5,6}
Generate the HOST LXC configuration files
Generate a config file
This is done on the host node and will set the container resources, networking, and confinement.
I call it config.fedora . Make sure the following information is accurate:
container name (lxc.utsname)
network (lxc.network.ipv4)
rootfs (lxc.rootfs)
fstab (lxc.mount)
lxc.utsname = fedora
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.65/24
lxc.rootfs = /lxc/rootfs.fedora
lxc.mount = /lxc/fstab.fedora
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.10/24
lxc.rootfs = /lxc/rootfs.fedora
lxc.mount = /lxc/fstab.fedora
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.fedora/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.fedora . Make sure the following information is accurate:
/lxc/fstab.fedora
none /lxc/rootfs.fedora/dev/pts devpts defaults 0 0
none /lxc/rootfs.fedora/proc proc defaults 0 0
none /lxc/rootfs.fedora/sys sysfs defaults 0 0
#none /lxc/rootfs.fedora/var/lock tmpfs defaults 0 0
#none /lxc/rootfs.fedora/var/run tmpfs defaults 0 0
/etc/resolv.conf /lxc/rootfs.fedora/etc/resolv.conf none bind 0 0
Clean up the init scripts
In the directory /lxc/rootfs.fedora/etc/init remove all the files except
rc.conf
start-ttys.conf
tty.conf
Edit both rc.conf and start-ttys.conf and change the start line to
start on startup
At the bottom of rc.conf change
exec /etc/rc.d/rc $RUNLEVEL
to
exec /etc/rc.d/rc.fedora
Use this as /lxc/rootfs.fedora/rc.d/rc.fedora
#!/bin/bash
# Whatever is needed to clear out old daemon/service pids from your container
#rm -f $(find /var/run -name '*pid')
route add default gw 192.168.1.1
/etc/init.d/rsyslog start &
/etc/init.d/iptables start &
/etc/init.d/sshd start &
/etc/init.d/mysqld start &
/etc/init.d/httpd start &
This script is modified from Here .
Make the file executable
chmod a+x /lxc/rootfs.fedora/etc/rc.d/rc.fedora
Remove all the files on /lxc/rootfs.fedora/etc/init.d except the services you wish to run
In this example we have only
httpd
iptables
mysqld
rsyslog
sshd
Configure and start the container
lxc-create -f ~bodhi/lxc/config.fedora -n fedora
Disable selinux (on the host)
setenforce 0
Start the container, watch for error messages
lxc-start -n fedora
Note: It takes some time for the container to boot ...
lxc-console or ssh in and set a locale
lxc-console -n fedora
In the container run:
yum -y reinstall glibc-common
Clean up container
From within the container
yum clean all
Stop the container
lxc-stop -n fedora
Optional : Clean unnecessary files
remove the febootstrap cache (if it exists). You may remove the shared doc and locales.
rm -rf rootfs/var/yum/cache/febootstrap
rm -rf rootfs/usr/share/locale/*
rm -rf rootfs/usr/share/doc/*
Pingback: Shadows of epiphany » Blog Archive » LXC Configure Fedora Containers | Just linux!
Pingback: LXC howto « Richard WM Jones
Hello,
I have few questions regarding this setup…..
1. When I follow your setup step-by-step (except the rc.config part, because there is no such thing on Fedora) I get the error
==================================================
lxc-start: Device or resource busy – failed to mount ‘none’ on ‘/lxc/rootfs.fedora/dev/pts’
lxc-start: failed to setup the mounts for ‘m1′
lxc-start: failed to setup the container
====================================================
But when a remove the .mount line from the config file it boots but slower. What could be the problem?
2. Even when I start the machine a try a ssh connection but I get a PTY error (I assume that might be error with /dev/pts mount?
Thanks in advance,
Nikola
@NSim – I can not tell from what you posted.
Check the syntax of your fstab file, is the path correct ?
Also, there is a file on Fedora /etc/init/rc.conf and that file needs a small modification. At least it did last time I looked.
Hi,
I solved the problem………
1. Because I could not find rc.conf file, I just removed the scripts from etc/init.d (for now everything is working ok)
2. For the mount problem:
– from the fstab file I remover the “none /lxc/rootfs.fedora/dev/pts devpts defaults 0 0″ line
– I added lxc.pts=1 at the bottom of lxc.conf file
So it boots ok, with every service I left in init.d
Regards
Making a rootfs with febootstrap no longer works with FC14 and newer. Any ideas of what is the replacement for febootstrap since 3.0+ is just for appliances now?
-David
@DavidA: I have not looked, what is wrong with feboostrap ?
http://lists.fedoraproject.org/pipermail/package-announce/2010-December/051796.html
Pingback: LXC Linux Containers on Ubuntu 10.04 with Centos 5 clients » DBArticles
Can you tell us what would be the equivalent procedure to this now that febootstrap2, which I assume you use, no longer exists?
(As opposed to the supermin appliance febootstrap3 which is not at all the same utility).
@Mike BRIGHT
Currently I use mock , see
http://fedoraproject.org/wiki/Using_Mock_to_test_package_builds