The pattern behind the confusion
These words tend to appear next to each other on architecture diagrams, so it is easy to treat them as synonyms. But each one makes a different decision: restart a process, accept traffic, validate a change, release an artifact, isolate a workload, add capacity or survive a failure. Mixing those decisions is how a seemingly sensible setup creates a production incident.
1. Liveness is not readiness
A Kubernetes liveness probe answers whether the container should be restarted. A readiness probe answers whether the pod should receive traffic. Both can test an endpoint, but their failure actions are different. Startup probes can give slow applications time to initialize before liveness and readiness take over.
Imagine a payment API whose database is unavailable for 20 seconds. If its readiness check fails, Kubernetes removes its endpoint from matching Services; the process stays alive and can become ready again when the database recovers. If that dependency is also required by liveness, every replica may restart at once, losing warm state and putting even more pressure on recovery. A liveness check should detect a process state that a restart is likely to fix, not every downstream outage.
livenessProbe:
httpGet: { path: /health/live, port: 8080 }
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet: { path: /health/ready, port: 8080 }
periodSeconds: 5
failureThreshold: 22. CI is not CD—and CD has two meanings
Continuous integration (CI) means integrating small changes frequently and validating them with automated checks: build, tests, static analysis and sometimes security scans. Continuous delivery keeps a release candidate ready to deploy through a reliable pipeline, but production deployment may still require an explicit decision. Continuous deployment goes further: every change that clears the required gates is deployed automatically. “CD” is ambiguous unless the team says which meaning it intends.
A green CI run is evidence about the checked commit, not proof that a rollout will succeed. A safe release process promotes the same tested artifact, then observes production error rate, latency and business signals. Rebuilding the source independently for each environment weakens that chain of custody.
When each model fits
- Continuous delivery: useful when a release needs a coordinated window or explicit approval. The artifact and checks are still automated.
- Continuous deployment: useful when strong automated checks, progressive rollout and rollback signals make frequent low-risk releases practical.
- Neither means “push every commit directly to all users”: branch policy, environment gates, canaries and observability still matter.
For the complete path from commit to users, see How Code Flows: From Local Development to Production.
3. A container is not a small virtual machine
A virtual machine runs a guest operating system and its own kernel on virtualized hardware. A Linux container is a group of host processes isolated using kernel mechanisms such as namespaces, with resources governed by cgroups. An image supplies a filesystem and configuration, while the processes share the host kernel. That is why containers can often start quickly and use fewer resources, but they do not offer the same isolation boundary as separate guest kernels.
Containers are still useful isolation, just not a promise that untrusted code is safely separated from the host. Privileged containers, broad host mounts, excessive Linux capabilities or a kernel vulnerability can break assumptions. Use least privilege, rootless or non-root processes where practical, resource limits and stronger sandboxing or VMs when the threat model calls for them.
4. More replicas do not guarantee high availability
Scaling asks whether a system can serve more load. High availability asks whether it can keep serving through a failure. Ten copies of an API on one node may have more capacity than one copy, but the node remains a single point of failure. Even spreading replicas across nodes is insufficient if every node is in the same failing zone, depends on one database, or shares one misconfigured ingress.
A more resilient setup places replicas across nodes and, when needed, availability zones; uses health-aware routing; keeps sufficient spare capacity to survive losing a node or zone; and makes dependencies redundant where required. In Kubernetes, topology spread constraints and pod anti-affinity can influence placement, while a PodDisruptionBudget limits voluntary disruption. Neither replaces dependency design or guarantees survival of every failure.
| Question | Scaling | High availability |
|---|---|---|
| What are we protecting against? | More requests or work | Failure of a component or location |
| Typical mechanism | More replicas, caching, queues | Redundancy across failure domains |
| Can it fail despite 10 pods? | Yes, if a shared bottleneck saturates | Yes, if all pods share one dependency |
The free system quality guide connects these choices to latency, throughput and availability.
5. Docker is not Kubernetes
Docker tooling can build images, package applications and run containers. Kubernetes orchestrates workloads across a cluster: it schedules pods, maintains desired replica counts, connects ready endpoints to Services and rolls out new versions. The distinction is packaging and local/container runtime tooling versus cluster-level orchestration. You can use Docker-built OCI images in Kubernetes, but Kubernetes does not require Docker Engine on its nodes: modern clusters use runtimes exposed through the Container Runtime Interface, such as containerd or CRI-O.
If you already run a single service reliably on a simpler platform, Kubernetes is not automatically an upgrade. Its controllers, networking, access control, upgrades and observability bring operating cost. Use it when cluster scheduling, declarative reconciliation, service discovery and rollout controls solve actual problems you have.
Putting the distinctions together
A commit passes CI; a delivery process produces and promotes a versioned image; a deployment process releases it; Kubernetes schedules containers and only sends traffic to ready pods; liveness can restart a stuck container; spreading replicas across failure domains keeps a component failure from becoming an outage. Each mechanism has one job and a different failure mode.
| Concept | Decision it makes | Commonly confused with |
|---|---|---|
| Liveness | Should this container be restarted? | Readiness: should it receive traffic? |
| CI | Did the integrated change pass validation? | CD: how does it reach users? |
| Container | How is this process packaged and isolated? | VM: is there a separate guest kernel? |
| Scaling | Can we handle more demand? | HA: can we survive a failure? |
| Docker tooling | How do we build/run container images? | Kubernetes: how do we operate workloads across nodes? |
Continue with Behind the Scenes: Tech Edition for more under-the-hood mechanisms, or explore the system design learning path to practice choosing them in context.