Choose IBM’s Docker-based Container Service on Bluemix for your I/O intensive code

Few weeks ago IBM announced general availability of a new Docker-based container service[1] as part of Bluemix PaaS[2]. The service was in beta since the beginning of 2015 and looks very promising, especially for I/O heavy workloads like databases and analytics. This post will help you create your own container instance running on Bluemix and provide some pointers on how you can evaluate whether the I/O performance of the instances matches your application’s needs. It will also describe the nuances of using Docker Machine[5] if you are running Mac OSX or Windows.

Even if you are not familiar with Docker, chances are you know about virtual machines. When you order a server hosted in a cloud, in most cases you get a virtual machine instance (a guest) running on a physical server (a host) in your cloud provider’s data center. There are many advantages in getting a virtual machine (as opposed to a physical server) from a cloud provider and arguably the top one is quicker delivery. Getting access to a physical server hosted in a data center usually takes hours while you can get a virtual machine in a matter of minutes. However, many workloads like databases and analytics engines are still running on physical servers because virtual machine hypervisors introduce a non-trivial penalty on I/O operations in guest instances.

Enter Linux Containers(LXC) and Docker. Instead of virtualizing the hardware (as the case with traditional virtual machines) containers virtualize the operating system. Start up time for containers is as good or better (think seconds not minutes) than for virtual machines and the I/O overhead all but disappears. In addition, Docker makes it easier to manage both containers and their contents. Containers are not a panacea and there are situations where virtual machines make more sense but that’s a topic for another post.

In this post, you can follow along with the examples to learn whether I/O performance of Docker containers on IBM Bluemix matches your application’s needs. Before starting, make sure that you have access to Bluemix[3] and to the Container Service[4].

Getting Started

The following steps describe how to use Docker Machine[5] for access to a Docker installation. You can skip the Docker Machine instructions if you are already running Docker 1.6 or higher on your Linux instance. Otherwise, you’ll want a Docker Machine which deploys a VirtualBox guest with Tiny Core Linux to OS X or Windows and you can ssh into the guest to access docker CLI.

Start of Docker Machine specific instructions

Install Docker Machine as described here[5].  Use the following command to connect to your Docker Machine Tiny Core Linux guest

docker-machine ssh dev

Install python and the ice CLI tool in your guest so you can interface with the IBM Container Service environment. The approach used in these steps to install python is specific to TinyCore Linux and shouldn’t be used on other distros.

tce-load -wi python
curl https://bootstrap.pypa.io/get-pip.py -o - | sudo python
curl https://bootstrap.pypa.io/ez_setup.py -o - | sudo python
curl -o cf.tgz -L -O https://cli.run.pivotal.io/stable?release=linux64-binary
sudo tar -zxvf cf.tgz -C /usr/bin/
curl -O https://static-ice.ng.bluemix.net/icecli-3.0.zip
sudo pip install icecli-3.0.zip
rm -f cf.tgz icecli-3.0.zip setuptools-18.0.1.zip

End of Docker Machine specific instructions

If you are not using Docker Machine, you should follow the standard ice CLI installation instructions[6]

Before proceeding, you will create a public/private key pair which you’ll use to connect to your container. The following steps save your private key file to id_rsa and your public key file to id_rsa.pub with both in your local directory. The second step ensures that the private key file is ignored by Docker and doesn’t get included in your image.

sudo ssh-keygen -f id_rsa -t rsa
echo id_rsa > .dockerignore

Make sure that you have access to the IBM Container Service from the Bluemix dashboard as described here[8] and proceed to login using the ice CLI with the command below. Note that when prompted you’ll need to enter your Bluemix credentials and to specify the logical organization as well as the space where your container will reside.

ice login

The login command should complete with a Login Succeeded message.

Next, you will pull one of the base IBM Docker images and customize it with your own Docker file:

docker pull registry.ng.bluemix.net/ibmnode:latest

Once the image completed downloading, you will create a Dockerfile that will customize the image with your newly created credentials (so you can ssh into it) and with sysbench scripts for performance testing.

Create a Dockerfile using your favorite editor and the following contents:

FROM registry.ng.bluemix.net/ibmnode:latest
MAINTAINER Carl Osipov

ADD *.sh /bench/

EXPOSE 22
COPY id_rsa.pub /root/.ssh/
RUN cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys

RUN apt-get update && apt-get install -y sysbench

Next, create io.sh with the following contents

#!/bin/sh
SIZE="$1"
sysbench --test=fileio --file-total-size=$SIZE prepare
sysbench --test=fileio --file-total-size=$SIZE --file-test-mode=rndrw --init-rng=on --max-time=30 --max-requests=0 run
sysbench --test=fileio --file-total-size=$SIZE cleanup

And cpu.sh containing:

#!/bin/sh
PRIME="$1"
sysbench --test=cpu --cpu-max-prime=$PRIME run

add execute permissions to both scripts

chmod +x *.sh

At this point your custom Docker image is ready to be built. Run

docker build -t sysbench .

which should finish with a Successfully built message followed by an ID.

Push your custom Docker image to Bluemix

When you first accessed the Container Service via the Bluemix dashboard[4], you should have specified a custom namespace to be used when provisioning your containers. Note that in the steps below, `ice namespace get` is evaluated to retrieve the custom namespace which is unique to your account.

docker tag sysbench registry.ng.bluemix.net/`ice namespace get`/sysbench
docker push registry.ng.bluemix.net/`ice namespace get`/sysbench
ice run -p 22 -n sysbench `ice namespace get`/sysbench

After you’ve executed the commands above, your container should be in a BUILD stage which changes to the Running stage after a minute or so. You can verify that by executing

ice ps

Request a public IP address from the Container Service and note its value.

ice ip request

Bind the provided public IP address to your container instance with

ice ip bind <public_ip_address> sysbench

Now you can go ahead and ssh into the container using

sudo ssh -i id_rsa root@<public_ip_address>

Once there, notice it is running Ubuntu 14.04

lsb_release -a

on a 48 core server with Intel(R) Xeon(R) CPU E5-2690 v2 @ 2.60GHz CPUs

cat /proc/cpuinfo
...
processor : 47
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz

Now you can also test out the I/O performance using

. /bench/io.sh 100M

Just for a comparison, I ordered a Softlayer virtual machine (running on a Xen hypervisor) and ran the same Docker container and the benchmark there. In my experience, the I/O benchmark results were roughly twice better on the Container Service than on a Softlayer VM. You can also get a sense of relative CPU performance using

. /bench/cpu.sh 5000

Conclusions

Benchmarks are an artificial way of measuring performance and better benchmark results don’t always mean that your application will necessarily run better or faster. However, benchmarks can help you understand if there exists potential for better performance and help you design or redesign your code accordingly.

In case of the Containers Service on IBM Bluemix, I/O benchmark performance results are significantly superior to those from a Softlayer virtual machine. This shouldn’t be surprising since Containers runs on bare metal Softlayer servers. However, unlike the hardware servers, Containers can be delivered to you in seconds compared to hours for bare metal. This level of responsiveness and workload flexibility enable Bluemix application designers to create exciting web applications built on novel and dynamic architectures.

References

[1] https://developer.ibm.com/bluemix/2015/06/22/ibm-containers-on-bluemix/
[2] https://console.ng.bluemix.net
[3] https://apps.admin.ibmcloud.com/manage/trial/bluemix.html
[4] https://console.ng.bluemix.net/catalog/?org=5b4b9dfb-8537-48e9-91c9-d95027e2ed77&space=c9e6fd6b-088d-4b2f-b47f-9ee229545c09&containerImages=true
[5] https://docs.docker.com/machine/#installation
[6] https://www.ng.bluemix.net/docs/starters/container_cli_ov_ice.html#container_install
[7] https://www.ibm.com/developerworks/community/blogs/1ba56fe3-efad-432f-a1ab-58ba3910b073/entry/ibm_containers_on_bluemix_quickstart?lang=en&utm_content=buffer894a7&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer
[8] https://www.ng.bluemix.net/docs/containers/container_single_ov.html#container_single_ui