Article
Kubernetes Explained: Pods, Deployments, Services, and Production Basics
A practical Kubernetes guide covering core architecture, Pods, Deployments, Services, probes, ConfigMaps, Secrets, storage, Ingress, and common production mental models.
What Problem Kubernetes Solves
Containers solve the “it works on my machine” problem by packaging the application together with its dependencies. That still leaves another problem: how do we run many containers reliably in production?
If we run containers manually on one or more virtual machines, we quickly run into operational issues:
- We must start, stop, restart, and monitor containers ourselves.
- We must decide where each container should run.
- We must handle scaling when traffic increases.
- We must recover when a container or machine fails.
- We must roll out new versions without unnecessary downtime.
Kubernetes solves these problems by acting as a container orchestrator. Instead of managing individual containers manually, we describe the desired state and Kubernetes works to keep the cluster in that state.
Example:
- “I want 3 replicas of my API running.”
- “The app should receive traffic only when it is healthy.”
- “If one Pod dies, create another one.”
- “Expose the app internally or externally.”
That is the main Kubernetes idea:
- we declare what we want
- Kubernetes continuously tries to make reality match that desired state
Core Building Blocks
Cluster
A Cluster is the full Kubernetes environment. It is made of machines called Nodes.
Node
A Node is a machine, virtual or physical, with CPU, memory, disk, and network resources.
There are two major categories:
Control Planenodes: manage the clusterWorkernodes: run application workloads
Pod
A Pod is the smallest deployable unit in Kubernetes. A Pod usually contains one main container, but it can contain more than one container if those containers need to live and work together closely.
Important:
- Containers in the same Pod share the same network namespace.
- They can talk to each other over
localhost. - They can also share storage volumes.
Example:
- One Pod runs
my-api - Another Pod runs
postgres
Even if each Pod contains one container, Kubernetes still manages Pods, not raw containers.
High-Level Architecture
At a high level, Kubernetes is split into two sides:
- the control plane, which stores cluster state and makes decisions
- the worker nodes, which actually run application workloads
kubectl is the client tool we use from our machine. When we run a command such as:
kubectl apply -f deployment.yamlkubectl sends the request to the API Server. The API Server is the front door of the cluster. Almost every component talks through it instead of talking directly to each other.
The API Server stores the desired cluster state in etcd. For example:
- this Deployment should have 3 replicas
- this Service should route to Pods with a certain label
- this ConfigMap should contain these values
After the desired state is saved, the control plane components react to it.
The Scheduler looks for Pods that do not yet have a Node assigned. It chooses a suitable worker node based on available CPU, memory, constraints, and scheduling rules.
The Controller Manager runs controllers that keep checking whether the real cluster matches the desired state. If a Deployment says “run 3 Pods” but only 2 are running, a controller creates another Pod.
The worker nodes are where containers actually run. Each worker node has:
kubelet, which starts and monitors Pods on that nodekube-proxy, which helps Service networking reach the right Pods- the actual
Pods, which wrap one or more containers
So the normal flow is:
- You describe what you want.
- The API Server stores that desired state.
- The scheduler and controllers decide what needs to happen.
- Worker nodes run the Pods.
- Kubernetes keeps reconciling the real cluster back toward the desired state.
Control Plane Components
kubectl
kubectl is the command-line tool used to communicate with the cluster.
Examples:
kubectl get podskubectl get nodeskubectl apply -f deployment.yamlkubectl describe pod my-podkubectl logs my-podTo connect to a cluster, kubectl uses a kubeconfig file with cluster endpoint information, users, and credentials.
API Server
The API Server is the main entry point to the cluster. All cluster operations go through it.
Examples:
kubectl apply -f app.yamlsends a request to the API server- controllers watch the API server for changes
- the scheduler reads pending Pods from the API server
If you remember one thing, remember this:
- Kubernetes components mostly communicate through the API server
etcd
etcd is a distributed, strongly consistent key-value store. It stores the cluster state.
Examples of data stored there:
- which Nodes exist
- which Pods exist
- desired replica counts
- ConfigMaps and Secrets
- Service definitions
If the cluster state must be remembered, it is typically stored in etcd.
Scheduler
The Scheduler decides on which Node a newly created Pod should run.
It looks at factors such as:
- available CPU and memory
- Pod constraints
- taints and tolerations
- affinity and anti-affinity rules
Important:
- the scheduler chooses a Node
- it does not actually run the container itself
Controller Manager
The Controller Manager runs controllers that continuously compare desired state with actual state and fix differences.
Examples:
- Deployment controller: ensures the right number of Pods exist
- ReplicaSet controller: keeps the requested number of Pod replicas running
- Node controller: reacts when Nodes go down
- Job controller: tracks one-time task completion
This is one of the most important Kubernetes patterns:
- controller sees current state
- controller knows desired state
- controller acts until both match
Worker Node Components
kubelet
Each Node runs a kubelet. It is the agent on the Node that talks to the control plane.
Responsibilities:
- watches for Pod specs assigned to its Node
- makes sure containers are started and kept running
- reports Pod and Node status back to the cluster
The kubelet does not decide where the Pod should go. The scheduler decides that first.
Container Runtime
The container runtime actually runs the containers.
Examples:
containerdCRI-O
The kubelet asks the runtime to pull images and start containers.
kube-proxy
kube-proxy helps implement Service networking on each Node.
It makes sure traffic sent to a Service can be forwarded to the correct Pods.
Kubernetes Is Declarative
Kubernetes is usually managed through YAML manifest files.
A manifest describes the desired state of an object.
Example:
apiVersion: v1kind: Podmetadata: name: nginx-podspec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80Apply it with:
kubectl apply -f pod.yamlRead manifests as:
apiVersion: which API version this object useskind: what object we are creatingmetadata: name, labels, annotationsspec: desired state
Labels and Selectors
Labels are key-value metadata attached to objects. They are extremely important because many Kubernetes objects find other objects through labels.
Example labels:
metadata: labels: app: my-api env: prodA Selector matches objects with certain labels.
Example:
- a Service selects Pods with
app: my-api - a Deployment manages Pods with matching labels
Without labels and selectors, many Kubernetes objects would not know what to manage or route traffic to.
Pods
Pods are ephemeral. That means they are not meant to be treated like long-lived pets.
If a Pod dies, Kubernetes often replaces it with a new Pod rather than repairing the old one.
Important Pod facts:
- Pod IPs are not stable long-term
- Pods can be recreated
- Pods should be stateless unless persistent storage is used
Example Pod use case:
- a single
nginxcontainer for quick testing
In real applications, you usually do not create Pods directly. You create a higher-level object such as a Deployment.
ReplicaSet
A ReplicaSet ensures that a certain number of identical Pod replicas are running.
Example:
- desired replicas:
3 - if 1 Pod crashes, ReplicaSet creates another
Usually, we do not manage ReplicaSets directly. A Deployment manages them for us.
Deployments
A Deployment is the standard way to run stateless applications.
It provides:
- multiple replicas
- rolling updates
- rollbacks
- declarative scaling
When you create a Deployment:
- the Deployment creates a ReplicaSet
- the ReplicaSet creates Pods
- Kubernetes keeps that replica count running
Example Deployment:
apiVersion: apps/v1kind: Deploymentmetadata: name: my-apispec: replicas: 3 selector: matchLabels: app: my-api template: metadata: labels: app: my-api spec: containers: - name: api image: my-api:1.0.0 ports: - containerPort: 8080Scale it:
kubectl scale deployment my-api --replicas=5Rolling update example:
kubectl set image deployment/my-api api=my-api:1.1.0Rollback example:
kubectl rollout undo deployment/my-apiServices
Pods are short-lived and their IPs can change. A Service gives a stable way to reach a set of Pods.
A Service usually selects Pods by label.
Example:
- Pods labeled
app: my-api - Service forwards traffic to those Pods
ClusterIP
Default service type. Exposes the app inside the cluster only.
Common use case:
- frontend Pod talks to backend Pod through an internal Service
NodePort
Exposes the Service on a port on each Node.
Common use case:
- basic testing from outside the cluster
LoadBalancer
Used mainly in cloud environments. Provisions an external load balancer that sends traffic to the Service.
Common use case:
- expose a public web app
Example Service:
apiVersion: v1kind: Servicemetadata: name: my-api-servicespec: selector: app: my-api ports: - port: 80 targetPort: 8080 type: ClusterIPThis means:
- clients call the Service on port
80 - traffic is forwarded to matching Pods on port
8080
Probes
Probes are health checks for containers.
The two most important ones are:
livenessProbereadinessProbe
There is also a third one:
startupProbe
livenessProbe
Checks whether the container is still alive.
If it fails repeatedly, Kubernetes restarts the container.
Use it when:
- the app is stuck or deadlocked
- the process is running but no longer functioning correctly
readinessProbe
Checks whether the container is ready to receive traffic.
If it fails:
- the container is not killed
- the Pod is removed from Service endpoints temporarily
Use it when:
- the app needs time to load data
- the app depends on a database connection
startupProbe
Useful for slow-starting applications.
It gives the application more time to start before liveness checks begin.
Example:
containers: - name: api image: my-api:1.0.0 ports: - containerPort: 8080 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 15 periodSeconds: 20Practical difference:
- readiness controls traffic
- liveness controls restart
ConfigMaps
A ConfigMap stores non-sensitive configuration outside the container image.
This is useful because containers should be reusable and environment-independent.
Examples of data stored in ConfigMaps:
- application settings
- feature flags
nginx.conf- environment-specific values
ConfigMaps can be consumed as:
- environment variables
- files mounted through volumes
Example ConfigMap:
apiVersion: v1kind: ConfigMapmetadata: name: api-configdata: APP_ENV: production LOG_LEVEL: infoUse it in a Deployment:
envFrom: - configMapRef: name: api-configImportant:
- ConfigMaps are for non-sensitive data
- Secrets are for sensitive data
Secrets
A Secret stores sensitive data such as:
- passwords
- API tokens
- database connection credentials
It can also be mounted as files or exposed as environment variables.
Important clarification:
- Secrets are not magically encrypted by default in every setup
- they are only base64-encoded in the manifest
- stronger protection depends on cluster configuration
Namespaces
Namespaces logically separate resources inside the same cluster.
Common use cases:
- separate teams
- separate environments like
dev,staging,prod - avoid naming collisions
Examples:
kubectl get pods -n kube-systemkubectl get services -n defaultThe kube-system namespace contains many internal Kubernetes components.
Requests and Limits
Containers can declare resource needs.
requests: minimum resources the scheduler uses when placing the Podlimits: maximum resources the container is allowed to use
Example:
resources: requests: cpu: "200m" memory: "256Mi" limits: cpu: "500m" memory: "512Mi"This matters because:
- scheduling decisions depend on requests
- limits help prevent one container from consuming too much
Volumes and Persistent Storage
Containers are ephemeral, so data written inside the container filesystem can disappear when the Pod is recreated.
Volumes let Pods access storage.
Important distinction:
- a regular Pod restart may keep some Pod-level volume data
- a Pod replacement can still lose data unless persistent storage is configured
For stateful apps, Kubernetes typically uses persistent volumes.
Key objects:
PersistentVolume(PV)PersistentVolumeClaim(PVC)
Simple idea:
- PV = actual storage resource
- PVC = request for storage by a Pod
Ingress
Ingress manages external HTTP/HTTPS access to Services, usually with routing rules.
Example use case:
/apigoes to the API Service/goes to the frontend Service
Ingress sits above Services and usually requires an Ingress Controller such as NGINX Ingress.
Useful Mental Model
Think of Kubernetes in layers:
Podruns containersReplicaSetkeeps the right number of PodsDeploymentmanages updates for stateless appsServicegives stable networking to PodsIngressexposes HTTP/HTTPS routes from outside
And behind all of this:
- the control plane watches desired state
- worker nodes run workloads
- controllers continuously reconcile differences
Common Interview-Level Clarifications
Pod vs Container
- container = the running process packaged as an image
- Pod = Kubernetes wrapper around one or more containers
Deployment vs ReplicaSet
- ReplicaSet keeps N Pods alive
- Deployment manages ReplicaSets and rollout strategy
Service vs Ingress
- Service exposes Pods inside the cluster or at the network level
- Ingress provides HTTP/HTTPS routing rules to Services
Readiness vs Liveness
- readiness decides if traffic should reach the Pod
- liveness decides if the container should be restarted
ConfigMap vs Secret
- ConfigMap = non-sensitive configuration
- Secret = sensitive configuration
Minimal End-to-End Example
This example shows how a Deployment and Service work together.
apiVersion: apps/v1kind: Deploymentmetadata: name: demo-apispec: replicas: 2 selector: matchLabels: app: demo-api template: metadata: labels: app: demo-api spec: containers: - name: api image: nginx:1.25 ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: demo-api-servicespec: selector: app: demo-api ports: - port: 80 targetPort: 80 type: ClusterIPWhat happens:
- Deployment asks for 2 Pods
- ReplicaSet creates and maintains those 2 Pods
- Service finds Pods with label
app: demo-api - Other Pods can call
demo-api-serviceinside the cluster
Summary
Kubernetes is a system for running containers reliably at scale.
The most important ideas are:
- everything is described as desired state
- Pods are the basic workload unit
- Deployments manage stateless app replicas and rollouts
- Services provide stable access to Pods
- probes control health and traffic readiness
- ConfigMaps and Secrets externalize configuration
- the control plane continuously reconciles cluster state