Docker is phenomenal for packaging an application into an isolated container. However, what happens when you need to run 500 instances of that container across 20 different physical servers? What if server #4 catches fire? Who restarts the containers? Who handles the load balancing? Kubernetes (K8s) is the industry-standard orchestration system that manages the deployment, scaling, and self-healing of containerized applications.


Module 1: The Kubernetes Architecture

Kubernetes is a declarative system. You do not write scripts saying "run this container, then map this port". Instead, you write a YAML file describing the Desired State (e.g., "I want 3 instances of my Node.js app running at all times"). The K8s Control Plane constantly monitors the cluster, and if an instance crashes, it automatically creates a new one to match your desired state.

The K8s Vocabulary

  • Pod: The smallest deployable unit. It contains one (or sometimes more) Docker containers. You never run containers directly; you run Pods.
  • Node: A physical or virtual machine (e.g., an AWS EC2 instance) that runs your Pods.
  • Cluster: A group of Nodes managed by a Control Plane.
  • Deployment: A controller that manages a group of identical Pods and handles seamless rolling updates.

Module 2: Writing a Deployment

Let's deploy a Node.js backend. We define a Deployment.yaml.

deployment.yamlyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-api
  labels:
    app: backend
spec:
  replicas: 3 # We want EXACTLY 3 pods running
  selector:
    matchLabels:
      app: backend
  template: # The blueprint for the Pod
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: nodejs-app
        image: my-docker-repo/backend-api:v1.0.0
        ports:
        - containerPort: 3000
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"

Apply this to the cluster using kubectl apply -f deployment.yaml. Kubernetes will pull the image and distribute the 3 pods across your nodes.


Module 3: Exposing the App (Services)

Pods are mortal. They die, and K8s restarts them with entirely new IP addresses. You cannot rely on a Pod's IP. A Service provides a stable IP address and acts as an internal load balancer.

service.yamlyaml
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend # This tells the Service to route traffic to any Pod with this label
  ports:
    - protocol: TCP
      port: 80         # Port exposed inside the cluster
      targetPort: 3000 # Port the Node.js app is listening on inside the Pod

Module 4: Ingress (Routing External Traffic)

A Service makes your app reachable inside the cluster. To expose it to the internet, you need an Ingress Controller (like Nginx). The Ingress acts as an API Gateway, routing traffic based on URL paths.

ingress.yamlyaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
spec:
  rules:
  - host: api.mycompany.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port: 
              number: 80

Module 5: ConfigMaps and Secrets

Never bake environment variables into your Docker image. K8s provides ConfigMaps for non-sensitive data and Secrets for passwords.

secret.yamlyaml
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  # Values must be Base64 encoded
  db_password: c3VwZXJzZWNyZXQ=