Docker: What’s new and what’s next?
If you use DevOps, like we do at Askida, you’re probably familiar with Docker, an open platform that allows developers and system administrators to build, ship and run distributed applications. A few weeks ago, I was lucky enough to attend DockerCon in Austin, Texas, which blew me away. It was very stimulating and inspiring to be around Docker experts from all over the world and hear them talk about the future of the platform. I couldn’t wait to get my hands on some of the new features!
Coming back from the conference, I thought I’d take a moment to discuss what’s new in the world of Docker and where the platform is heading next. The first thing to know is what Docker recently changed its versioning system to standardize Docker’s Enterprise and Community editions. Versioning now employs the following format: Year.Month.Version, plus either -ce (for Community Edition) or –ee (for Enterprise Edition). To give you a concrete example, a March 2017 release of the Community Edition would be referred to as “17.03.0-ce.” Community Edition also comes in two versions: Regular and Edge.
The main differences between Enterprise Edition, Community Edition and Community Edge Edition are the frequency of releases and the support period. Community Edge Edition, for example, is released every month and is only supported for a few weeks, so you need to upgrade as soon as a new version is available. For production systems, this isn’t ideal, but for a dev or build system, this can be a good way to play with various features before they become official. A good example of this is the Multi Stage build that I’ll discuss in a bit. It will officially become available as part of version 17.05, but Edge users have already started experimenting with it.
Community Edition, in comparison, is released on a quarterly basis and supported for 4 months, which gives you about one month to upgrade to the new version. Enterprise Edition is also released quarterly, but the version is supported for a full year. You also receive extra support and some additional useful tools (signing your images, scanning them against all known vulnerability, etc) with your subscription.
Let’s move on from versioning to talk about what’s known as Multi Stage build, which will be released as part of version 17.05. This is something I wish had been a released couple of months ago, back when we were struggling with the size of our images and ended up having to use a workaround in Ansible to make them lighter, which didn’t feel like a satisfying solution. During the “What’s Next” conference at DockerCon, an official solution to this problem was presented on stage, so I was happy to know that we weren’t the only ones struggling with this.
Part of the appeal of Multi Stage build is that it redefines the way you build your Docker image. In a standard DockerFile, everything is sequential, starting with a “From” statement, then followed by a series of commands. If you have 30 steps in total and decide to change step #4, then your next rebuild will recreate everything from step #4 all the way to the end. Moreover, everything is kept, so if you install development tools to compile your application within a DockerFile, then the resulting image will be huge, which explains the need to use Ansible, bash scripts or multiple DockerFiles to build separately and then produce a clean production image. With the Multi Stage build, you can now have everything in the same Dockerfile using multiple “From” statements, which allows you to split large tasks into logical units and produce a clean final image. Since you can have multiple logical build units, modifying one will not necessary force you to rebuild all the other units.
If we look at this Go sample app, we can see that the final image was shrunk from 258 MB to only 6 MB. This is very impressive considering that the final output is exactly the same.
Service commands have also been upgraded. We now have access to:
Synchronous commands: When you create a service, it fires and forgets. You don’t have all the steps, so you get an ID back right away and that’s it. This works for most cases, but if you want to have an automated script reacting on output, you need to use some scripting to get the actual state. The Docker Team added the Synchronous Service command. When it runs, all steps are described when they happen and the service exits when it’s completed, which gives you a more effective method to automate rollback or sequence multiple actions. Visually, you can see the progress bar the same way you would for any regular application being deployed.
Automatic rollback: Before, with Docker, you could only pause or continue when something went wrong during a service update. Now, you can add a rollback action, which can simplify a lot of CICD pipelines. Actions can be determined by one failure or a specific percentage of failures. In some cases, it could be okay to proceed with an update even if 10% of the service fails to update.
Service logs: Since services can be represented by a large number of replicas, it can tedious to go through the entire log. Of course, you can use centralized log systems like the ELK (Elastic, Logtstash, Kibana) stack, but without them, the log can be a nightmare. Luckily, the Docker Team has added service logs that fetch the logs of all containers for a particular service. You can now retrieve a specific amount of lines and even follow any new output as a stream. However, this works only if you’ve picked JSON or Journald as a logging driver.
Topology-aware placement: When building a huge swarm, it’s normal to control where we place containers, as some nodes are OS specific or have special network interfaces mapped to them. We can use placement constraints, which forces a container to be placed on a node with a specific label. If no such node is available, it will fail. With topology-aware placement, we can add placement preferences so that we can ask our managers to deploy services on a set of nodes. If none are available, we can deploy on others. For example, let’s say you place your nodes in different availability zones, like 2 in Montreal and 2 in Toronto. With regular spread, if you ask for 2 replicas, there is a good chance that you’ll end up with one container on each Montreal node. If your Montreal center goes down, your system would become unavailable for precious seconds or minutes. With topology-aware placement, you can ask Docker to spread the defined sites across so that you end up with one container in Montreal and one in Toronto, making your system more resistant to a potential failure of one of your sites.
Docker Compose (stack): Docker has finally enhanced Docker Compose, called Stack Now, to allow you to mix services and containers in the same stack. We can deploy in one command containers running our database, messaging layers, network configurations as well as services. The Docker Team also simplified port mapping with clearer messages like Targeted, Published and so on. Both features will make using Docker a smoother and better experience overall.