Key Takeaway: Kubernetes is a system that runs your containerized applications across multiple servers, keeps them healthy, and scales them up or down automatically --- so you focus on building software instead of babysitting infrastructure.
Kubernetes is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications across clusters of machines. Google originally designed it based on 15 years of running production containers internally, then donated it to the Cloud Native Computing Foundation (CNCF) in 2015. Today, over 96% of organizations surveyed by the CNCF report using or evaluating Kubernetes, and every major cloud provider --- AWS, Azure, and Google Cloud --- offers a managed Kubernetes service.
If you are a cloud engineer, DevOps practitioner, or developer working with containerized applications, Kubernetes is a skill you cannot afford to skip. This guide explains everything in plain English, with practical YAML examples you can run on your own machine. No prior Kubernetes experience is required --- just a basic understanding of what containers and Docker do. If you want to brush up on Docker fundamentals first, read our Docker vs Kubernetes comparison to understand how the two tools relate.
What Problem Does Kubernetes Actually Solve?
Imagine you have built a web application, packaged it into a Docker container, and deployed it to a single server. That works fine for a side project. But when real users arrive, problems stack up quickly:
- One server is not enough. Traffic spikes crash your single container.
- Crashes happen. When the container dies at 3 AM, nobody restarts it until morning.
- Updates are risky. Deploying a new version means downtime while you stop the old container and start the new one.
- Scaling is manual. You write custom scripts to launch containers across multiple machines, then build your own health checks, load balancing, and service discovery from scratch.
Before Kubernetes, every team solved these problems differently. They wrote custom deployment scripts, built homegrown health-check systems, and stitched together service discovery with Consul or ZooKeeper. The result was fragile, expensive-to-maintain infrastructure that varied wildly between organizations.
Kubernetes solves all of this with a single, declarative API. You describe your desired state --- "I want 5 copies of my web server, each with 512 MB of memory, behind a load balancer" --- and Kubernetes continuously works to make reality match that description. If a server fails, Kubernetes moves your containers to a healthy server. If traffic doubles, Kubernetes adds more replicas. If you push a new container image, Kubernetes performs a rolling update with zero downtime.
The value proposition is straightforward: Kubernetes replaces dozens of custom scripts and tools with one consistent platform that works the same way whether you run 5 containers or 5,000.
How Does Kubernetes Architecture Work?
A Kubernetes cluster has two parts: the control plane (the brain) and the worker nodes (the muscle). Understanding how these interact is the foundation of everything else.
The Control Plane
The control plane makes all the decisions. It runs on one or more dedicated machines (or is fully managed by your cloud provider). Here are its key components:
kube-apiserver --- The front door to Kubernetes. Every action --- creating a container, scaling a deployment, reading logs --- goes through the API server as an HTTP request. It validates requests, checks permissions, and stores the result in etcd. Think of it as the receptionist that every visitor must pass through.
etcd --- A distributed key-value database that stores every piece of cluster state. Every pod, service, secret, and config map you create is saved here. If etcd is lost and unrecoverable, the cluster state is gone. Production clusters back up etcd automatically every 30 minutes at minimum.
kube-scheduler --- Watches for newly created pods that have not been assigned to a node yet and picks the best node for each one. It considers CPU and memory requirements, affinity rules, taints, and tolerations. The scheduler does not run containers --- it only decides where they should run.
kube-controller-manager --- Runs a collection of control loops that detect when actual state drifts from desired state and take corrective action. For example, the ReplicaSet controller notices when a pod crashes and creates a replacement. The Node controller detects when a worker node goes offline. Each controller operates independently, watching its assigned resource type.
Worker Nodes
Worker nodes are the machines that actually run your containers. Each node has three components:
kubelet --- An agent on every node that receives pod specifications from the API server and ensures the described containers are running and healthy. If a container crashes, kubelet restarts it. It also reports node status and resource usage back to the control plane.
kube-proxy --- Maintains network rules on each node so that traffic sent to a Kubernetes Service gets forwarded to the correct pods. It configures iptables or IPVS rules automatically.
Container runtime --- The software that pulls container images and runs them. Since Kubernetes 1.24, the default runtime is containerd. Docker-built images still work perfectly --- only the runtime interface changed.
Architecture Diagram Description
Visualize it this way:
+--------------------------+
| CONTROL PLANE |
| |
| kube-apiserver |
| etcd (cluster state) |
| kube-scheduler |
| kube-controller-manager |
+-----------+--------------+
|
API calls over HTTPS
|
+-------------------+-------------------+
| | |
+---------v--------+ +-------v----------+ +------v-----------+
| WORKER NODE 1 | | WORKER NODE 2 | | WORKER NODE 3 |
| | | | | |
| kubelet | | kubelet | | kubelet |
| kube-proxy | | kube-proxy | | kube-proxy |
| containerd | | containerd | | containerd |
| | | | | |
| [Pod A] [Pod B] | | [Pod C] [Pod D] | | [Pod E] [Pod F] |
+------------------+ +------------------+ +------------------+
The control plane talks to worker nodes through the kubelet agent. Users and CI/CD systems interact with the control plane through the API server, typically using the kubectl command-line tool. The control plane runs separately from your application workloads, which live entirely on worker nodes.
What Are the Core Kubernetes Resources You Need to Know?
Kubernetes has dozens of resource types, but beginners need to understand five: Pods, Deployments, Services, ConfigMaps, and Secrets. Master these, and you can deploy most applications.
Pods: The Smallest Unit
A Pod is the smallest deployable unit in Kubernetes. It wraps one or more containers that share a network namespace (they can talk to each other on localhost) and storage volumes. In practice, most pods run a single application container. Multi-container pods are used for sidecar patterns like log collection, proxy injection, or secret management.
Here is a pod specification in YAML:
apiVersion: v1
kind: Pod
metadata:
name: nginx-basic
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
Key details in plain English:
-
apiVersion: v1tells Kubernetes which API to use. -
kind: Podsays "this is a pod definition." -
metadata.namegives the pod a human-readable name. -
metadata.labelsattaches key-value tags so other resources (Services, Deployments) can find this pod. -
spec.containerslists the containers inside the pod. Here, there is one container running the nginx web server. -
resources.requeststells the scheduler "this container needs at least 100 millicores of CPU and 128 megabytes of memory." The scheduler will only place it on a node with enough capacity. -
resources.limitssays "this container cannot use more than 250 millicores and 256 megabytes." This prevents a runaway process from starving other pods on the same node.
Always set resource requests and limits. Without them, a single misbehaving container can consume an entire node's resources and crash everything else running there.
Deployments: Managing Pod Lifecycles
You almost never create pods directly. Instead, you create a Deployment, which manages pods through ReplicaSets. A Deployment provides:
- Replica management --- Run N copies of your pod.
- Rolling updates --- Replace old pods with new ones gradually, with zero downtime.
- Rollbacks --- Revert to a previous version if the new one has problems.
- Self-healing --- If a pod crashes, the Deployment automatically creates a replacement.
Here is a deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: app
image: myregistry/web-app:v2.1.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Walking through the important fields:
-
replicas: 3runs three copies of the pod. -
strategy.rollingUpdatesays "during an update, take down at most 1 pod and add at most 1 new pod at a time." This means at least 2 pods are always serving traffic during a deployment. -
readinessProbechecksGET /healthzevery 10 seconds. A pod will not receive traffic from a Service until this probe passes. This prevents sending users to a pod that is still starting up. -
livenessProbechecks the same endpoint every 20 seconds. If this probe fails repeatedly, Kubernetes restarts the container. This catches situations where a process is running but deadlocked or stuck.
The combination of readiness and liveness probes is what makes Kubernetes deployments reliable. The readiness probe prevents sending traffic to unready pods. The liveness probe catches and restarts stuck processes.
Services: Stable Networking
Pods are ephemeral --- they get new IP addresses every time they are rescheduled. If Pod A needs to talk to Pod B, it cannot hardcode Pod B's IP address because that address will change.
Services solve this by providing a stable DNS name and IP address that automatically routes traffic to the correct set of pods.
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: ClusterIP
selector:
app: web-app
ports:
- port: 80
targetPort: 8080
This creates a Service called web-app-service that forwards traffic from port 80 to port 8080 on any pod with the label app: web-app. Other pods in the cluster can reach it at web-app-service.default.svc.cluster.local (or just web-app-service within the same namespace).
Service Types:
| Type | What It Does | When to Use |
|---|---|---|
| ClusterIP (default) | Accessible only inside the cluster | Internal service-to-service communication |
| NodePort | Exposes on a static port (30000-32767) on every node | Development and testing |
| LoadBalancer | Provisions a cloud load balancer (ALB, Azure LB, GCP LB) | Production internet-facing services |
When Should You Use Kubernetes vs Docker Compose?
This is one of the most common questions beginners ask, and the answer depends on your scale, team size, and operational requirements. Here is a direct comparison:
| Factor | Docker Compose | Kubernetes |
|---|---|---|
| Best for | Single-server applications, development environments, small teams | Multi-server production systems, large teams, microservices |
| Complexity | Simple YAML, minimal learning curve | Steeper learning curve, more YAML, more concepts |
| Scaling | Manual (change replica count and restart) | Automatic horizontal pod autoscaling based on CPU, memory, or custom metrics |
| Self-healing | Restart policy on container crash, no node-level recovery | Reschedules pods to healthy nodes if a server fails |
| Rolling updates | Limited (recreate or manual blue-green) | Built-in rolling updates with configurable surge and unavailability |
| Networking | Simple bridge network, manual port mapping | Built-in service discovery, DNS, load balancing across pods |
| Secret management | Environment variables or Docker secrets (single host) | Kubernetes Secrets with encryption at rest, external secret operators |
| Multi-server | No (single Docker host only) | Yes (distributes workloads across a cluster of nodes) |
| Cost | Free, runs on any machine with Docker | Control plane costs ($73/month on EKS/GKE, free on AKS standard tier) plus node costs |
| Ecosystem | Smaller, focused on local development | Massive ecosystem: Helm, ArgoCD, Prometheus, Istio, hundreds of operators |
Use Docker Compose when: - Your application runs on a single server and will stay there. - You are building a development or staging environment. - Your team has fewer than five engineers and does not need multi-server redundancy. - You want the simplest possible container setup.
Use Kubernetes when: - Your application needs to survive server failures without downtime. - You need automatic scaling based on traffic. - You run microservices that need service discovery and internal load balancing. - You have a team large enough to justify the operational overhead. - You are deploying to production on AWS, Azure, or GCP and want managed infrastructure.
For a deeper comparison of the two tools, including code examples for both, see our article on Docker vs Kubernetes: When to Use Each.
How Do You Configure Applications in Kubernetes?
Applications need configuration --- database hostnames, feature flags, API keys, TLS certificates. Kubernetes provides two resources for this: ConfigMaps for non-sensitive data and Secrets for sensitive data.
ConfigMaps
ConfigMaps store configuration as key-value pairs. You can inject them into pods as environment variables or mount them as files.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "postgres.default.svc.cluster.local"
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"
To use these values in a pod, reference the ConfigMap in the container spec:
envFrom:
- configMapRef:
name: app-config
Now your application can read DATABASE_HOST, LOG_LEVEL, and MAX_CONNECTIONS as standard environment variables.
Secrets
Secrets hold sensitive data --- passwords, API keys, TLS certificates. They are base64-encoded by default (not encrypted), so you must enable encryption at rest for etcd in production. Better yet, use the External Secrets Operator to sync secrets from AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager directly into Kubernetes.
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
username: app_user
password: "use-external-secret-manager-in-production"
The critical distinction: ConfigMaps are for configuration that could safely appear in a git repository. Secrets are for values that should never be committed to source control.
How Do You Handle Storage for Stateful Applications?
Pods are ephemeral. When a pod is deleted or rescheduled, its local filesystem disappears. Databases, file uploads, and any workload requiring data persistence need PersistentVolumes.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp3
resources:
requests:
storage: 50Gi
A PersistentVolumeClaim (PVC) is a request for storage. On managed Kubernetes, the storageClassName maps to cloud provider storage:
-
gp3on EKS provisions AWS EBS gp3 volumes. -
managed-csion AKS provisions Azure Managed Disks. -
standard-rwoon GKE provisions Google Persistent Disks.
You mount the PVC into your pod spec, and Kubernetes handles provisioning the actual disk, attaching it to the node where your pod runs, and reattaching it if the pod moves to a different node.
How Do You Expose Applications to the Internet?
For HTTP and HTTPS traffic, Kubernetes uses Ingress resources to route external requests to the correct backend Service based on hostname or URL path.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
This Ingress routes app.example.com/ to web-app-service and app.example.com/api to api-service, all through a single load balancer with TLS termination. You need an Ingress Controller installed in the cluster --- popular options include NGINX Ingress Controller, Traefik, and cloud-native controllers like the AWS ALB Ingress Controller.
What About Security? Understanding RBAC
Kubernetes includes Role-Based Access Control (RBAC) to restrict who can do what in your cluster. It is enabled by default on all managed Kubernetes services.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: production
name: read-pods-binding
subjects:
- kind: User
name: "developer@example.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
This creates a Role that allows reading pods and pod logs in the production namespace, then binds that Role to a specific user. The user can view pods but cannot create, delete, or modify them.
The principle of least privilege applies: give users and service accounts only the permissions they need. Start restrictive and expand as needed, rather than granting cluster-admin and trying to lock things down later.
Which Managed Kubernetes Service Should You Choose?
Running Kubernetes yourself (the control plane, etcd backups, cluster upgrades) is complex. Most teams use a managed service where the cloud provider handles the control plane and you manage only the worker nodes and your application deployments.
Amazon EKS
EKS charges $0.10/hour for the control plane ($73/month). Worker nodes are billed as regular EC2 instances. EKS integrates deeply with AWS IAM, Application Load Balancers, EBS and EFS for storage, and CloudWatch for monitoring. Fargate profiles allow running pods without managing any nodes at all.
Best for: AWS-centric organizations, teams with existing AWS infrastructure, workloads needing deep AWS service integration.
Azure AKS
AKS does not charge for the control plane on its standard tier (the uptime SLA tier costs $0.10/hour). Worker nodes are billed as Azure VMs. AKS integrates with Entra ID for identity, Azure Monitor for observability, and Azure Policy for governance.
Best for: Microsoft shops using Azure AD, organizations running Windows containers (AKS has the strongest Windows node support), teams already on Azure.
Google GKE
GKE Autopilot is the most hands-off option --- Google manages the nodes entirely, and you pay only for the resources your pods actually request. GKE Standard charges $0.10/hour plus node costs. GKE Autopilot enforces security best practices automatically (no privileged containers, no host network access).
Best for: Teams wanting minimal operational overhead, organizations prioritizing developer productivity over infrastructure control.
If you are pursuing Kubernetes certification alongside learning, our CKA, CKAD, and CKS certification comparison guide breaks down which exam aligns with your career goals.
How Do You Get Started Right Now?
You do not need a cloud account to start learning. Install kubectl and create a local cluster on your laptop using kind (Kubernetes in Docker) or minikube:
# Install kind (requires Go)
go install sigs.k8s.io/kind@v0.24.0
# Create a local cluster
kind create cluster --name learning
# Verify you are connected
kubectl cluster-info
kubectl get nodes
# Deploy nginx with 3 replicas
kubectl create deployment nginx --image=nginx:1.27-alpine --replicas=3
# Expose it as a service
kubectl expose deployment nginx --port=80 --type=NodePort
# Check everything is running
kubectl get pods -o wide
kubectl get services
# Scale up to 5 replicas
kubectl scale deployment nginx --replicas=5
# Watch pods appear in real time
kubectl get pods -w
# Update the image (triggers a rolling update)
kubectl set image deployment/nginx nginx=nginx:1.28-alpine
# Roll back to the previous version
kubectl rollout undo deployment/nginx
# Clean up
kind delete cluster --name learning
Practice these commands until they feel natural. The muscle memory of kubectl comes from repetition. Try deploying a multi-container application, breaking pods intentionally to see how Kubernetes recovers, and inspecting events with kubectl describe pod <name>.
What Production Best Practices Should Beginners Know?
Even as a beginner, understanding production patterns early prevents bad habits:
-
Use namespaces for isolation. Separate environments (dev, staging, production) and teams into namespaces. Apply ResourceQuotas to prevent any namespace from consuming all cluster resources.
-
Define Pod Disruption Budgets. Specify the minimum number of pods that must stay running during voluntary disruptions like node drains and cluster upgrades.
-
Enforce Network Policies. By default, every pod can talk to every other pod. Network Policies restrict traffic --- for example, allowing only your API pods to reach the database pods.
-
Scan container images. Use tools like Trivy, Snyk, or cloud-native scanning (AWS ECR scanning, GCP Artifact Analysis) to catch vulnerabilities before deployment.
-
Adopt GitOps. Use ArgoCD or Flux to sync cluster state from a Git repository. Every change goes through a pull request, creating audit trails and one-click rollbacks.
-
Deploy observability from day one. Prometheus for metrics, Grafana for dashboards, and a log aggregation stack (Loki, the EFK stack, or cloud-native logging). Set alerts for pod restart loops, high memory pressure, and expiring TLS certificates.
Frequently Asked Questions
Is Kubernetes hard to learn?
Kubernetes has a real learning curve, but it is not as steep as its reputation suggests. If you already understand containers (building Docker images, running them, mapping ports), you have the foundation. The core concepts --- pods, deployments, services --- take a few hours to understand and a few weeks of practice to internalize. The complexity grows when you move into production operations: networking, RBAC, storage, cluster upgrades, and troubleshooting. Start with a local cluster using kind, deploy a few applications, and build from there.
Do I need to learn Docker before Kubernetes?
Yes. Kubernetes orchestrates containers; it does not replace Docker. You need to understand how to build container images, write Dockerfiles, and run containers locally before adding the orchestration layer. Our Docker vs Kubernetes guide covers the relationship between the two in detail.
Can I run Kubernetes on my laptop?
Absolutely. Tools like kind (Kubernetes in Docker), minikube, and Docker Desktop with Kubernetes enabled all run a local cluster on a single machine. These clusters behave almost identically to cloud clusters for learning purposes. You can create deployments, services, ingress rules, and RBAC policies locally before ever touching a cloud provider.
How much does Kubernetes cost in production?
The control plane costs range from free (AKS standard tier) to $73/month (EKS, GKE Standard). Worker node costs depend on the instance types you choose --- typically $50-200/month per node for small-to-medium workloads. GKE Autopilot charges only for pod resource requests, which can reduce costs for variable workloads. The real cost is often engineering time for cluster management, which is why managed services are the default recommendation for most teams.
What Kubernetes certifications exist and which should I pursue first?
The CNCF offers three certifications: CKA (Certified Kubernetes Administrator), CKAD (Certified Kubernetes Application Developer), and CKS (Certified Kubernetes Security Specialist). For beginners moving into DevOps or platform engineering, start with the CKA. For developers who primarily deploy applications to existing clusters, the CKAD is more relevant. The CKS requires passing the CKA first and focuses on cluster security hardening. Read our complete CKA study guide for a structured preparation plan.
Where to Go From Here
The resources covered in this guide represent approximately 20% of what Kubernetes offers. StatefulSets for databases, DaemonSets for node-level agents, Jobs and CronJobs for batch processing, Custom Resource Definitions for extending the API, Operators for automating complex applications, and service meshes for advanced traffic management all build on these fundamentals.
The path forward has three steps. First, deploy real applications on a local cluster until the core concepts are second nature. Second, move to a managed cloud cluster (EKS, AKS, or GKE) and configure networking, storage, and RBAC in a production-like environment. Third, pursue certification to validate your skills and accelerate your career.
Citadel Cloud Management's free DevOps courses cover Kubernetes from beginner to production-grade deployments, including hands-on labs for EKS, AKS, and GKE. The courses walk you through real cluster setups, Helm chart development, ArgoCD GitOps workflows, and the observability stack that production clusters require.
For cloud engineers preparing for certification exams, our CKA vs CKAD vs CKS comparison helps you choose the right exam, and our structured study guides provide week-by-week preparation plans aligned to the exam objectives.
Ready to build production-grade Kubernetes skills? Start with Citadel's free DevOps and cloud courses and move from beginner to certified Kubernetes practitioner with real-world labs and enterprise architecture patterns.