Why Pods? 5 Solid Use Cases
You’ve immersed yourself in the containerization world for a while. Kubernetes is the next frontier, but the concept of a pod is a little foreign. When you first learn about pods it’s hard to think of a use case where a pod is a more natural fit than a container. Plus, the tutorials and documentation cover what a pod is rather than why you should use one. It’s easy to think up “trivial” use cases, but how are people actually using pods in the real world?
Well, wonder no longer. We’re cover five real world use cases for pods. These should provide some insight into when and why we should use pods.
Let’s start with
Kubernetes’ DNS integration.
The pod in this addon integrates three components: skyDNS, a local copy of etcd,
and kube2sky. Instead of writing a custom DNS server, the Kubernetes team uses
existing components. So why not a single container here? Using a pod means that
the pieces can be independently verified and upgraded.
The source for kube2sky
shows the advantages here.
kube2sky ships as a small utility that does one
thing well, and it’s the only custom code in the pod. Using pods here makes it
easier to use existing containers in new and interesting ways.
According to Google’s Brian Grant:
Virtually all production services at Google use our internal legacy equivalent of pods. The most common multi-container use cases include pushing log data (not unlike fluentd or logstash) and content / config management / data loading.
Let’s talk about “pushing log data”. This means one container collecting and
shipping log data from another. To build on this, imagine we were using
logstash and wanted to change to
fluentd. Shipping these in a single
container binds our application code to our log shipper. Not ideal. But if we
schedule these in a pod we can change our log shipper at will. We could even add
a new log shipper as a trial without touching the application container.
Separation of concerns isn’t just for code; it can grant operational simplicity
Continuing on in Brian Grant’s example, we have data loading. Let’s use the concrete example of a static site generator. We’ll have three processes involved here. First, we’ll need a data loader to get the raw source for the site. Next, the static site generator will generate content when the data changes. Finally, a web server serves the new files. But how can we structure this?
We could use a single container for this whole system, but let’s examine our options. If we do that, changing the generator requires changing the whole image. Likewise for changing how we load content, or the web server. We’d also have to figure out how to supervise all the processes in the container. Using a pod solves these problems and opens up options. If we need to swap components or use sub-components in different projects, we can. Composability is an important benefit here.
Easier Reasoning about Processes
When you schedule many processes in a single container, how do you manage them
all? The single-container answer is to add in a process manager like
systemd. This makes the individual containers heavier, not to
mention coupling the components. By using a pod, we can let the infrastructure
take care of that work. We can also add more processes later without rebuilding
the entire image. Reducing the number of supervision systems lets us trust our
architecture instead of hacking around it.
The last use case is from Brendan Burns’ post The Distributed System Toolkit: Patterns for Composite Containers. In it, he introduces three concepts: the sidecar, the ambassador, and the adapter. We’ve covered the sidecar (log shipping and data loading) and ambassador (DNS), so let’s look at the adapter pattern.
The purpose of an ambassador pod is to “standardize and normalize output”. The article uses the example of monitoring. A monitoring system expects a standard format, but each application exports data differently. An adapter can sit between the application and the monitoring system to normalize the data. Decoupling comes up again here: If we change our monitoring system, it’s simpler to change the adapter than the application. We can build an inbound adapter as well, for example on the receiving side of monitoring as a proxy. This lets us use more off-the-shelf components for more flexible deployments.
So, Why Use Pods?
These use cases show that pods let us decouple dependencies and make infrastructure easier to use and more efficient. Another benefit: by using pods, we also get operational transparency. Our infrastructure has more visibility into what the applications it’s running are doing. This means that the operations team has a better idea of what’s going on in the applications. Developers benefit too: decoupling runtime dependencies means that local development and staging get easier. A good rule of thumb here is to ask yourself what would happen in the container if you needed to change your infrastructure. If the answer makes you sweat, use a pod instead.