Skip to main content
< All Topics

Kubernetes Multi-Container Patterns

Multi-Container Patterns

Imagine a specialized surgery. You have the Lead Surgeon (Main Container) doing the actual operation. But they cannot do everything alone. They need an Anesthesiologist (Sidecar) to monitor the patient’s vitals continuously, and a Nurse (Ambassador) to fetch tools from the outside storage room so the surgeon doesn’t have to leave the table.

In Kubernetes, a Pod is that operation theatre. It usually holds one main container, but sometimes we add “helper” containers to assist the main one. They live together, share the same network IP (talk via localhost), and can see the same storage volumes.

  1. Sidecar: The “Assistant.” It extends functionality (like logging) without changing the main app.
  2. Adapter: The “Translator.” It converts output from your app into a format the monitoring tool understands.
  3. Ambassador: The “Proxy.” It handles connections to the outside world, so your app handles simple localhost requests.
  • Tightly Coupled: These containers live and die together. If the Pod dies, all containers inside it die.
  • Shared Context: They share the same Network Namespace (IP address) and IPC (Inter-Process Communication).
  • Shared Storage: They can mount the same Volume to read/write shared files.
PatternRoleBest AnalogyPrimary Use Case
SidecarEnhancerA sidecar attached to a motorbike.Log forwarding, config syncing, file watching.
AdapterStandardizerA universal travel power adapter.Normalizing metrics, formatting output.
AmbassadorGatewayA receptionist handling calls.Database proxy, service discovery, authentication.

While 90% of the time you run a “Single-Container Pod,” the “Multi-Container Pod” is a powerful feature for separation of concerns.

Instead of jamming all logic (logging, monitoring, proxying) into one giant, messy application code, we split them.

The Sidecar Pattern (The Assistant)

“Main Container” serves the users, and the “Sidecar Container” handles boring tasks like collecting logs, updating configuration files, or handling security (HTTPS).

FeatureDescriptionReal-World Example
Primary GoalOffload non-business tasks.Moving log shipping logic out of Java code.
CouplingTightly coupled in deployment, loosely coupled in code.Deployed together in one YAML, but code is separate.
NetworkingShares localhost.Sidecar can talk to Main App on localhost:8080.
LifecycleLifecycle is tied to the Pod.If the Pod is killed, the Sidecar is killed too.


The Adapter Pattern (The Translator)

In Kubernetes, the “Adapter Pattern” standardizes the output of your application. If your app speaks “Language A” but your monitoring tool expects “Language B,” the Adapter sits in the middle and translates A to B.

  • The Translator: It changes the appearance or format of the main container’s output.
  • Standardizer: It ensures all Pods in your cluster look the same to the outside world, even if the apps inside are different.
  • Hides Complexity: The outside world doesn’t need to know the messy details of the main app.
  • Interface Transformation: The primary goal is to match an external interface requirement (like Prometheus metrics).
  • Shared Network: Uses localhost to communicate with the main container.
  • Shared Volumes: Often reads files (logs or status files) written by the main container to transform them.
FeatureDescriptionReal-World Example
Primary GoalStandardization & Translation.Converting “Error: 500” text to a JSON Metric { "status": 500 }.
CouplingTightly coupled.Works directly with the specific output of the main app.
NetworkingMasks the Main App.The monitoring system talks to the Adapter, not the Main App.
LifecycleSymbiotic.If the main app stops producing data, the adapter has nothing to translate.

The Ambassador Pattern (The Proxy)

In Kubernetes, your Main App wants to talk to a complex database cluster. Instead of coding complex logic (like “which shard is active?” or “how to handle retries?”) into your app, your app simply talks to localhost. The Ambassador container listens on localhost, takes the request, and proxies it to the correct destination in the outside world.

It acts as a gateway for outbound traffic.

  • The Proxy: It sits between your app and the outside world.
  • The Smart Router: It knows where to send your traffic (Sharding, Failover).
  • The Bodyguard: It handles security (mTLS, Authentication) so your app doesn’t have to.
  • Outbound Gateway: Unlike the Adapter (which focuses on output/monitoring), the Ambassador focuses on connections your app makes to other services.
  • Localhost Abstraction: Your app thinks it is talking to a local service (localhost:3306), but it’s actually talking to a remote cluster (db-prod-01.aws...).
  • Language Agnostic: Use an Ambassador written in Go (like Envoy) to handle networking for a Main App written in Java or Python.
  • Common Use Case: Database proxies or Service Mesh proxies (like Envoy or Istio). The app talks to localhost, and the Ambassador handles the complex logic of routing to the correct database shard or handling circuit breaking.
FeatureDescriptionReal-World Example
Primary GoalProxy & Abstract Connections.App talks to localhost, Proxy sends to CloudDB.
CouplingLoosely coupled.App just needs a TCP connection; doesn’t care who handles it.
NetworkingHandles “Outbound” traffic.Managing connection pools to a Redis cluster.
LifecycleSymbiotic.If the Ambassador dies, the Main App loses internet/DB access.

Benefits
  • Reusability: Write the helper container once, use it with many different main applications.
  • Isolation: If the logging agent crashes, your main web server keeps running (usually).
  • Team Independence: The “Ops” team manages the logging container image; the “Dev” team manages the app image.

Contents
Scroll to Top