-
Notifications
You must be signed in to change notification settings - Fork 42
XIA Linux Containers (XLXC)
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
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.
To create containers, an Ethernet bridge must first be created. This will allow containers to communicate with the host and, potentially, with other containers.
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
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
Once a container is created, it can be executed or run.
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
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.
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
Once you are done with a container, you can destroy it using the xlxc-destroy.rb script.
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
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
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
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.
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.
The page zFilter principal shows an instructive example of use of XLXC that is easy to modify and extend.
All grants that have generously supported the development of Linux XIA are listed on our Funding page.