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
Splitting an application into multiple containers doesn't mean cramming unrelated processes into one container — each container should still have a single clear responsibility.
Pod IPs change every time a pod is rescheduled; always configure inter-component communication using the stable Service DNS name.
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
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
- Give two concrete benefits of splitting a front end and a database into separate containers rather than combining them.
- How does a frontend container find a backend/database component running elsewhere in the cluster?
- What is a Podman pod, and how does it relate to a Kubernetes pod?
- Why should a database component typically not have its own Route?
- Where should environment-specific configuration values live instead of being baked into a container image?