DevOps Tutorial · Containers and Kubernetes · Lesson 19 of 25

Kubernetes Basics

Pods, Deployments, Services and the declarative reconciliation loop that makes Kubernetes self-healing.

Create a free account to save this page, take notes and track your progress. Sign in

What Kubernetes does

Kubernetes runs containers across a cluster of machines. You declare the desired state ("3 replicas of api:1.4"), and controllers continuously compare it with the actual state and fix differences: restarting crashed containers, rescheduling pods from failed nodes, rolling out new versions.

The reconciliation loopTry it yourself
desired = {"api": 3, "worker": 2}
actual = {"api": ["api-a", "api-b"], "worker": ["worker-a", "worker-b", "worker-c"]}

def reconcile():
    for app, want in desired.items():
        pods = actual[app]
        if len(pods) < want:
            new = f"{app}-{chr(ord('a') + len(pods))}"
            pods.append(new)
            print(f"{app}: {len(pods) - 1}/{want} -> start {new}")
        elif len(pods) > want:
            print(f"{app}: {len(pods)}/{want} -> stop {pods.pop()}")
        else:
            print(f"{app}: {want}/{want} ok")

reconcile()
actual["api"].remove("api-b")       # a node fails
print("node lost api-b")
reconcile()

Output

api: 2/3 -> start api-c
worker: 3/2 -> stop worker-c
node lost api-b
api: 2/3 -> start api-c
worker: 2/2 ok

Core objects

Object Purpose
Pod One or more containers scheduled together; the unit Kubernetes runs
Deployment Keeps N identical pods running; handles rolling updates
Service A stable name and virtual IP that load-balances to matching pods
Ingress / Gateway HTTP routing from outside the cluster to Services
ConfigMap / Secret Configuration and sensitive values for pods
Namespace A scope for names, quotas and access control
apiVersion: apps/v1
kind: Deployment
metadata: { name: api }
spec:
  replicas: 3
  selector: { matchLabels: { app: api } }
  template:
    metadata: { labels: { app: api } }
    spec:
      containers:
        - name: api
          image: ghcr.io/acme/api:3f9c2a1      # deploy by commit SHA
          ports: [{ containerPort: 8080 }]
          resources:
            requests: { cpu: 250m, memory: 256Mi }
            limits: { memory: 512Mi }
          readinessProbe: { httpGet: { path: /readyz, port: 8080 } }
---
apiVersion: v1
kind: Service
metadata: { name: api }
spec:
  selector: { app: api }
  ports: [{ port: 80, targetPort: 8080 }]
kubectl apply -f api.yaml
kubectl get pods -l app=api
kubectl describe pod api-7c9d...       # events: scheduling, probes, OOMKilled
kubectl logs deploy/api -f
kubectl rollout undo deploy/api        # back to the previous version

Managed Kubernetes services: Amazon EKS, Azure AKS and Google GKE run the control plane for you.

Test yourself

A pod managed by a Deployment is deleted. What happens?

  1. The Deployment's controller creates a replacement to restore the desired replica count
  2. Nothing until someone redeploys
  3. The whole Deployment is deleted
  4. The Service stops working permanently
Show answer

Answer: The Deployment's controller creates a replacement to restore the desired replica count

Controllers reconcile actual state to desired state continuously.

Was this page helpful?