Introduction to Kubernetes
Kubernetes (K8s) is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications across a cluster of machines. Originally built by Google and now governed by the CNCF, it has become the industry standard for running containers in production.
Why Kubernetes
Docker packages an app into a container; but running hundreds of containers across many servers — keeping them healthy, scaled, networked, and updated with zero downtime — is what Kubernetes solves.
- Self-healing — restarts failed containers, reschedules them on healthy nodes.
- Horizontal scaling — scale apps up/down automatically based on load.
- Service discovery & load balancing — built-in DNS and traffic distribution.
- Automated rollouts & rollbacks — ship new versions safely.
- Declarative config — you describe the desired state; K8s makes it real and keeps it that way.
The Declarative Model
You don't tell K8s how to do things step by step. You declare the desired state in YAML ("run 3 replicas of this image"), and the control plane continuously reconciles reality toward it.
Kubernetes Architecture
A Kubernetes cluster has two planes: the Control Plane (the brain that makes global decisions) and the Worker Nodes (where your containers actually run). Understanding which component does what is the single most-asked K8s interview question.
Cluster Anatomy — Visual
Control Plane Components
| Component | Responsibility |
|---|---|
| kube-apiserver | The front door — all reads/writes go through its REST API; validates & persists to etcd |
| etcd | Distributed key-value store holding the entire cluster state (the source of truth) |
| kube-scheduler | Watches for unscheduled pods and assigns each to the best node |
| kube-controller-manager | Runs reconcile loops (node, replicaset, deployment controllers…) |
| cloud-controller-manager | Integrates with cloud provider APIs (load balancers, volumes, nodes) |
Worker Node Components
| Component | Responsibility |
|---|---|
| kubelet | Agent on each node; ensures the containers described in PodSpecs are running & healthy |
| kube-proxy | Maintains network rules so Services route traffic to the right pods |
| Container runtime | Actually runs containers (containerd, CRI-O) |
kubectl apply → API server validates & writes to etcd → scheduler picks a node → kubelet on that node tells the runtime to start the pod → kube-proxy wires up networking. Name every component and you've nailed the architecture question.Control Plane Components
The control plane is the cluster's brain — it makes global decisions and detects/responds to events. It never runs your application containers (in a typical setup); it manages everything that does.
The Five Components
- kube-apiserver — the only component everything else talks to; exposes the Kubernetes REST API.
- etcd — consistent, highly-available key-value store; the single source of truth. Back this up!
- kube-scheduler — assigns pods to nodes based on resources, affinity, taints.
- kube-controller-manager — bundles the core controllers (Node, ReplicaSet, Job, Endpoint…).
- cloud-controller-manager — talks to the cloud provider for LBs, storage, and node lifecycle.
Worker Nodes
Worker nodes are the machines (VMs or physical) that actually run your application pods. Each node is managed by the control plane and runs three things.
Node Components
- kubelet — the node agent. Receives PodSpecs from the API server and makes sure those containers are running and healthy; reports status back.
- kube-proxy — implements the Service abstraction by managing iptables/IPVS rules for pod networking.
- Container runtime — containerd or CRI-O; pulls images and runs containers via the CRI.
Inspecting Nodes
cordoned (no new pods) and drained (evict existing pods) for maintenance — key commands during cluster upgrades.Kubernetes Cluster
A cluster is the complete unit: one (or more) control plane nodes plus a set of worker nodes, working together as a single logical platform on which you deploy applications.
Cluster Setup Options
| Tool | Use |
|---|---|
| minikube / kind | Local single-node clusters for learning & dev |
| kubeadm | Bootstrap a self-managed cluster |
| EKS / AKS / GKE | Managed clusters (cloud runs the control plane) |
Quick Local Start
Pods
A Pod is the smallest deployable unit in Kubernetes — a wrapper around one or more containers that share the same network namespace (IP & port space), storage volumes, and lifecycle. You almost never create pods directly; controllers (Deployments) create them for you.
What's Inside a Pod — Visual
Pod Manifest
Key Facts
- Containers in a pod share localhost and can share volumes — used for sidecar patterns.
- Pods are ephemeral & mortal — they get a new IP each time; never rely on a pod's identity.
- A pod is scheduled to one node as a unit (all its containers run together).
- Manage pods via controllers (Deployment/StatefulSet), not directly.
Multi-Container Pods
Sometimes a pod runs more than one container that must work together — sharing network and volumes. There are well-known patterns for this.
The Patterns
| Pattern | Purpose |
|---|---|
| Sidecar | Helper alongside the main app (log shipper, proxy, sync agent) |
| Ambassador | Proxy that simplifies access to external services |
| Adapter | Transforms the app's output to a standard format (e.g. metrics) |
| Init container | Runs to completion before app containers start (setup, migrations) |
Init Container Example
ReplicaSets
A ReplicaSet ensures a specified number of identical pod replicas are running at all times. If a pod dies, the ReplicaSet creates a new one; if there are too many, it deletes extras. It's the self-healing & scaling engine beneath Deployments.
How It Reconciles — Visual
How It Identifies Its Pods
A ReplicaSet uses a label selector to know which pods it owns. It constantly counts pods matching the selector and adds/removes to match the desired replica count.
Deployments
A Deployment is the most common way to run a stateless app. It manages ReplicaSets to provide declarative updates — rolling out new versions, rolling back, and scaling — all while keeping your app available.
Deployment → ReplicaSet → Pods — Visual
Deployment Manifest
Everyday Commands
StatefulSets
A StatefulSet manages stateful applications (databases, Kafka, Zookeeper) that need stable identity and storage — unlike Deployments where pods are interchangeable.
What It Guarantees
- Stable, ordered names —
myapp-0,myapp-1, … (not random). - Stable persistent storage — each pod keeps its own PVC across restarts/rescheduling.
- Ordered, graceful deploy/scale — pods created/deleted in order (0,1,2 …).
- Stable network identity via a headless Service (
myapp-0.svc).
DaemonSets
A DaemonSet ensures a copy of a pod runs on every node (or a subset). As nodes join the cluster, they automatically get the pod; as nodes leave, the pods are removed.
Typical Uses
- Log collectors (Fluentd, Filebeat) on every node.
- Node monitoring agents (node-exporter, Datadog).
- Storage/network plugins (CNI, CSI daemons).
Jobs
A Job runs a pod (or several) to completion — for batch/one-off tasks like a data migration, backup, or report. Unlike Deployments, it's not meant to run forever; it finishes and stops.
parallelism + completions for parallel batch processing. A Job tracks success and retries failed pods up to backoffLimit.CronJobs
A CronJob runs Jobs on a schedule, using standard cron syntax — for recurring tasks like nightly backups, report generation, or cleanup.
successfulJobsHistoryLimit / failedJobsHistoryLimit, and prevent overlap with concurrencyPolicy: Forbid.Namespaces
Namespaces provide virtual clusters within a physical cluster — a way to divide resources between teams, environments, or projects. They give scope to names, enable resource quotas, and support access control (RBAC).
Logical Partitioning — Visual
Working with Namespaces
Key Points
- Default namespaces:
default,kube-system(control plane),kube-public. - Cross-namespace DNS:
service.namespace.svc.cluster.local. - Not everything is namespaced — Nodes, PersistentVolumes, and StorageClasses are cluster-scoped.
- Apply ResourceQuotas and LimitRanges per namespace to cap usage.
Labels and Selectors
Labels are key-value pairs attached to objects; selectors query objects by their labels. This loosely-coupled mechanism is how Services find pods, ReplicaSets own pods, and you filter resources.
selector matching pod labels is exactly how traffic finds pods. Use consistent label conventions (app, tier, env, version).Annotations
Annotations attach non-identifying metadata to objects — info for tools and humans, not for selection. Unlike labels, you can't query by them.
Labels vs Annotations
| Labels | Annotations | |
|---|---|---|
| Purpose | Identify & select | Describe / configure tools |
| Queryable | Yes (selectors) | No |
| Examples | app: myapp | build info, ingress config, change-cause |
nginx.ingress.kubernetes.io/rewrite-target) and Prometheus scrape settings.Services
Pods are ephemeral and get new IPs constantly. A Service provides a stable virtual IP and DNS name in front of a set of pods (selected by labels), with built-in load balancing — so clients have one reliable address regardless of pod churn.
Stable Front for Changing Pods — Visual
The Four Service Types
| Type | Exposes | Use |
|---|---|---|
| ClusterIP | Internal virtual IP (default) | Pod-to-pod within the cluster |
| NodePort | A port on every node | Basic external access / dev |
| LoadBalancer | Cloud load balancer | Production external access |
| ExternalName | A CNAME to an external host | Alias to an external service |
selector → pod labels match, and kube-proxy programs the load-balancing rules. Layering: ClusterIP (internal) → NodePort (node port) → LoadBalancer (cloud LB) each builds on the previous.ClusterIP
ClusterIP is the default Service type. It exposes the Service on an internal virtual IP reachable only inside the cluster — ideal for internal microservice-to-microservice communication.
- Reachable via the cluster IP or DNS name (
myapp.default.svc.cluster.local). - Not accessible from outside the cluster.
- A headless variant (
clusterIP: None) returns pod IPs directly — used by StatefulSets.
NodePort
NodePort exposes the Service on a static port on every node (range 30000–32767). External traffic to <NodeIP>:<NodePort> is routed to the Service, then to pods.
LoadBalancer
LoadBalancer provisions an external cloud load balancer (AWS ELB, GCP LB, Azure LB) that routes internet traffic to the Service. It's the standard way to expose a service externally on managed clusters.
The cloud provider assigns a public IP/hostname (kubectl get svc shows EXTERNAL-IP). Under the hood it builds on NodePort.
ExternalName
ExternalName maps a Service to an external DNS name via a CNAME record — no proxying, no selector, no pods. It lets in-cluster apps reach an external service through a stable internal name.
external-db, and you can later swap the real host (or move the DB into the cluster) without changing app config.Ingress
An Ingress manages external HTTP/HTTPS access to services in the cluster, providing host- and path-based routing, TLS termination, and a single entry point — so you don't need a separate LoadBalancer per service.
One Entry Point, Many Services — Visual
Ingress Manifest
Ingress Controller
An Ingress Controller is the actual pod (a reverse proxy) that watches Ingress resources and implements their routing rules. Kubernetes ships the Ingress API but not a controller — you install one.
Popular Controllers
| Controller | Notes |
|---|---|
| ingress-nginx | Most common, community standard |
| Traefik | Dynamic config, great DX |
| AWS Load Balancer Controller | Provisions ALB/NLB on EKS |
| HAProxy / Contour / Kong | High-performance / API-gateway features |
Service Discovery
Service discovery is how pods find and talk to each other without hardcoding IPs. Kubernetes provides it automatically through DNS and environment variables.
Two Mechanisms
- DNS (preferred) — every Service gets a DNS name; pods resolve
service-name(same namespace) orservice.namespace.svc.cluster.local. - Environment variables — kubelet injects
<SVC>_SERVICE_HOST/PORTfor services existing at pod start (legacy, order-dependent).
DNS in Kubernetes
Kubernetes runs an internal DNS server (CoreDNS) that gives every Service and pod a resolvable name, powering service discovery.
Naming Convention
Debugging DNS
kube-system first.Kubernetes Networking
Kubernetes networking follows a flat model with four fundamental rules, implemented by a CNI plugin (Calico, Cilium, Flannel, AWS VPC CNI).
The Networking Model
- Every pod gets its own IP.
- Pods can communicate with all other pods without NAT.
- Nodes can communicate with all pods.
- The IP a pod sees itself as = the IP others use to reach it.
The Layers
| Communication | Mechanism |
|---|---|
| Container ↔ container (same pod) | localhost |
| Pod ↔ pod | CNI plugin (flat network) |
| Pod ↔ Service | kube-proxy (iptables/IPVS) |
| External ↔ Service | NodePort / LoadBalancer / Ingress |
Network Policies
By default, all pods can talk to all pods. A NetworkPolicy is a firewall for pods — it restricts ingress/egress traffic by pod/namespace selectors and ports, enabling zero-trust segmentation.
ConfigMaps
A ConfigMap stores non-confidential configuration as key-value pairs, decoupling config from container images (the 12-factor principle). The same image runs in dev/staging/prod with different ConfigMaps.
Two Ways to Consume — Visual
Define & Consume
Secrets
A Secret stores sensitive data — passwords, tokens, TLS certs, registry credentials. Structurally like a ConfigMap, but intended for confidential values with extra handling (base64-encoded, can be encrypted at rest, mounted as tmpfs).
Creating Secrets
Consuming Secrets
Volumes
A container's filesystem is ephemeral — lost on restart. A Volume gives pods storage with a lifecycle tied to the pod (or longer, for persistent types) and lets containers in a pod share files.
Common Volume Types
| Type | Lifecycle / Use |
|---|---|
emptyDir | Empty dir created with the pod, deleted with it (scratch/shared) |
configMap / secret | Inject config/secrets as files |
persistentVolumeClaim | Durable storage that outlives the pod (PV/PVC) |
hostPath | A path on the node (use sparingly) |
emptyDir die with the pod.Persistent Volumes (PV)
A PersistentVolume is a piece of cluster storage (an EBS volume, NFS share, disk) provisioned by an admin or dynamically by a StorageClass. It exists independently of any pod — the cluster-level storage resource.
The PV / PVC / Pod Relationship — Visual
Key Concepts
- Access modes: ReadWriteOnce (one node), ReadOnlyMany, ReadWriteMany, ReadWriteOncePod.
- Reclaim policy:
Retain(keep data),Delete(remove with PVC). - Static provisioning (admin pre-creates PVs) vs dynamic (StorageClass creates on demand).
Persistent Volume Claims (PVC)
A PersistentVolumeClaim is a request for storage by a user/pod — specifying size, access mode, and (optionally) a StorageClass. Kubernetes binds the PVC to a matching PV (or dynamically provisions one).
Claim & Use
Binding Lifecycle
PVC states: Pending → Bound (matched to a PV) → Released (PVC deleted) → reclaimed per policy.
Storage Classes
A StorageClass defines a "class" of storage and enables dynamic provisioning — when a PVC requests this class, the matching volume (e.g. an AWS EBS gp3 disk) is created automatically.
- provisioner — the CSI driver that creates the volume.
- WaitForFirstConsumer — delays binding until a pod is scheduled, so the disk lands in the right AZ.
- A cluster can have a default StorageClass used when a PVC omits one.
Resource Requests & Limits
Each container can declare CPU/memory requests (guaranteed minimum, used for scheduling) and limits (hard maximum). These drive scheduling, autoscaling, and stability.
What Happens at the Limit
- CPU over limit → throttled (slowed, not killed).
- Memory over limit → container is OOMKilled (exit 137).
QoS Classes (from requests/limits)
| Class | When |
|---|---|
| Guaranteed | requests == limits for all containers |
| Burstable | requests < limits |
| BestEffort | none set (evicted first under pressure) |
-XX:MaxRAMPercentage so heap respects the container memory limit and avoids OOMKills.Horizontal Pod Autoscaler (HPA)
The HPA automatically scales the number of pod replicas up or down based on observed metrics (CPU, memory, or custom). More load → more pods; less load → fewer. It's how K8s apps handle variable traffic.
The Control Loop — Visual
HPA Manifest
How It Decides
desiredReplicas = ceil(currentReplicas × currentMetric / targetMetric). Requires metrics-server (or a custom metrics adapter) and resource requests set on pods.
Vertical Pod Autoscaler (VPA)
The VPA automatically adjusts the CPU/memory requests & limits of pods based on actual usage — right-sizing them rather than adding more replicas.
Modes
- Off — only recommends values.
- Initial — sets resources at pod creation.
- Auto/Recreate — evicts & recreates pods with new sizes.
Cluster Autoscaler
The Cluster Autoscaler adds or removes nodes in the cluster. When pods can't be scheduled (no capacity), it adds nodes; when nodes are underused, it drains and removes them.
The Three Autoscalers Together
| Autoscaler | Scales | Trigger |
|---|---|---|
| HPA | Pod replicas | CPU/mem/custom metrics |
| VPA | Pod resource sizes | Actual usage |
| Cluster Autoscaler | Nodes | Unschedulable pods / idle nodes |
Rolling Updates
A rolling update is the default Deployment strategy — it replaces old pods with new ones gradually, keeping the app available throughout (zero downtime). New pods are added and verified healthy before old ones are removed.
Gradual Replacement — Visual
Tuning the Rollout
maxSurge + maxUnavailable control speed vs availability. maxUnavailable: 0, maxSurge: 1 = safest (always full capacity). Readiness probes are essential — without them, traffic hits pods before they're ready.Rollbacks
If a new version is broken, you can roll back to a previous one instantly. Kubernetes keeps a revision history of a Deployment (the old ReplicaSets, scaled to 0), so reverting is just scaling the old ReplicaSet back up.
Rollback Commands
How It Works
- Each rollout creates a new ReplicaSet; old ones are retained (scaled to 0).
revisionHistoryLimitcontrols how many old ReplicaSets are kept (default 10).- Rollback scales the old ReplicaSet up and the current one down — another rolling update in reverse.
--record or use kubernetes.io/change-cause annotations so rollout history shows why each revision happened — invaluable during incidents.Health Checks
Kubernetes uses probes to know whether a container is alive, ready for traffic, and finished starting. There are three probe types, each answering a different question.
| Probe | Question | On failure |
|---|---|---|
| Liveness | Is it alive? | Restart the container |
| Readiness | Can it serve traffic? | Remove from Service endpoints |
| Startup | Has it finished booting? | Kill if it never starts; gates the others |
Probe Mechanisms
Each probe can use httpGet, tcpSocket, exec (command), or grpc.
Liveness Probes
A liveness probe answers "is this container still working?" If it fails (e.g. the app deadlocked), Kubernetes restarts the container — self-healing for hung processes that are running but stuck.
Key Guidance
- Probe a lightweight liveness endpoint — not one that checks the DB (a DB outage shouldn't restart your app pointlessly).
- Set a generous
initialDelaySeconds/use a startup probe for slow JVM apps. - Too-aggressive liveness = restart loops; tune
failureThreshold/periodSeconds.
Readiness Probes
A readiness probe answers "is this container ready to receive traffic?" If it fails, the pod is removed from the Service's endpoints (no traffic) but not restarted — perfect for warm-up and temporary dependency loss.
Why It's Critical for Rollouts
- During a rolling update, traffic only goes to pods that pass readiness — so users never hit a half-started pod.
- A pod that loses a dependency can fail readiness (drop out of rotation) and rejoin when healthy — without a restart.
/actuator/health/liveness and /readiness when probes are enabled.Startup Probes
A startup probe protects slow-starting containers. While it's running, liveness and readiness probes are disabled — so a JVM app that takes 60s to boot isn't killed by an impatient liveness probe.
initialDelaySeconds on liveness. Once it passes once, normal liveness/readiness take over.Scheduling
Scheduling is how the kube-scheduler decides which node runs each new pod. It filters nodes that can't fit the pod, then scores the rest and picks the best.
The Two Phases
- Filtering — eliminate nodes lacking resources or violating constraints (taints, affinity, node selectors).
- Scoring — rank remaining nodes (spread, resource balance, affinity preferences) and pick the highest.
Influencing Placement
| Mechanism | Effect |
|---|---|
| nodeSelector | Simple label match |
| Node Affinity | Rich rules (required/preferred) |
| Pod Affinity/Anti-affinity | Place near/away from other pods |
| Taints & Tolerations | Repel pods unless they tolerate |
Pending (and may trigger the Cluster Autoscaler).Node Selectors
The simplest way to constrain a pod to specific nodes: nodeSelector matches node labels. The pod only schedules onto nodes with all the listed labels.
Node Affinity
Node Affinity is an expressive way to constrain which nodes a pod can run on, based on node labels — supporting required (hard) and preferred (soft) rules, plus rich operators (In, NotIn, Exists).
Hard vs Soft — Visual
Manifest
requiredDuringScheduling" = must be satisfied to schedule. "preferredDuringScheduling" = best effort. "IgnoredDuringExecution" means already-running pods aren't evicted if labels later change. Node affinity attracts pods to nodes; taints repel them — they're complementary.Pod Affinity & Anti-Affinity
Pod (anti-)affinity places pods relative to other pods rather than nodes — "co-locate with" (affinity) or "keep apart from" (anti-affinity), using a topology key like node or zone.
Typical Uses
- Anti-affinity — spread replicas across nodes/zones for high availability.
- Affinity — co-locate a cache with the app that uses it to reduce latency.
Taints & Tolerations
Taints and tolerations work together to repel pods from nodes unless the pod explicitly tolerates the taint. It's the inverse of affinity: affinity attracts pods to nodes; taints keep pods off nodes — used to dedicate nodes (GPU, special hardware) or keep workloads off control-plane nodes.
How They Pair — Visual
Applying Them
Taint Effects
| Effect | Meaning |
|---|---|
| NoSchedule | New non-tolerating pods won't schedule |
| PreferNoSchedule | Avoid if possible (soft) |
| NoExecute | Also evicts existing non-tolerating pods |
RBAC (Role-Based Access Control)
RBAC controls who can do what on which resources in the cluster. It binds subjects (users, groups, service accounts) to roles (sets of permissions) — the foundation of cluster security and least privilege.
The Four Objects — Visual
Role + RoleBinding
Role vs ClusterRole
| Scope | |
|---|---|
| Role + RoleBinding | A single namespace |
| ClusterRole + ClusterRoleBinding | Whole cluster (or cluster-scoped resources) |
cluster-admin.Service Accounts
A ServiceAccount is an identity for pods (machine identity), as opposed to user accounts for humans. Pods use it to authenticate to the Kubernetes API and (via cloud integration) to cloud services.
- Each namespace has a
defaultSA; assign a dedicated one per app for least privilege. - Bind RBAC Roles to the SA to control what the pod's code can do via the API.
- Cloud IAM integration: IRSA (EKS), Workload Identity (GKE), Workload Identity (AKS) map SAs to cloud roles.
Security Contexts
A securityContext sets privilege and access controls for a pod or container — run as non-root, drop Linux capabilities, read-only filesystem, etc.
Pod Security Standards
Pod Security Standards (PSS) define three policy levels enforced by the built-in Pod Security Admission controller — replacing the deprecated PodSecurityPolicy.
| Level | Meaning |
|---|---|
| Privileged | Unrestricted (trusted system workloads) |
| Baseline | Prevents known privilege escalations |
| Restricted | Hardened best practice (non-root, no caps…) |
enforce=restricted (with warn/audit for visibility) to block insecure pods at admission time — defense in depth alongside securityContext.Kubernetes Secrets Management
Native Secrets are base64-encoded, not encrypted by default. Production secret management adds encryption, rotation, and external sources.
Hardening & External Options
- Encryption at rest — enable etcd encryption (or a KMS provider) so Secrets aren't plaintext in etcd.
- RBAC — tightly restrict who/what can read Secrets.
- External Secrets Operator — sync from Vault / AWS Secrets Manager / GCP / Azure into K8s Secrets.
- Secrets Store CSI Driver — mount secrets directly from an external store as files.
- Sealed Secrets — encrypt secrets so they're safe to commit to Git (GitOps).
Logging in Kubernetes
Pods are ephemeral, so their logs vanish when they die. Production logging means shipping logs off the node to a central store. The standard pattern: apps log to stdout/stderr → a node agent collects → a backend aggregates & indexes.
The Logging Pipeline — Visual
Key Points
- 12-factor logging — apps write to stdout/stderr, never to files inside the container.
- Node-level agent — Fluent Bit/Fluentd runs as a DaemonSet (one per node) and tails container logs.
- Backends — EFK (Elasticsearch-Fluentd-Kibana) or PLG (Promtail-Loki-Grafana).
kubectl logsonly shows current/recent logs from a live pod — fine for debugging, not for retention.
Monitoring with Prometheus
Prometheus is the de-facto monitoring system for Kubernetes — a time-series database that pulls (scrapes) metrics from targets, stores them, and lets you query (PromQL) and alert on them.
Pull-Based Monitoring — Visual
The Ecosystem
| Component | Role |
|---|---|
| Prometheus | Scrapes & stores metrics; PromQL queries |
| node-exporter | Node-level metrics (CPU, mem, disk) |
| kube-state-metrics | Metrics about K8s objects (deployments, pods) |
| Alertmanager | Routes alerts (Slack, PagerDuty, email) |
| Grafana | Dashboards on top of Prometheus |
kube-prometheus-stack Helm chart (Prometheus + Grafana + Alertmanager + exporters).Grafana Integration
Grafana is the visualization layer — it queries data sources (Prometheus, Loki) and renders dashboards and alerts. It turns raw metrics into the graphs teams watch.
- Add Prometheus as a data source; build panels with PromQL.
- Import community dashboards (e.g. "Kubernetes cluster monitoring" by ID).
- Use Loki as a data source to correlate logs with metrics in one place.
Kubernetes Dashboard
The Kubernetes Dashboard is a general-purpose web UI for the cluster — view workloads, drill into pods, see logs, and do basic management without the CLI.
Observability in Kubernetes
Observability = understanding system state from its outputs, built on three pillars: metrics, logs, and traces.
| Pillar | Answers | Tools |
|---|---|---|
| Metrics | What is happening (rates, saturation) | Prometheus + Grafana |
| Logs | What happened (events, errors) | Loki / EFK |
| Traces | Where time went (request path) | Jaeger / Tempo (OpenTelemetry) |
kubectl Commands
kubectl is the CLI for talking to the cluster's API server. Here's the everyday toolkit.
Viewing & Describing
Creating & Editing
Debugging
kubectl apply -f (GitOps-friendly) over imperative create/run. Add -o yaml --dry-run=client to generate manifests from imperative commands.Helm Charts
Helm is the package manager for Kubernetes. A Chart bundles all the manifests for an app into a versioned, templated, reusable package — so you install complex apps with one command and configure them per environment via values.
Chart → Release — Visual
Core Concepts
| Term | Meaning |
|---|---|
| Chart | A package of templated K8s manifests |
| Values | Config inputs (values.yaml) injected into templates |
| Release | An installed instance of a chart in a cluster |
| Repository | A collection of charts (e.g. Bitnami) |
Commands
Operators
An Operator extends Kubernetes to manage a complex stateful app (a database, Kafka) by encoding human operational knowledge into software — a custom controller that watches a CRD and reconciles the app's desired state (backups, failover, upgrades).
Pattern
- CRD defines a new resource type (e.g.
kind: PostgresCluster). - Custom controller watches it and acts (provision, scale, back up, recover).
- You manage the app declaratively, like any native K8s object.
Custom Resource Definitions (CRDs)
A CRD lets you extend the Kubernetes API with your own resource types. Once defined, your custom resource behaves like a built-in one — created with kubectl apply, stored in etcd, watched by controllers.
Kubernetes API
The Kubernetes API (served by kube-apiserver) is the central interface to everything — kubectl, controllers, and your code all talk to it. It's a RESTful API over resources grouped into API groups and versions.
- Declarative — you POST/PATCH desired state; controllers reconcile.
- Versioned groups —
apps/v1,batch/v1,networking.k8s.io/v1. - Watch — clients stream changes (the basis of controllers).
- Access it with client libraries (client-go, fabric8 for Java) or
kubectl.
Container Runtime
The container runtime is the software on each node that actually runs containers. The kubelet talks to it through the Container Runtime Interface (CRI), so any CRI-compliant runtime works.
Runtimes
| Runtime | Notes |
|---|---|
| containerd | Most common; graduated CNCF project |
| CRI-O | Lightweight, built for K8s (OpenShift default) |
| Docker Engine | Removed as a runtime in v1.24 (dockershim) — images still work |
Docker vs Containerd
A common point of confusion. Docker is a full platform (CLI, build, API) built on top of containerd. Kubernetes only needs the runtime part, so it uses containerd directly.
| Docker | containerd | |
|---|---|---|
| Scope | Full platform (build, CLI, runtime) | Core runtime only |
| CRI-compatible | No (needed dockershim) | Yes (native) |
| Use in K8s | Removed in v1.24 | Default runtime |
Kubernetes Deployment Strategies
How you roll out a new version trades off speed, risk, and cost. The main strategies:
| Strategy | How | Trade-off |
|---|---|---|
| Recreate | Kill all old, start all new | Downtime; simplest |
| Rolling Update | Replace gradually (default) | Zero downtime; two versions briefly coexist |
| Blue-Green | Two full envs, switch traffic | Instant cutover/rollback; 2× resources |
| Canary | Small % to new version first | Lowest risk; needs traffic control |
Blue-Green Deployment
Run two identical environments — Blue (current) and Green (new). Deploy & test Green while Blue serves traffic, then flip the Service to Green in one switch. Roll back instantly by flipping back.
In K8s, switch by updating the Service's selector (e.g. version: v2) to point at the Green pods.
Canary Deployment
Release the new version to a small subset of users/traffic first (e.g. 5%), watch metrics, then gradually ramp to 100% if healthy — or roll back if errors spike. Lowest-risk strategy.
GitOps
GitOps makes Git the single source of truth for cluster state. You commit declarative manifests; an in-cluster agent (Argo CD, Flux) continuously syncs the cluster to match Git — and corrects any drift.
Principles
- Declarative — entire system described in Git.
- Versioned & auditable — every change is a commit/PR.
- Pulled automatically — agent applies Git → cluster (no manual
kubectl apply). - Self-healing — drift is reverted to match Git.
CI/CD with Kubernetes
A typical pipeline builds and tests a container image (CI), then deploys it to the cluster (CD) — increasingly via GitOps.
Pipeline Stages
- CI — build image, run tests, scan for CVEs, push to registry (tag = git SHA).
- CD — update manifests & apply (or let Argo CD/Flux pull).
- Progressive delivery — canary/blue-green via Argo Rollouts.
Managed Kubernetes (EKS / AKS / GKE)
Running your own control plane is hard (etcd, HA, upgrades, security). Managed Kubernetes services run the control plane for you — you just manage workloads and (usually) worker nodes. The big three: EKS (AWS), AKS (Azure), GKE (Google).
Managed vs Self-Managed — Visual
The Big Three
| EKS (AWS) | AKS (Azure) | GKE (Google) | |
|---|---|---|---|
| Pod IAM | IRSA / Pod Identity | Workload Identity | Workload Identity |
| Serverless nodes | Fargate | Virtual Nodes (ACI) | Autopilot |
| Node autoscale | Karpenter / CA | Cluster Autoscaler | Built-in (often best) |
| Origin | — | — | Google created K8s |
EKS Quick Flow
Kubernetes on Azure (AKS)
Azure Kubernetes Service is Microsoft's managed K8s — free managed control plane, deep Azure integration (Entra ID, Azure Monitor, ACR).
- Workload Identity maps K8s ServiceAccounts to Entra ID for keyless Azure access.
- Integrates with Azure Monitor / Container Insights, ACR, and Azure CNI.
- Virtual Nodes (ACI) for serverless burst capacity.
Kubernetes on GCP (GKE)
Google Kubernetes Engine is the most mature managed K8s (Google created Kubernetes). Known for strong autoscaling and the fully-managed Autopilot mode.
- Autopilot — Google manages nodes too; you pay per pod resource, not per node.
- Excellent built-in autoscaling, networking, and release channels.
- Workload Identity for keyless access to Google Cloud APIs.
Troubleshooting Kubernetes Clusters
A systematic approach to the most common K8s failures. Start broad (get), narrow down (describe → events), then inspect (logs/exec).
The Debug Workflow — Visual
Common Pod States & Causes
| Symptom | Likely cause & fix |
|---|---|
ImagePullBackOff | Bad image name/tag or registry auth → check image & imagePullSecrets |
CrashLoopBackOff | App crashes on start → logs --previous; check config/env, liveness probe |
Pending | No node fits → resources, taints, affinity, PVC unbound → describe pod |
OOMKilled (137) | Memory limit too low / leak → raise limit, tune JVM heap |
CreateContainerConfigError | Missing ConfigMap/Secret referenced |
| Service unreachable | Selector/label mismatch, wrong targetPort, no ready endpoints |
Command Toolkit
kubectl describe pod (read the Events) and kubectl logs --previous. For Service issues, always check kubectl get endpoints — empty endpoints = selector/readiness problem.Cluster Upgrades
Kubernetes releases ~3 times a year and supports only the latest few versions, so clusters need regular upgrades. Order matters: control plane first, then nodes.
Process
- Upgrade the control plane (one minor version at a time).
- Upgrade node pools — cordon & drain each node, replace, repeat.
- Check deprecated APIs (
kubectl deprecations/ pluto) before upgrading.
Backup & Disaster Recovery
DR for K8s means protecting two things: cluster state (etcd / API objects) and persistent data (volumes).
- etcd snapshots — back up the control plane's state store (self-managed clusters).
- Velero — back up/restore K8s objects + PV snapshots; supports cross-cluster migration.
- Volume snapshots — via CSI for persistent data.
- GitOps — manifests in Git are themselves a backup of desired state; rebuild a cluster from Git.
High Availability (HA) Clusters
An HA cluster removes single points of failure so the cluster keeps working through node/zone failures.
HA Building Blocks
- Multiple control-plane nodes (3 or 5) with a quorum etcd.
- Multi-AZ worker nodes so a zone outage doesn't take everything down.
- Spread workloads — pod anti-affinity / topologySpreadConstraints + PodDisruptionBudgets.
- ≥2 replicas per service, behind a Service/Ingress.
Service Mesh (Istio)
A service mesh adds a networking layer for service-to-service communication — handling traffic management, security (mTLS), and observability without changing app code, via sidecar proxies (Envoy) injected next to each pod.
What Istio Provides
- Traffic management — fine-grained routing, canary/weighted splits, retries, timeouts.
- Security — automatic mutual TLS between services, authz policies.
- Observability — metrics, traces, and a service-dependency map for free.
Kubernetes Best Practices
✓ Do
- Set resource requests & limits on every container
- Define liveness, readiness & startup probes
- Run as non-root with a securityContext
- Use namespaces + RBAC + least privilege
- Externalize config (ConfigMaps/Secrets)
- ≥2 replicas + anti-affinity + PodDisruptionBudgets
- Pin image tags (git SHA); manage via GitOps/Helm
✗ Avoid
latestimage tags- Running as root / privileged
- No probes (broken pods get traffic)
- Storing state in pods (use PVCs)
- Secrets in plain manifests in Git
- One giant namespace for everything
- Manual
kubectlchanges in prod (drift)
Production-Grade Kubernetes Deployments
A consolidated checklist of what "production-ready" means — tying the whole tutorial together.
Reliability
≥2 replicas · multi-AZ spread · probes · PodDisruptionBudgets · rolling updates · autoscaling (HPA + Cluster Autoscaler).
Resources
Requests & limits on all containers · right-sized · QoS Guaranteed for critical apps.
Security
RBAC least privilege · non-root securityContext · NetworkPolicies · Pod Security restricted · encrypted Secrets.
Observability
Prometheus + Grafana metrics · centralized logging (Loki/EFK) · tracing · alerting.
Delivery
CI builds + scans · immutable SHA tags · GitOps (Argo/Flux) · progressive delivery (canary).
Operations
Backups (Velero + etcd) · tested DR · upgrade plan · managed control plane (EKS/AKS/GKE).