Few weeks ago IBM announced general availability of a new Docker-based container service as part of Bluemix PaaS. 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 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 and to the Container Service.
The following steps describe how to use Docker Machine 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. 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
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 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.
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, 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
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
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
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.