Core Concepts and Fundamentals
The moment I realized I needed container orchestration was when I was manually restarting failed containers at 2 AM for the third time that week. What started as a simple two-container application had grown into a complex system with dozens of interdependent services, and manual management was no longer sustainable.
Container orchestration isn’t just about automation - it’s about building systems that can heal themselves, scale automatically, and maintain service availability even when individual components fail.
Container Orchestration Essentials
Orchestration solves the problems that emerge when you move from running a few containers to managing a production system. The core challenges it addresses:
- Service Discovery: How do containers find and communicate with each other?
- Load Distribution: How do you distribute traffic across multiple instances?
- Health Management: How do you detect and replace failed containers?
- Resource Allocation: How do you ensure containers get the resources they need?
Here’s how I approach these in Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: web-app:v1.2.0
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
This handles replica management, rolling updates, resource allocation, and health checking automatically.
Service Discovery and Communication
In production, containers need to find and communicate with each other reliably. I use Kubernetes Services to provide stable network identities:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 8080
type: ClusterIP
Applications can now connect to web-app-service
and the service will automatically load balance across healthy pods.
Scaling Strategies
Automatic scaling is essential for production workloads. I implement both horizontal and vertical scaling:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Storage Management
Production applications need reliable, persistent storage. I design storage strategies based on data characteristics:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: database-storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15-alpine
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-credentials
key: password
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-storage
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast-ssd
resources:
requests:
storage: 100Gi
Configuration Management
Production configuration management requires security and flexibility:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.host: postgres-service
database.port: "5432"
log.level: "warn"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database.password: <base64-encoded-password>
jwt.secret: <base64-encoded-secret>
Network Security
Production networks need comprehensive security policies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: production-policy
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
Rolling Updates
I implement deployment strategies that minimize downtime and risk:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
template:
spec:
containers:
- name: api-server
image: api-server:v1.0.0
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
The rolling update strategy ensures zero-downtime deployments by gradually replacing old pods with new ones, only proceeding when health checks pass.
These core concepts form the foundation of reliable production Docker deployments. They address the complexity that emerges when moving from simple container usage to production-grade systems that serve real users.
Next, we’ll explore practical applications of these concepts with real-world examples and complete deployment scenarios for different types of applications.