AU294 · Red Hat Enterprise Linux Automation with Ansible

Multi-Container Applications

Chapter 7 of 8

Objective: Understand the design considerations for applications composed of multiple containers, and deploy a multi-container application on OpenShift.

Overview

Most real applications are not a single container — a typical web application needs a front end, a back end, and a database, each with different scaling, update, and resource needs. This chapter covers how to think about splitting an application into containers and wiring them together.

Key Concepts

Why split into multiple containers

Separating an application into multiple single-purpose containers (rather than one container running everything) lets each piece be scaled, updated, and restarted independently — a front end can scale to handle traffic spikes without also scaling the database, and a bug fix to the front end doesn't require rebuilding the database image.

Design considerations

Splitting an application well raises several questions: which components need to talk to each other and how (Service DNS names, not hardcoded IPs); which components need persistent storage versus which are stateless and freely replaceable; and which configuration differs between environments and should be externalized into ConfigMaps/Secrets rather than baked into images.

Service discovery between containers

Within a cluster, one component reaches another through its Kubernetes Service name, which resolves via internal DNS (<service>.<namespace>.svc.cluster.local) — components never need to know a pod's actual (and constantly changing) IP address.

Local multi-container development with pods

Podman itself supports a Kubernetes-style pod grouping for local development and testing, letting several containers share a network namespace before the same definitions are deployed to a real cluster.

$ podman pod create --name myapp -p 8080:8080
$ podman run -d --pod myapp --name front quay.io/example/frontend
$ podman run -d --pod myapp --name back quay.io/example/backend

Deploying a multi-container application on OpenShift

On OpenShift, each component of a multi-container application is typically its own Deployment and Service (for example a frontend Deployment/Service and a database Deployment/Service), tied together by the frontend's configuration pointing at the database Service's DNS name, with a single Route exposing only the component that needs external access.

Working with It

One Main Process per Container, Not per Application

Splitting an application into multiple containers doesn't mean cramming unrelated processes into one container — each container should still have a single clear responsibility.

Use Service Names, Never Pod IPs

Pod IPs change every time a pod is rescheduled; always configure inter-component communication using the stable Service DNS name.

Only Expose What Needs External Access

Create a Route only for the component the outside world actually needs to reach (typically the front end) — internal components like a database should remain reachable only inside the cluster.

Wiring a front end to a database Service by name

# In the frontend Deployment's env, reference the database Service by name
env:
  - name: DB_HOST
    value: "inventory-db"   # resolves via cluster DNS to the database Service
  - name: DB_PORT
    value: "5432"

Watch Out For

Common Pitfall

Create a Route only for the component the outside world actually needs to reach (typically the front end) — internal components like a database should remain reachable only inside the cluster.

Key Terms

Multi-container application
An application composed of multiple independently deployable containers/components.
Service discovery
The mechanism (cluster DNS resolving a Service name) components use to find each other.
Podman pod
A Podman construct grouping several containers under one shared network namespace, mirroring a Kubernetes pod.
ConfigMap
A cluster resource for externalizing non-sensitive configuration from an image.
Secret
A cluster resource for externalizing sensitive configuration (credentials, keys) from an image.

Review Questions

  1. Give two concrete benefits of splitting a front end and a database into separate containers rather than combining them.
  2. How does a frontend container find a backend/database component running elsewhere in the cluster?
  3. What is a Podman pod, and how does it relate to a Kubernetes pod?
  4. Why should a database component typically not have its own Route?
  5. Where should environment-specific configuration values live instead of being baked into a container image?