Overview

Skill Level: Any Skill Level

Ingredients

A system or VM running Linux

(optional) docker command line tools

Installation of the rkt toolkit https://github.com/coreos/rkt/releases

actool from the appc-<version>.tar.gz download at https://github.com/appc/spec/releases/

An interest in running an AMQP 1.0 broker designed to help you develop your apps

Step-by-step

  1. Create an ACI from the MQ Light docker image

    NB: Rkt currently does not support running apps in a container as any user except root, the latest instance of the MQ Light docker image requires this, until this is fixed the following will currently not work.

    If you already have docker installed the easiest way to create an ACI is to take the docker image and convert it.

    To do this we need a container run with the MQ Light image;

    docker run ibmimages/mqlight

    This will download the MQ Light docker image and start a container from it that will instantly exit complaining that you need to accept the license before it will run, but it has done enough for our needs.

    docker ps -aCONTAINER ID   IMAGE                      COMMAND     CREATED              STATUS   PORTS   NAMESd82485acb216   ibmimages/mqlight:latest   "mqlight"   About a minute ago   Exited           elated_wright

    This shows the container that was created by running the image and we can use this information to export it. FIrst you need to create a directory where we will put the data needed for the ACI

    mkdir -p mqlight/rootfs

    We’ll use a directory called mqlight, the folder “rootfs” holds the filesystem that makes up the container.

    docker export elated_wright | tar -x -C mqlight/rootfs -f -

    Using the name for the container we got earlier we tell docker to export the image, from the docker docs https://docs.docker.com/reference/commandline/cli/#export we can see that export produces a tar archive, so we pipe the output into tar and tell it to extract the contents into “mqlight/rootfs”

    Now that we have the filesystem for our container we need the App Container Spec manifest file that defines the running environment for the ACI we’re going to create. For more information on the App Container Spec; https://github.com/appc/spec/blob/master/SPEC.md

    The section “Creating the ACI manifest file” has the full manifest, copy it into a file in the “mqlight” directory called “manifest”

    We should now have a directory called “mqlight” that contains a directory called “rootfs” that contains the filesystem for our container and a file called “manifest” that defines the environment for running our container. Time to create the ACI…

  2. Creating the ACI manifest

    App Containers have a manifest, a JSON file, that defines metadata about the image, applications that are launched when the container is run and for each application configuration details such as environment variables, mount points and ports that will be used.

    Below is the complete manifest file that will be used for this container

    {"acKind": "ImageManifest","acVersion": "0.5.3","name": "mqlight","app": {"environment": [{"name": "MQLIGHT_HOME","value": "/opt/mqlight"},{"name": "MQLIGHT_DATA_PATH","value": "/var/mqlight"}],"exec": ["/usr/local/bin/mqlight"],"eventHandlers": null,"user": "0","group": "0","mountPoints": [{"name": "data-path","path": "/var/mqlight","readOnly": false}],"ports": [{"name": "amqp","port": 5672,"protocol": "tcp","socketActivated": false},{"name": "web","port": 9180,"protocol": "tcp","socketActivated": false}]}}

    In this case there is only the one app which is the script responsible for launching the MQ Light server. We’ve set two environment variables that are required to say where MQ Light was installed to and where it should store its data. We’ve declared a mount point called “data-path”, when we run the container we define a local directory for this mount point an the container environment maps the two together. We also specify two ports that the container will expose, 5672 is for amqp traffic and 9180 which is the web interface for the MQ Light server. The “user” and “group” options allow you to specify a specific user and group that the app should be run as in the container, at this time no other option but “0” is supported.

    This configuration should be put into a file called “manifest” in the same folder as the “rootfs” directory for the container being created.

  3. Creating an ACI from scratch

    So you want to craft your container image from scratch, but why? Maybe you want to make it smaller. The docker MQ Light image is based on the ubuntu base which will include packages that are not needed. Perhaps you want to include some other functionality in your container, or change some of the standard configuration.

    In this section we will be using “debootstrap” on ubuntu to create our container file system, if you don’t have it already installed

    apt-get install debootstrap

    Firstly we’re going to need a directory to store the container filesystem and configuration

    mkdir -p mqlight/rootfs

    Great, now lets get a filesystem. We’re going to use debootstrap with the “minbase” variant (which only includes essentials and apt), based on Ubuntu “Trusty Tahr” (as that’s the current Long Term Support release) and put all the files into “mqlight/rootfs”. We’re also adding the “curl” and “sudo” packages to the install list as we’ll use them shortly.

    debootstrap --variant=minbase --components=main --include=curl trusty mqlight/rootfs

    So that’s the filesystem for the container but what about MQ Light itself? We’re not quite ready for that yet, first we have to do some config and setup on our filesystem.

    chroot mqlight/rootfs /bin/bash

    This puts us inside the filesystem that we created with debootstrap so we can set it up

    mkdir -p /opt/mqlightmkdir -p /var/mqlightsed -e 's/^%sudot.*/%sudotALL=NOPASSWD:ALL/g' -i /etc/sudoers

    We create the directory that we’re going to install MQ Light into, and the directory that MQ Light will use to store configuration and other data “/var/mqlight”, this will actually be overlaid with a directory on the host system when we actually run the image.

    Finally we add a line to “/etc/sudoers” to allow all members of the “sudo” group

    Installing MQ Light time. Being as we’re working with rkt which is a pretty new, fast moving thing we’re going to also use the early access version of MQ Light, go to the MQ Light home page to check the download location for the current early access release.

    curl -sL http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqkoa/IBM-MQ-Light-Linux-x64-early-access-L150326.1.tar.gz | tar -zx --strip-components 1 -C /opt/mqlight

    Part of what was created for the MQ Light docker container is a script that is used to start and stop MQ Light and we’re going to reuse it in our ACIf

    curl -k -o /usr/local/bin/mqlight https://raw.githubusercontent.com/ibm-messaging/mqlight-docker/master/early-access/mqlightchmod +x /usr/local/bin/mqlightsed -e 's//home/user//root/' -i /usr/local/bin/mqlightsed -e 's/user:staff/root:root/' -i /usr/local/bin/mqlightsed -e 's/owner=user/owner=root/' -i /usr/local/bin/mqlightsed -e 's/group=staff/group=root/' -i /usr/local/bin/mqlight

    and make it executable. Unfortunately at this time rkt doesn’t support running container apps as any user other than root so we have to make some changes to it which is all the ‘sed’ commands. This script expects a tar.gz file of mqlight configuration data when it starts up, handily it provides function to do this for us. First though we have to mount /proc otherwise java in this chroot environment won’t run properly

    mount -t proc none /proc

    Run the mqlight script with the intialize option

    su -c "MQLIGHT_HOME=/opt/mqlight MQLIGHT_DATA_PATH=/var/mqlight /usr/local/bin/mqlight initialize"

    We also set a couple of environment variables that are required, we run it under su here to ensure the environment is correct. It’ll take 30 seconds or so to finish, and when it it you should find a file called “mqlight-data.tar.gz” in “/root”. Don’t forget to unmount /proc from the chroot or trying to build the aci in later steps will fail

    umount /proc

    End the chroot session and we’re done here.

    Now that we have the filesystem for our container we need the App Container Spec manifest file that defines the running environment for the ACI we’re going to create. For more information on the App Container Spec; https://github.com/appc/spec/blob/master/SPEC.md

    The section “Creating the ACI manifest file” has the full manifest, copy it into a file in the “mqlight” directory called “manifest”

    We should now have a directory called “mqlight” that contains a directory called “rootfs” that contains the filesystem for our container and a file called “manifest” that defines the environment for running our container. Time to create the ACI…

  4. Building and running our new container

    (Assuming the actool command is on your path)

    actool build mqlight mqlight.aci

    After a minute or so the command should finish and you should find you have a file of about 290 MB called mqlight.aci

    Now the fun part, running our container…

    (Again assuming the rkt command is on your path)

    rkt run --volume data-path,kind=host,source=/var/rkt/mqlight --set-env LICENSE=accept mqlight.aci

    Reading though the manifest you’ll have noticed that we declared a mount point called “data-path” this is a location external to the container that will be mapped to “/var/mqlight” inside the container. We declare where this location is from the host side with the “–volume” option, “source=” specifying the location to map to “data-path”.

    Now it’s running you should be able to go to http://127.0.0.1:9180 in your browser and see the MQ Light interface, the Documentation tab has details on the different languages MQ Light has specific clients for (or alternatively you can use any other AMQP 1.0 client such as the Apache Qpid Proton clients)

Expected Outcome

An Application Container Image (ACI) with MQ Light installed that can be launched by the rkt toolset

Join The Discussion