When we started experimenting with Docker and Kubernetes, we were just looking for a more efficient way to stand up our applications. Traditionally, it’s an infrastructure or operations team’s responsibility to make sure every dependency an application needs to run is set up the server, and that none of them are in conflict — and then continue to ensure that throughout the life of the system. It’s also their responsibility to figure out which server the application need to go on in the first place.
This was just how infrastructure worked. It was time-consuming, a little bit tedious and prone to error. Every time you moved your environment, you had to build it fresh.
Everyone wanted this part of the job to basically go away so we could focus on doing the parts of our work that are challenging, interesting, and let us use our whole brains. A few of us at Table XI started playing around with containerization by ourselves, using it inside projects to see if we could save ourselves some time.
As we tested out options, two tools seemed the most promising: Docker as an image/container manipulation tool, and Kubernetes as an orchestration platform for running those containers efficiently across infrastructure. Together, the two proved so powerful that we started rolling them out to clients.
Now, our goal is to use the Kubernetes/Docker combination on all of our projects within the year. We’ll explain what Docker and Kubernetes are, why we like the two together so much, and how we plan to adopt it everywhere.
How Docker and Kubernetes work together
To understand the difference between Docker and Kubernetes and how the two work together, it helps to first understand how things work now. Typically, when we set an application up to run on a server, any external dependencies that software has to be loaded onto the same server individually. This could be system libraries, utilities, really anything the application needs to reference to do its job. This isn’t so bad in itself — whoever’s running the server can just add the dependencies. But it does get tricky really quickly. For instance, if multiple applications are on the same server. One may require a different, conflicting version of the same dependency, for example. And you end up with a soup of dependencies floating around the server, any one of which could have an unpatched security bug.
It’s just … messy. Docker lets us take all that mess and pack it up into a single container. All a developer needs to do is run a single command to build an “image” from a “Dockerfile” and all of the necessary dependencies will be ready and available. What works on your machine will also work in production. The container creates a boundary, blocking out a lot of the reasons why things break down. You can move them around, update them, swap them out — once it’s in a container, you can handle it however you want without worrying about adverse interactions.
Then there’s getting it onto a server. In the past, we had to treat our servers like pets, not cattle. Each machine was a special snowflake that we’d have to tend to meticulously. Instead of making them work for us, we’d often ended up working for them. This is where Kubernetes comes in. Kubernetes is an open source container orchestration platform. We write code that tells Kubernetes what kind of environments we want the applications to live in, and it automatically arranges the necessary containers across our servers to make the most efficient use of space and compute power. Basically, Docker is the brick maker and Kubernetes is the mason, elegantly lining them up.