The Ops Community ⚙️

Cover image for 4 container design patterns for Kubernetes
Daniele Polencic
Daniele Polencic

Posted on

4 container design patterns for Kubernetes

Running new apps in Kubernetes is straightforward.

But what happens when you have legacy apps that:

  • Log to file instead of stdout?
  • Has no support for Prometheus?
  • Has no support for HTTPS?

First, let's cover the basics.

In Kubernetes, a pod is a collection of containers.

Containers are isolated using two Linux primitives: control groups and namespaces.

  1. Control groups are for limiting resources (max 256MB of memory).
  2. Namespaces are for isolation (you can only see this folder).

Control groups and Linux namespaces are the fundamental primitives of containers

All the containers in a Pod are isolated except for the network.

The network is shared, and a single IP address is assigned to all containers in a Pod (Pod's IP address).

Containers in the same pod share the same network namespace

Why would you need to run more than a container in a Pod?

If you can't (or don't want to) change the code in your app, you might need to adjust its functionality in other ways.

Let's have a look at an example.

Recent versions of Elasticsearch support TLS, but it was a paid extra feature for a long time.

How did you secure traffic with TLS?

You could add a proxy to your pod as a container.

The (encrypted) traffic reaches the proxy first, then (unencrypted) Elasticsearch.

The traffic is proxied by the NGINX container before reaching ElasticSearch

Another example is exposing your apps to the public internet without an Ingress.

Cloudflare tunnel runs an agent alongside the app and proxies all the traffic.

The tunneld agent tunnels the traffic to the Cloudflare network

What happens when you want to use Prometheus, but your app has a custom format for exposing metrics?

There's no need to change the code if you use an adapter.

Example: Elasticsearch doesn't expose Prometheus metrics.

Adapter to the rescue!

The container adapts the Elastic Search metrics to be compatible with Prometheus

When you have an extra container in the Pod to handle input, that's called the Ambassador pattern.

If it processes the output of the main container, it's an Adapter instead.

Adapter vs Ambassador pattern

The default for apps in Kubernetes is to print the logs to stdout.

What if you have an app that logs to file instead?

How do you collect the logs?

You can use a container that retrieves the content of the log file and prints it to stdout.

The sidecar container retrieves the content of the file and prints it to stdout

Other sidecars include containers that inject secrets, reload the app when there's a change to ConfigMaps, caching, etc.

Any container that enhances your app is generally called a sidecar container.

Example include:

Elasticsearch recommends setting the virtual memory to a higher value (i.e. mmap count) before the app starts.

How do you do that in Kubernetes?

You can use Init Containers, which are containers that run to completion before the "normal" containers start.

Init containers in Kubernetes

So if you're migrating existing apps into Kubernetes, you have four patterns at your disposal:

  • Ambassador
  • Adapter
  • Sidecar
  • Init

Those are from the original Google paper.

In this blog post, you can find more in-depth explanations about the multi-container patterns.

And finally, if you've enjoyed this thread, you might also like:

Top comments (2)

sweetdevil144 profile image
Abhinav Pandey

Hello Daniels. I saw your profile and your posts. I was starting to learn about kubernetes and docker and thought it would be opt to contact you. Can you suggest me a path for learning DevOps along with Kubernetes and Docker

danielepolencic profile image
Daniele Polencic