Containers & Orchestration

Containers package an application and all its dependencies into a single, portable unit that runs consistently across any environment. Container orchestrators then manage scheduling, scaling, networking, and health of those containers at scale. Together, they are the de-facto deployment model for modern distributed systems.

Docker

Docker is the standard toolchain for building and running containers. A container is a lightweight, isolated process that shares the host OS kernel but has its own filesystem, network, and process space. Unlike a virtual machine, there is no guest OS — containers start in milliseconds and have negligible overhead.

Images and containers

  1. Image — a read-only, layered snapshot of the filesystem: OS base, runtime, dependencies, and application code. Built from a Dockerfile; stored in a registry (Docker Hub, Amazon ECR, GitHub Container Registry).
  2. Container — a running instance of an image. You can run many containers from the same image simultaneously. Containers are ephemeral — stopping one discards any state written inside it. Persistent data must be mounted via volumes.

Dockerfile

A Dockerfile is a recipe that defines how to build an image. Each instruction creates a new layer; layers are cached and reused, so only changed layers are rebuilt. Keep layers small and order instructions from least to most frequently changed to maximise cache hits.

Key concepts

  1. Registry — a repository for images. docker push uploads an image; docker pull downloads it. CI/CD pipelines build and push on every merge.
  2. Volumes — mounts that persist data outside the container lifecycle. Used for databases, file uploads, or any state that must survive a container restart.
  3. Networking — containers on the same host communicate over a virtual bridge network. Docker assigns each container a private IP; services discover each other by name in Docker Compose.
  4. Docker Compose — a tool for defining and running multi-container applications locally. A single docker-compose.yml specifies all services, their images, environment variables, volumes, and network links. Essential for local development; not used in production (replaced by an orchestrator).

Kubernetes

Kubernetes (K8s) is an open-source container orchestrator originally built by Google. It automates deployment, scaling, self-healing, and rolling updates of containerised workloads across a cluster of machines.

Architecture

  1. Control plane — the brain of the cluster. Runs the API server (all communication goes through it), the scheduler (assigns pods to nodes), the controller manager (reconciles desired vs actual state), and etcd (the distributed key-value store that holds all cluster state).
  2. Worker nodes — machines that run your workloads. Each node runs a kubelet (agent that communicates with the control plane), a container runtime (containerd, Docker), and kube-proxy (manages network rules).

Core objects

  1. Pod — the smallest deployable unit. A pod wraps one or more containers that share a network namespace and storage volumes. Pods are ephemeral; they are created and destroyed, never updated in place.
  2. Deployment — declares the desired state for a set of identical pods (replica count, image version). The deployment controller continuously reconciles actual state to match. Rolling updates and rollbacks are built in.
  3. Service — a stable network endpoint (DNS name + virtual IP) that load-balances traffic across the pods matching a label selector. Pods come and go; the Service IP never changes.
  4. Ingress — an HTTP/HTTPS routing layer that sits in front of Services. Routes external traffic to the right Service based on hostname or URL path; handles TLS termination.
  5. ConfigMap / Secret — externalise configuration and credentials from the container image. Injected as environment variables or mounted as files at runtime.
  6. Horizontal Pod Autoscaler (HPA) — automatically scales the replica count of a Deployment based on CPU, memory, or custom metrics.

Self-healing

Kubernetes continuously compares desired state (defined in manifests) to actual state (what is running). If a pod crashes, the controller restarts it. If a node dies, pods are rescheduled on healthy nodes. This reconciliation loop is the core of how Kubernetes achieves reliability without manual intervention.

Managed Kubernetes

Running the control plane yourself is operationally expensive. Every major cloud provider offers a managed Kubernetes service where the control plane is their responsibility:

  1. Amazon EKS — Elastic Kubernetes Service
  2. Google GKE — Google Kubernetes Engine (the most mature; Kubernetes originated here)
  3. Azure AKS — Azure Kubernetes Service

Amazon ECS

Amazon Elastic Container Service (ECS) is AWS's proprietary container orchestrator. It is simpler than Kubernetes — fewer abstractions, less configuration — and integrates tightly with the AWS ecosystem (IAM, ALB, CloudWatch, ECR). The trade-off is that it is AWS-only; there is no portable open standard underneath.

Core concepts

  1. Task definition — a blueprint for a container (or group of containers): which image to use, CPU/memory allocation, environment variables, IAM role, port mappings. Equivalent to a Kubernetes Pod spec.
  2. Task — a running instance of a task definition. Equivalent to a Kubernetes Pod.
  3. Service — maintains a desired count of running tasks, integrates with an Application Load Balancer for traffic distribution, and replaces failed tasks automatically. Equivalent to a Kubernetes Deployment + Service.
  4. Cluster — a logical grouping of tasks and services.

EC2 launch type vs Fargate

EC2 launch typeFargate
InfrastructureYou manage EC2 instances in the clusterAWS manages the underlying infrastructure
BillingPay for EC2 instances regardless of utilisationPay per task CPU/memory per second
ControlFull control over instance type, AMI, storageNo access to underlying host
Best forPredictable, sustained workloads; GPU tasksVariable workloads; teams that want no server management

ECS vs Kubernetes

Amazon ECSKubernetes
Learning curveLow — fewer concepts, AWS console drivenHigh — many abstractions, YAML-heavy
PortabilityAWS onlyAny cloud or on-premise
EcosystemDeep AWS integration (IAM, ALB, CloudWatch)Large open-source ecosystem (Helm, Istio, Argo)
FlexibilityOpinionated — simpler but less customisableHighly extensible via CRDs and operators
Best forAWS-native teams wanting simplicityMulti-cloud, large teams, complex workloads