Setup Linux Container with LXC on Ubuntu 16.04

Linux containers (LXC), is an open source, lightweight operating system-level virtualization software that helps us to run a multiple isolated Linux systems (containers) on a single Linux host. LXC provides a Linux environment as close as to a standard Linux installation but without the need for the separate kernel. LXC is not a replacement of standard virtualization software’s such as VMware, VirtualBox, and KVM, but it is good enough to provide an isolated environment that has its own CPU, memory, block I/O, network.
LXC is released under GNU LGPLv2.1+ license. LXC project is sponsored by Canonical Ltd, who is behind Ubuntu OS.
In this guide, I will show you how to install LXC on Ubuntu 16.04, and create and manage LXC using the command line as well as using LXC Web Portal.
This tutorial should also work on previous versions of Ubuntu, such as Ubuntu 14.04 / 14.10 / 15.04 / 15.10
Prerequisites:
LXC containers use bridge networking to have access to/from an external network, before starting the container we must create a network bridge on Ubuntu.
Follow the steps to configure bridging on Ubuntu; I am creating bridged interface “br0” using ethernet card “ens33”
$ sudo nano /etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback ##Bridge Name ### auto br0 ### Bridge Information iface br0 inet static bridge_ports ens33 bridge_stp off bridge_fd 9 ### Bridge IP ### address 192.168.12.15 netmask 255.255.255.0 network 192.168.12.0 broadcast 192.168.12.255 gateway 192.168.12.2 dns-nameservers 8.8.8.8
Install LXC on Ubuntu 16.04:
Now, it’s the time to install LXC. Install the LXC and other packages for the containers to work properly.
$ sudo apt-get install lxc lxc-templates wget bridge-utils
Issue the following command to check everything is okay to run containers.
$ sudo lxc-checkconfig Kernel configuration not found at /proc/config.gz; searching... Kernel configuration found at /boot/config-4.4.0-15-generic --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled Bridges: enabled Advanced netfilter: enabled CONFIG_NF_NAT_IPV4: enabled CONFIG_NF_NAT_IPV6: enabled CONFIG_IP_NF_TARGET_MASQUERADE: enabled CONFIG_IP6_NF_TARGET_MASQUERADE: enabled CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled FUSE (for use with lxcfs): enabled --- Checkpoint/Restore --- checkpoint restore: enabled CONFIG_FHANDLE: enabled CONFIG_EVENTFD: enabled CONFIG_EPOLL: enabled CONFIG_UNIX_DIAG: enabled CONFIG_INET_DIAG: enabled CONFIG_PACKET_DIAG: enabled CONFIG_NETLINK_DIAG: enabled File capabilities: enabled Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
Configuring LXC Network:
Disable the default bridge “lxcbr0“, got created as part of LXC installation.
$ sudo nano /etc/default/lxc-net
Set “USE_LXC_BRIDGE” to “false“.
USE_LXC_BRIDGE="false"
Configure LXC to use the bridge “br0“, that we created earlier. If you already have any other bridge configured, you can set that in the below file.
$ sudo nano /etc/lxc/default.conf
lxc.network.type = veth
lxc.network.link = br0 # Replace with your bridge name
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
Creating First Linux Container:
LXC provides you the ready-made templates for easy installation of Linux containers. Templates are usually found in /usr/share/lxc/templates .
$ sudo ls /usr/share/lxc/templates/ lxc-alpine lxc-archlinux lxc-centos lxc-debian lxc-fedora lxc-openmandriva lxc-oracle lxc-slackware lxc-sshd lxc-ubuntu-cloud lxc-altlinux lxc-busybox lxc-cirros lxc-download lxc-gentoo lxc-opensuse lxc-plamo lxc-sparclinux lxc-ubuntu
Let’s create our first Ubuntu container, issue the following command in terminal
$ sudo lxc-create -n ubuntu_lxc -t ubuntu
Where,
-n <container name>
-t <template>
LXC will start creating the container “ubuntu_lxc“, you would get output something like below.
Sample output:
Checking cache download in /var/cache/lxc/xenial/rootfs-amd64 ...
Installing packages in template: ssh,vim,language-pack-en
Downloading ubuntu xenial minimal ...
I: Retrieving InRelease
I: Checking Release signature
I: Valid Release signature (key id 790BC7277767219C42C86F933B4FE6ACC0B21F32)
I: Retrieving Packages
I: Validating Packages
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
.
.
.
Download complete
Copy /var/cache/lxc/xenial/rootfs-amd64 to /var/lib/lxc/ubuntu_lxc/rootfs ...
Copying rootfs to /var/lib/lxc/ubuntu_lxc/rootfs ...
Generating locales (this might take a while)...
en_IN.UTF-8... done
Generation complete.
Creating SSH2 RSA key; this may take some time ...
2048 SHA256:2gY+KoAVdyeFbKZSjueMtV5pxuMNvPIltXCazRYSpJA root@raj-virtual-machine (RSA)
Creating SSH2 DSA key; this may take some time ...
1024 SHA256:+pXVAkgv7kUDs2iNf7AKbyHMe58OIopJFtnfwJ1fpK0 root@raj-virtual-machine (DSA)
Creating SSH2 ECDSA key; this may take some time ...
256 SHA256:vh1u7wgeMPMeZTWvidZT34FTsQ+oQUKBpJzazjp1Khc root@raj-virtual-machine (ECDSA)
Creating SSH2 ED25519 key; this may take some time ...
256 SHA256:qZvWvYnmJusDZhq5IJ/r8UsWBkrSHUg2vWCevMJgFZk root@raj-virtual-machine (ED25519)
invoke-rc.d: policy-rc.d denied execution of start.
Current default time zone: 'Etc/UTC'
Local time is now: Thu Apr 7 17:53:19 UTC 2016.
Universal Time is now: Thu Apr 7 17:53:19 UTC 2016.
##
# The default user is 'ubuntu' with password 'ubuntu'!
# Use the 'sudo' command to run tasks as root in the container.
##
Please make a note of login details, you would require this information to log in to the containers.
If you want to create a container based on Ubuntu 14.04, use the following command.
$ sudo lxc-create -t ubuntu -n trusty_lxc -- -r trusty -a amd64
-r <release>
-a <arc>
Starting Linux Containers:
Once after creating the containers, start it using the following command, -d to run containers in the background.
$ sudo lxc-start -n ubuntu_lxc -d
Now, take a console of the container using the following command.
$ sudo lxc-console -n ubuntu_lxc
Enter the username (ubuntu) and password (ubuntu) to log in. You can find the default credential at the end of the output during the creation of a container.
Sample output:
Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Ubuntu Xenial Xerus (development branch) ubuntu_lxc pts/0 ubuntu_lxc login: ubuntu Password: Welcome to Ubuntu Xenial Xerus (development branch) (GNU/Linux 4.4.0-15-generic x86_64) * Documentation: https://help.ubuntu.com/ The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. ubuntu@ubuntu_lxc:~$
You can perform all your work in this container as like you do on a Linux servers.
To exit from the container’s console, press “Ctrl+a” followed by “q”. Now, you will be returned to host computer’s terminal.
If you want to connect to the console of the container again ( the container is still running), run the following command.
$ sudo lxc-console -n ubuntu_lxc
Working with Linux Containers:
To listing down the available containers on the host machine, use the following command.
$ sudo lxc-ls ubuntu_lxc
Use the following command to list down the containers that are currently running on the host computer.
$ sudo lxc-ls --active ubuntu_lxc
You could see the same output for both of the commands as I have only one container which is currently running.
You can use the following command to list the containers with detailed information.
$ sudo lxc-ls -f NAME STATE AUTOSTART GROUPS IPV4 IPV6 ubuntu_lxc RUNNING 0 - 192.168.12.18 -
To get the details of the running container, issue the following command.
$ sudo lxc-info -n ubuntu_lxc
Name: ubuntu_lxc
State: RUNNING
PID: 2933
IP: 192.168.12.18
CPU use: 0.90 seconds
BlkIO use: 20.96 MiB
Memory use: 31.67 MiB
KMem use: 0 bytes
Link: vethFLQOYF
TX bytes: 3.21 KiB
RX bytes: 6.41 KiB
Total bytes: 9.62 KiB
You can use IP address to connect to the containers.
You can stop running containers using “lxc-stop” command, use the following command to stop “ubuntu_lxc”.
$ sudo lxc-stop -n ubuntu_lxc
Cloning containers:
LXC offers a feature of cloning a container from the existing container, run the following command to clone an existing “ubuntu_lxc” container to a new container “ubuntu_lxc_clone”.
Note: You must stop a container before initiating the clone.
$ sudo lxc-copy -n ubuntu_lxc -N ubuntu_lxc_clone
Check out whether a container is created successfully.
$ sudo lxc-ls ubuntu_lxc ubuntu_lxc_clone
You can start the cloned container and start working on it.
$ sudo lxc-start -n ubuntu_lxc_clone
$ sudo lxc-console -n ubuntu_lxc_clone Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Ubuntu Xenial Xerus (development branch) ubuntu_lxc_clone pts/0 ubuntu_lxc_clone login: ubuntu Password: Last login: Sat Apr 9 16:15:22 UTC 2016 from 192.168.12.1 on pts/4 Welcome to Ubuntu Xenial Xerus (development branch) (GNU/Linux 4.4.0-15-generic x86_64) * Documentation: https://help.ubuntu.com/ To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. ubuntu@ubuntu_lxc_clone:~$
Power off the container from LXC console.
ubuntu@ubuntu_lxc_clone:~$ sudo poweroff
Taking a Snapshot:
LXC also offers an another feature called the snapshot, follow the below steps to perform the snapshot.
Note: Before taking a snapshot, make sure the container is not running. Stop a running container using the following command.
$ sudo lxc-stop -n ubuntu_lxc_clone
For a demo, let’s take a snapshot of ubuntu_lxc_clone.
$ sudo lxc-snapshot -n ubuntu_lxc_clone
Sample output:
lxc-snapshot: lxccontainer.c: do_lxcapi_snapshot: 3371 Snapshot of directory-backed container requested. lxc-snapshot: lxccontainer.c: do_lxcapi_snapshot: 3372 Making a copy-clone. If you do want snapshots, then lxc-snapshot: lxccontainer.c: do_lxcapi_snapshot: 3373 please create an aufs or overlayfs clone first, snapshot that lxc-snapshot: lxccontainer.c: do_lxcapi_snapshot: 3374 and keep the original container pristine.
To know where the snapshot is being saved, run the following command.
$ sudo lxc-snapshot -L -n ubuntu_lxc_clone snap0 (/var/lib/lxc/ubuntu_lxc_clone/snaps) 2016:04:09 22:35:16
In Ubuntu, LXC snapshots are stored in “/var/lib/lxc/<containername>/snaps”
Restoring Snapshot:
To restore a container from the snapshot, we took earlier, use the following command.
$ sudo lxc-snapshot -r snap0 -n ubuntu_lxc_clone
Destroying Containers:
To remove a container, use the following command.
Note: You must remove the snapshots before destroying the containers. ($ sudo lxc-snapshot -d snap0 -n ubuntu_lxc_clone)
$ sudo lxc-destroy -n ubuntu_lxc_clone
Running a CentOS Container on Ubuntu 16.04:
Install “yum” package for Redhat based containers.
$ sudo apt-get install yum
Create a CentOS 7 container using the following command.
$ sudo lxc-create -n centos_lxc -t centos -- -R 7 -a x86_64 Host CPE ID from /etc/os-release: Checking cache download in /var/cache/lxc/centos/x86_64/7/rootfs ... Downloading centos minimal ... base | 3.6 kB 00:00 base/primary_db | 5.3 MB 12:26 updates | 3.4 kB 00:00 updates/primary_db | 3.9 MB 02:17 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package chkconfig.x86_64 0:1.3.61-5.el7 will be installed Complete! Fixing rpmdb location ... Download complete. Copy /var/cache/lxc/centos/x86_64/7/rootfs to /var/lib/lxc/centos_lxc/rootfs ... Copying rootfs to /var/lib/lxc/centos_lxc/rootfs ... sed: can't read /var/lib/lxc/centos_lxc/rootfs/etc/init/tty.conf: No such file or directory Storing root password in '/var/lib/lxc/centos_lxc/tmp_root_pass' Expiring password for user root. passwd: Success sed: can't read /var/lib/lxc/centos_lxc/rootfs/etc/rc.sysinit: No such file or directory sed: can't read /var/lib/lxc/centos_lxc/rootfs/etc/rc.d/rc.sysinit: No such file or directory Container rootfs and config have been created. Edit the config file to check/enable networking setup. The temporary root password is stored in: '/var/lib/lxc/centos_lxc/tmp_root_pass' The root password is set up as expired and will require it to be changed at first login, which you should do as soon as possible. If you lose the root password or wish to change it without starting the container, you can change it from the host by running the following command (which will also reset the expired flag): chroot /var/lib/lxc/centos_lxc/rootfs passwd
You can get the default credentials at the end of the output.
Start and take a console of Ubuntu container with the following command. You must change the root password at first login.
$ sudo lxc-start -n centos_lxc -d $ sudo lxc-console -n centos_lxc Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself CentOS Linux 7 (Core) Kernel 4.4.0-15-generic on an x86_64 centos_lxc login: root Password: You are required to change your password immediately (root enforced) Changing password for root. (current) UNIX password: New password: Retype new password: [root@centos_lxc ~]#
That’s All! thanks for reading. Be social, share this with your friends.