Regardless if you’ve migrated multiple applications or this is your first migration to a public Infrastructure-as-a-Service (IaaS) you will want to run a small proof-of-concept to make sure that the basic elements of data flow operate as expected and your components will run in the IaaS environment. This week I spent some time experimenting with the three top IaaS offerings: Amazon AWS, Google Compute Cloud and Microsoft Azure. The architecture was relatively simple: 3 docker containers, one hosting a LAMP—Linux, Apache, MySQL & PHP—stack running WordPress, one hosting Postfix mail server forwarding all mail, and one hosting CVS. The results of the testing were informative.
Google only offers a limited number of Linux versions by default, one of them is not Ubuntu, so I was forced to use Red Hat Enterprise. Luckily, the only thing that had to change was how to install Docker. Once Docker was installed, I created an Ubuntu layer and I was able to run my container builds. Google clearly had the best network performance of all three vendors. This was clear in how quickly the containers were able to pull from the various repositories. However, the issues of deploying these containers in this environment were soon apparent. The LAMP stack included a Secure Shell (SSH) interface that the host machine would not allow me to bind my Docker container to. This problem could not be overcome without significant rework and was required to finish the install. I put that aside and continued onto the Postfix container. That’s when it got real frustrating as I learned I could not bind the container to port 25 (SMTP). That’s right folks, the Gmail people don’t want you using their platform to build a mail server, go figure.
There’s a reason why AWS is the leader in cloud services, their user interface was the most elegant for building out the server environment that I designed. Moreover, their t1.micro edition was perfect for doing the early testing work without incurring a lot of charges and when I was done I was able to create a snapshot of that server and use it as the formation of an m3.medium. I selected the Ubuntu 14.04 64-bit EBS-backed machine image to start with, which greatly reduced the amount of data that Docker had to pull in order to formulate the base images. Since I already hosted my existing WordPress and CVS repository on Amazon, I set up an Elastic IP and just moved the association back and forth to test against jpmorgenthal.com, this greatly reduced the headache of setting up WordPress and Postfix since they required the domain name.
Of note, I was having a heck of a time getting my Postfix container running. I could connect to the server using localhost, but could not connect from my home development machine. I removed all firewalls and confirmed that the security rules allowed port 25. I checked the issue on the Interwebs and found others having the same issue. There was a common belief that AWS was block port 25. In truth they are not, but I did find out they limit outbound port 25 calls in an attempt to make sure that customers don’t shoot themselves in the foot and get identified as spammers. The real issue was that Comcast blocks outbound port 25, which I discovered by connecting through another t1.micro instance telnet session that worked fine. The bigger issue here is what is the responsibility of the cloud service provider to protect the credibility of the whole as AWS is doing with outbound email? Is it really they are trying to protect their clients or is it that they have an outbound SMTP mailing service that they want customers to use?
Total cost for using a mix of t1.micro and m3.medium with 15 GB EBS with Elastic IP and multiple snapshots over a period of 9 hours was a whopping $1.65
Microsoft, like Google, has excellent network performance and the performance of their smallest class of virtual servers also completed the process of building the LAMP container in a reasonable amount of time. Their portal interface was very intuitive for creating the Ubuntu server and they offered the option of using a password in addition to a x.509 certificate, which was a handy option that was not offered with Google or AWS. As with Amazon, once the containers were instantiated they performed well and were accessible across all ports that were exposed on the network interface.
Where Azure falls short today is in their networking. They do not have an Elastic IP service like Amazon, which made it very difficult to switch between the current server and the test environment. This would not bode well for dev/test scenarios where it would be useful to have a single DNS entry for the testing scripts and then just point that entry at the current test environment. It seems, based on some limited web searching, that customers really want dynamic IP addressing on Azure and Microsoft has not responded to this requirement.
Some quick notes on Docker itself. I found that the most success I had was when starting with a Dockerfile and doing my own builds to bootstrap an environment. This way facilitates that all the necessary ports that need to be exposed are set up appropriately and its easier to inject a foreground script that will keep the container alive after it is started. This latter point is key. A daemon-ized container requires that something be continually running in the foreground to keep the container alive. This can be done with a while..do script command handed to /bin/sh, but it’s far more effective to use the startup script that ensures all the necessary services have started and then goes into a wait loop. Also, if you do changes to your container once its started e.g. via SSH, remember to commit the changes when you exit the session or you will be repeating those steps the next time you run the container.