Introduction
Instructions tested with Ubuntu 14.04.
Install
Install LXC,
sudo apt-get install lxc
Create Regular Privileged Container
The simplest to implement container is a privileged container. In other words, the user and process running the container is root. This is not as bad as it seems from a security perspective and easiest to manage (so far). Tin to talk to Dickson to find out if Solaris (which is more mature with container technology) started using unprivileged and if so will look into that next for Linux.
Container Derived from Host OS
This draws the files from the existing image matching the Base OS to make your container. I observed it may also be looking at details of your Host OS as the process creates accounts in the image that matched Host OS. The image folder was created/downloaded during the lxc setup and resides in /var/cache/lxc/trusty/rootfs-amd64. The template file to create the container resides in /usr/share/lxc/templates/,
The --name specified will also be the container's name.
sudo lxc-create --template ubuntu --name my-container Checking cache download in /var/cache/lxc/trusty/rootfs-amd64 ... Installing packages in template: ssh,vim,language-pack-en Downloading ubuntu trusty minimal ... I: Retrieving Release I: Retrieving Release.gpg ... I: Resolving dependencies of base packages...
The rootfs-amd64 folder is only 384MB and was created when lxc was installed. The OS version will match your Host OS.
You may also download additional LXC image templates which may be different distributions (for example, OpenSUSE, Cent OS, Fedora and Arch Linux) and various versions of your Host OS.
You can see your new container,
sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART ------------------------------------------ app STOPPED - - NO # look at the stopped container sudo lxc-info --name my-container Name: my-container State: STOPPED
Sparse Container from Host OS
Not sure if this functionality exists yet. Solaris has a concept of a sparse root zone which I would call here sparse container. The idea to reduce scope overhead so that aside from basics (home, opt, temp) the rest of the file system is actually mounted as read-only from the Host OS. In this model we have tighter security and upgrade the Host OS would upgrade all containers on the OS.
File Structure
You will need to use sudo or root to view the directories. I use root,
sudo su - # log into root
There are 3 key files,
/var/lib/lxc/<container name>/config # used to configure container /var/lib/lxc/<container name>/rootfs # container file system (to do: understand how permissions uid matches) /var/lib/lxc/<container name>/fstab # controls mounting so you can share folders btw host OS and container /etc/default/lxc-net # controls general network settings (need to confirm)
See lxc.conf(5) for additional configuration options on the above files.
Container Networking
By default, LXC creates a private network namespace for each container using a DHCP server (dnsmasq), a NAT server (package name?) and configures IP Tables masquerade entries for outbound network access.
In other words, containers exist within a private network, may see each other, pull network data to whatever the host can access, but nothing outside aside from the host itself will see these servers. A good analogy is your home network behind 1 public IP given on your service provider router.
Static LXC Assigned IP
When working with servers it is best to use static IPs. This should be your first step if seriously using containers for production use. By default, LXC assigns an internal set of IPs within the range of 10.0.3.2 to 10.0.3.254 which is defined in /etc/default/lxc-net.
Change the range and enable reservations in /etc/default/lxc-net.
First change the range (LXC_DHCP_RANGE) and the maximum lease # (LXC_DHCP_MAX) to make available 10.0.3.2 to 10.0.3.99 for static assignment,
LXC_BRIDGE="lxcbr0" LXC_ADDR="10.0.3.1" LXC_NETMASK="255.255.255.0" LXC_NETWORK="10.0.3.0/24" LXC_DHCP_RANGE="10.0.3.100,10.0.3.254" LXC_DHCP_MAX="155"
Second, enable Reservations - Remove the # symble to enable "LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf".
# Uncomment the next line if you'd like to use a conf-file for the lxcbr0 # dnsmasq. For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have # container 'mail1' always get ip address 10.0.3.100. LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
Create and edit the /etc/lxc/dnsmasq.conf,
# Specify static IPs per container name or mac address. # Addresses should be outside of range in /etc/default/lxc-net (10.0.3.100 to 10.0.3.254) dhcp-host=web,10.0.3.10 dhcp-host=app,10.0.3.20 dhcp-host=database,10.0.3.30
Specify static IPs per container name (you can also use the container's mac address in situations of multiple network interfaces) (I have not tried or tested yet). To avoid conflicts, make sure the static IP addresses are outside of the range specified in /etc/default/lxc-net.
(... investigate later, when using macvlan, can I specify the external IP address here too?)
Make sure to turn off your containers and then restart the Host OS. It seems though, that a certain amount of time is needed for whatever is touching lxc-net to register the changes. (find out how to flush this).
I have read that there are ways to apply the changes without a restart but have not yet tested myself. The steps I have read are,
# Personally don't like what I see here... sudo service lxc-net restart sudo killall -s SIGHUP dnsmasq # this command did not appear to work and there was no way to do apt-get install killall # Tried this and it did noot work http://seminar.io/2014/07/27/dns-resolution-for-lxc-in-ubuntu-trusty/ sudo service lxc-net stop sudo service lxc-net start
Make sure everything restarted fine without errors. I had run into forgetting to change LXC_DHCP_MAX which resulted in lxc-dhcp not starting,
# Search boot log for errors, ... to put here ...
You may alternatively set the container OS itself to use static using the interfaces file.
Making Containers Available on the Network
Containers may also be made available on the larger network which is covered in 5.1 LXC with Advanced Networking.
Start Container
This starts the container as a process,
# start the container sudo lxc-start --name my-container --daemon # look at the running container sudo lxc-info --name my-container Name: my-container State: RUNNING PID: 3553 IP: 10.0.3.135 CPU use: 0.59 seconds BlkIO use: 384.00 KiB Memory use: 6.45 MiB KMem use: 0 bytes Link: vethBNKT75 TX bytes: 3.08 KiB RX bytes: 3.27 KiB Total bytes: 6.35 KiB
For troubleshooting, you may omit --daemon which will run the containers as an actual program where you can see the container booting up.
Logging In
Default template (so far in my own fresh install of Ubuntu 14.04) has no accounts on the base OS. For initial setup and emergencies, while on the base OS, use base OS root to get into container root (no password required),
sudo lxc-attach -n my-container
Strangely, going on my payed for server (where I installed minimal virtual machine with same Linux 14.04) resulted in ending message saying default account was created. In which case, you can load a console...
Replicate loading console,
sudo lxc-console -n my-container
To detach, CTRL+a, followed by ‘q’.
Container Management Key Commands
Here are some of the key commands for container management,
# stop sudo lxc-stop --name my-container # destroy sudo lxc-destroy --name my-container # snapshot # clone, but you still have to manually change the host file sudo lxc-clone -o original -n new sudo sed -i 's/original/new/' /var/lib/lxc/new/rootfs/etc/hosts # update host file # rename
Clone - after cloning make sure to manually update the hosts file as it still uses the older name.
There is more to write (link to sites).
Share Folders with Host
... (this will be moved into a separate article)
In this example, we want to mount a shared directory from the host system to be accessible to one or more containers,
container my-container directory = /opt/mount-host
You may actually use the same directory name and path for both host and container, but I have kept them different for clarity.
While in the lxc container, create your directory and setup any permission you may want to set,
cd /opt sudo mkdir mount-host sudo chown serveradmin:staff # make accessible to the serveradmin user and the all staff sudo shutdown -h now # shutdown the container
From the host modify the config files. In this example it is /var/lxc/my-container/config and add the following line,
lxc.mount.entry = /opt/lxc/shared/lxc/my-container /opt/mount-hostbg none bind.rw 0.0
Not sure if the order matters, but I usually place under the lxc.mount entry. The bind.rw is a reference to read and write which you may adjust accordingly for example bind.ro would be read only.
Moving Container to New Host
... (this will probably be a separate article)
Setting Up Zero Footprint 32-bit Java on LXC 64-bit
By default, the apt-get packages only use 64-bit architecture,
sudo dpkg --add-architecture i386 sudo apt-get update
Then follow-up with installing the proper dependencies, but not sure if I need to install in the host... need to try this out in a VM.
References
Good overview of lxc - https://www.flockport.com/lxc-vs-docker/
Initial article reviewing - https://linuxcontainers.org/lxd/introduction/
Official Ubuntu Docs - https://help.ubuntu.com/lts/serverguide/lxc.html#lxc-installation
Changing dnsmasq IP range - http://skyhigh71.github.io/2013/09/29/change_ip_address_range.html
Still to read - appears to be distilled LXC theory - http://the.binbashtheory.com/before-you-start-with-lxc-and-docker/#more-26