Kubernetes Fundamentals: Container Orchestration at Scale

Kubernetes (K8s) automates the deployment, scaling, and management of containerized applications. This guide covers the essential objects and commands you need to run workloads in a cluster.

kubectl Basics

kubectl is the primary CLI for interacting with a Kubernetes cluster:

# View cluster info
kubectl cluster-info

# List all resources in the default namespace
kubectl get all

# Get detailed information about a resource
kubectl describe pod my-app-7d4f8b6c9-x2k5j

# View logs
kubectl logs -f deployment/my-app

# Execute a command in a running pod
kubectl exec -it my-app-7d4f8b6c9-x2k5j -- /bin/bash

# Apply a manifest
kubectl apply -f deployment.yaml

# Delete a resource
kubectl delete -f deployment.yaml

Pod Specification

A Pod is the smallest deployable unit. While you rarely create pods directly, understanding the spec is essential:

apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
  labels:
    app: debug
spec:
  containers:
    - name: main
      image: alpine:3.19
      command: ["sleep", "3600"]
      resources:
        requests:
          cpu: "100m"
          memory: "128Mi"
        limits:
          cpu: "500m"
          memory: "256Mi"
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 15
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10

Liveness probes restart the container if it becomes unresponsive. Readiness probes remove the pod from service endpoints until it is ready to accept traffic.

Deployments

Deployments manage ReplicaSets and provide declarative updates:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: myregistry/my-app:v1.2.3
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef:
                name: my-app-config
            - secretRef:
                name: my-app-secrets

The RollingUpdate strategy replaces pods one at a time, ensuring zero downtime.

Services

Services provide stable networking for a set of pods:

# ClusterIP -- reachable only within the cluster
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080
# NodePort -- accessible on every node at a static port
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080
# LoadBalancer -- provisions an external LB (cloud providers)
spec:
  type: LoadBalancer
  ports:
    - port: 443
      targetPort: 8080

Ingress

Ingress routes external HTTP/HTTPS traffic to services:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app
                port:
                  number: 80

ConfigMaps and Secrets

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-config
data:
  APP_ENV: production
  LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
  name: my-app-secrets
type: Opaque
data:
  DB_PASSWORD: c3VwZXJzZWNyZXQ=   # base64-encoded

Namespaces and Resource Limits

Namespaces isolate workloads. Combine them with ResourceQuotas:

kubectl create namespace staging
kubectl get pods -n staging
apiVersion: v1
kind: ResourceQuota
metadata:
  name: staging-quota
  namespace: staging
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
    pods: "20"

Return to the DevOps hub or continue to Docker Guide and Terraform Guide.