Skip to content

XIA Linux Containers (XLXC)

Cody Doucette edited this page Mar 15, 2017 · 34 revisions

It is useful to create many XIA hosts for debugging and testing purposes. Although virtual machines can be created to suit this need, simulating larger networks of dozens or hundreds of nodes requires a more lightweight virtualization solution. Linux Containers are perfect for this task, as they isolate system resources and namespaces to create virtual environments but do not require as many resources as true virtual machines do.

There is a repository that contains scripts for creating many containers that have the ability to run the XIA kernel, assuming the host machine is running XIA. These scripts can be obtained with this command:

 $ git clone http://github.com/cjdoucette/xlxc.git

Before the scripts can be used, the basic LXC package, Ruby, and tools for network bridges must be obtained:

 # apt-get install lxc ruby1.9.1 bridge-utils

Additonally, the Ruby library ("gem") netaddr must be installed:

 # gem install netaddr 

Table of Contents

Ubuntu Version Information

The XLXC scripts are currently updated for Ubuntu 14.04 (Trusty Tahr). Your mileage may vary if trying to use XLXC with a different version of Ubuntu. However, you can obtain a virtual machine running Ubuntu 14.04 with an XIA kernel on the page Setting up an XIA development environment.

Create a Container

To create containers, an Ethernet bridge must first be created. This will allow containers to communicate with the host and, potentially, with other containers.

Create an Ethernet Bridge Using xlxc-bridge.rb

In order to create a bridge, you need a name for the bridge and a block of IP addresses in CIDR notation for interfaces that will attach to the bridge. The format of the command to create a bridge with the xlxc-bridge.rb script is:

 # ruby xlxc-bridge.rb -b bridge -c cidr

For example:

 # ruby xlxc-bridge.rb -b xiabr -c 192.168.10.0/24

Create a Container Using xlxc-create.rb

Once an Ethernet bridge is created, a container can be created using that bridge with the xlxc-create.rb script. To do so, you need a name for the container and the name of the Ethernet bridge that you want to attach to. The format of the command to create a container is:

 # ruby xlxc-create.rb -n name -b bridge

For example:

 # ruby xlxc-create.rb -n xia0 -b xiabr

Run a Container

Once a container is created, it can be executed or run.

Run a Container Using xlxc-start.rb

The xlxc-start.rb script initializes a container's networking resources and boots the container. The format of the program is:

 # ruby xlxc-start.rb -n name

For example:

 # ruby xlxc-start.rb -n xia0

It's most useful to start the container as a daemon and then use lxc-attach to login to the container as the root user (no password is required):

 # ruby xlxc-start.rb -n xia0 --daemon
 # lxc-attach -n xia0

Execute a Program in a Container Using xlxc-execute.rb

xlxc-execute.rb is capable of running a container on a command. For example, if the user wants to make an XIA container and add an HID, then the following commands could be used:

 # ruby xlxc-execute.rb -n xia0 -- sudo xip hid new xia0 && sudo xip hid add xia0 && cat

This would start an XIA container, create a new HID, and add that HID to the container. The final command, cat, is a way of keeping the container running. Otherwise, the container will close.

A more flexible way of doing this would be to create a script that the container can run. xlxc-create.rb is equipped to be able to create a unique script for each container if "--script" is indicated in the xlxc-create.rb command. By default, xlxc-create.rb creates a script for each container that looks like (for a container named xia0):

run.sh

 # Add HID for this container.
 sudo xip hid new xia0
 sudo xip hid add xia0
 # Keep container running.
 cat

This executable script can then be found in the root directory of the container. From the perspective of the host, it is /var/lib/lxc/xia0/rootfs/run.sh. With this script, the commands could instead be:

 # ruby xlxc-execute.rb -n xia0 -- ./run.sh

This way, run.sh can contain any number of commands to be executed automatically without logging-in to the container. Users are encouraged to edit the create_script function in xlxc-create.rb to make their own container scripts.

Stop a Container Using xlxc-stop.rb

To stop a running container, use the xlxc-stop.rb script. All that is required for this script is the name of the container that you wish to stop:

 # ruby xlxc-stop.rb -n name

For example:

 # ruby xlxc-stop.rb -n xia0

Destroy a Container

Once you are done with a container, you can destroy it using the xlxc-destroy.rb script.

Destroy a Container Using xlxc-destroy.rb

The purpose of the xlxc-destroy.rb script is to stop and destroy the container specified, including removing any files that were bind mounted. To do this, the user needs to specify the name of the container to be destroyed:

 # ruby xlxc-destroy.rb -n name

For example:

 # ruby xlxc-destroy.rb -n xia0

Destroy a Bridge Using xlxc-bridge.rb

If you want to destroy an Ethernet bridge, you can do so using xlxc-bridge.rb. Typically, you will want to do this only after destroying all containers using the bridge:

 # ruby xlxc-bridge.rb -b bridge --del

For example:

 # ruby xlxc-bridge.rb -b xiabr --del

This command will warn you if there are containers associated with a bridge you are trying to delete. However, you can force the bridge to be deleted with the --force option:

 # ruby xlxc-bridge.rb -b bridge --del --force

Create and Use a Container Network

There is also a script named xlxc-net.rb that makes creating a large number of containers very easy. It is basically a wrapper for xlxc-bridge.rb, xlxc-create.rb, xlxc-destroy.rb, xlxc-start.rb, xlxc-stop.rb, and xlxc-execute.rb.

To create a network of containers, xlxc-net.rb is used in the following form:

 # ruby xlxc-net.rb -n name -s size --create -t topology

For example, to create a bridge and ten containers all on the same LAN (using the same bridge), the following command could be used:

 # ruby xlxc-net.rb -n xia -s 10 --create -t connected 

This will create ten containers, named xia0, xia1, ..., xia9, all using the same bridge, xiabr.

The containers could also be created on separate LANs, using separate bridges, by specifying the star topology:

 # ruby xlxc-net.rb -n xia -s 10 --create -t star

This will also create ten containers, named xia0, xia1, ..., xia9, but each container will use a different bridge. The container xia0 will use the bridge xia0br, the container xia1 will use the bridge xia1br, etc.

To destroy a network of containers, xlxc-net.rb can also be used:

 # ruby xlxc-net.rb -n name -s size --destroy -t topology

For example, to delete the connected network created above:

 # ruby xlxc-net.rb -n xia -s 10 --destroy -t connected 

Networks of containers can also be started and stopped using xlxc-net.rb. When starting a network of containers, they will by default be started in daemon mode.

 # ruby xlxc-net.rb -n xia -s 10 --start

This command would start containers xia0, ..., xia9. You can then attach a console to any of these containers using lxc-attach:

 # lxc-attach -n xia5

To stop all containers at the same time, xlxc-net.rb can be used with the --stop switch:

 # ruby xlxc-net.rb -n xia -s 10 --stop

Finally, xlxc-net.rb can also be used to abstract the xlxc-execute.rb script (more information above) to networks of containers. For example:

 # ruby xlxc-net.rb -n xia -s 10 --execute -- ./run.sh

Miscellaneous

Using LXC Scripts

Some of the original LXC scripts can be used for Linux XIA containers as well. For example, you can view all containers with the following command:

 # lxc-ls --fancy

Or, you can freeze and unfreeze the containers using lxc-freeze and lxc-unfreeze.

However, you should not use lxc-create, lxc-destroy, lxc-start, lxc-stop, or lxc-execute. These scripts are not compatible with XLXC because they do not use bind mounts or custom networking settings.

Loading and Unloading Kernel Modules

Containers share the kernel with the host. Therefore, a container cannot add or remove kernel modules. In order to use XIA, the host must first load any principals that are desired. However, containers are then free to use those principals in their namespace by, for example, adding entries to their routing table.

Putting XLXC to work

The page zFilter principal shows an instructive example of use of XLXC that is easy to modify and extend.