Linux containers fascinated me for a long time over other virtualization solutions such as KVM and virtualbox. The low memory footprint and near-native performance are really attractive features.
But I couldn’t get them running in my two earlier attempts which ended with various problems. However this thread on the mailing list inspired me to try one more time and it turned out to be really really easy now.
Following are simple steps to get a network server running in a container.
I am using archlinux with kernel 3.9.2 and lxc 0.9.0 on x86_64. Arch now defaults to systemd for some time and the container created here also uses the same.
These steps create a x86_64 container using archlinux template.
Network setup
I am running containers on my desktop machine which has one ethernet interface, eth0 and connected to a DSL router for internet access.
A bridge interface is one option to provide networking in the containers. Following steps creates the necessary bridge using netctl.
- Stop interface eth0
- Comment out Address/Routes/Gateway/DNS from ethernet profile, since they won’t be used with the bridge setup.
- Add a bridge interface. /etc/netctl/examples/bridge is a great place to start. Reuse the same IP of eth0 interface. Bind to eth0 interface only and set FWDDelay to zero.
- Start the ethernet profile followed by the bridge profile. Ensure that networking works.
- Enable both the profiles with netctl enable. Reboot and ensure that the networking still works.
Networking is a one-time setup. Same bridge interface can be used for multiple containers.
Create the container
Following command creates the container
# lxc-create -n webproxy -t archlinux -- -P net-tools,openssh,vi,squid -p /data/shridhar/lxc/webproxy
The options used are
This option specifies the name of the container and is required to identify it.
This option specifies container template. Templates set up a particular distribution in the container. lxc ships with templates for many distributions.
- -P net-tools,openssh,vi,squid
This is a template specific option which specifies additional packages to install in the container. The template has few basic packages hard-coded in it. Since I will be setting up a squid server in the container, I added it on the command line only. Similarly ssh is required for remote maintenance.
- -p /data/shridhar/lxc/webproxy
This option specifies the path where the container rootfs will be created. Ensure that the destination leaf dir(webproxy in this case) does not exist. lxc will create that. The container config will live in the default location of /var/lib/lxc.
Set up networking for the container
# echo "lxc.network.ipv4.gateway=192.168.2.1" >> /var/lib/lxc/webproxy/config
# echo "lxc.network.ipv4=192.168.2.12/24" >> /var/lib/lxc/webproxy/config
These two commands set up networking for container. It is possible to setup DHCP in container but I don’t have a provider handy and I prefer static address since ssh keys rely on it.
Initial setup
Once container is created, some initial setup is required. So start container in foreground.
# lxc-start -n webproxy
Login as root. No password is required at the moment.
- Set up password for root
- Ensure that networking is working.
- Edit /etc/ssh/sshd_config and explicitly specify address to listen on. This should be done so that the host and the container can offer ssh service simultaneously. Enable and start ssh.
- Edit /etc/systemd/system/getty.target.wants/getty\@tty1.service and comment out ConditionPathExists line. Without this step, a getty does not start in the container and lxc-console does not work.
Apparently /sys/class/tty/console/active in the container reports tty0 which systemd does not find inside a container and is the cause of getty malfunction.
Now the container can be started in background. Stop it from another terminal and start it in the background, as follows
# lxc-stop -n webproxy && lxc-start -d -n webproxy
Now you should be able to ssh into it and use it as if it is a separate machine.