Kubernetes workloads are built from a small set of composable building blocks. The foundational unit is the Pod, which represents a single instance of a running process and may contain one or more containers that share a network namespace, storage volumes, and a common lifecycle. Multiple containers in a Pod are useful for tightly coupled processes that need to share resources: the sidecar pattern places a helper such as a logging agent alongside the main container, the ambassador pattern proxies network traffic on its behalf, and the adapter pattern transforms output for downstream consumers. Init containers run before the main application containers, executing to completion in order and typically handling setup tasks like pre-populating volumes, waiting for dependencies, or running migrations.
For long-running services, a Deployment manages a set of identical Pods through a ReplicaSet, supporting declarative updates, rolling updates governed by maxSurge and maxUnavailable parameters, easy scaling, and rollback to previous revisions via kubectl rollout undo. Deployments are the recommended way to manage replicated stateless workloads because the underlying ReplicaSet is hidden behind them. When stable network identity, ordered deployment, and persistent storage matter, as with databases like MySQL or distributed systems like Kafka and ZooKeeper, StatefulSets assign each Pod a persistent hostname such as web-0 and web-1 and bind each one to its own PersistentVolumeClaim. DaemonSets take a different approach, ensuring one copy of a Pod runs on every node (or a chosen subset) for cluster-wide agents like Fluentd, Prometheus node-exporter, or CNI plugins. For finite work, Jobs run Pods to successful completion with parameters like completions, parallelism, and backoffLimit, while CronJobs schedule Jobs on cron expressions and add concurrencyPolicy and history retention settings to control overlap and cleanup.