Learn Kubernetes in 10 DaysDay 10: Production Readiness and Best Practices

Day 10: Production Readiness and Best Practices

What You'll Learn Today

  • Resource isolation with Namespaces
  • Access control with RBAC
  • ResourceQuota and LimitRange
  • Monitoring and logging
  • Production best practices

Namespace Resource Isolation

In Day 2, you learned Namespace basics. In production, Namespaces separate resources by environment or team.

flowchart TB
    subgraph Cluster["Kubernetes Cluster"]
        subgraph Dev["dev namespace"]
            D1["App Pod"]
            D2["DB Pod"]
        end
        subgraph Staging["staging namespace"]
            S1["App Pod"]
            S2["DB Pod"]
        end
        subgraph Prod["production namespace"]
            P1["App Pod x3"]
            P2["DB Pod"]
        end
    end
    style Dev fill:#22c55e,color:#fff
    style Staging fill:#f59e0b,color:#fff
    style Prod fill:#3b82f6,color:#fff
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: production
# Create namespaces
kubectl create namespace production
kubectl create namespace staging

# Deploy to a namespace
kubectl apply -f deployment.yaml -n production

# Set default namespace
kubectl config set-context --current --namespace=production

RBAC (Role-Based Access Control)

RBAC controls who can do what in the cluster.

flowchart LR
    USER["User / ServiceAccount"] --> RB["RoleBinding"]
    RB --> ROLE["Role"]
    ROLE --> RES["Resources\n(Pods, Services...)"]
    style ROLE fill:#3b82f6,color:#fff
    style RB fill:#8b5cf6,color:#fff

Role and ClusterRole

Resource Scope Purpose
Role Within a Namespace Access to resources in a specific Namespace
ClusterRole Cluster-wide Access across all Namespaces or cluster resources
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: developer
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]

RoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: production
subjects:
  - kind: User
    name: alice
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer
  apiGroup: rbac.authorization.k8s.io

ServiceAccount

Authentication identity for Pods accessing the Kubernetes API.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-service-account
  namespace: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
spec:
  template:
    spec:
      serviceAccountName: app-service-account
      containers:
        - name: web
          image: nginx:1.27

ResourceQuota and LimitRange

ResourceQuota

Sets resource usage limits per Namespace.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: production-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"
    services: "20"
    persistentvolumeclaims: "10"

LimitRange

Sets defaults and limits for individual Pods/containers.

apiVersion: v1
kind: LimitRange
metadata:
  name: production-limits
  namespace: production
spec:
  limits:
    - type: Container
      default:
        cpu: "250m"
        memory: "256Mi"
      defaultRequest:
        cpu: "100m"
        memory: "128Mi"
      max:
        cpu: "2"
        memory: "4Gi"
      min:
        cpu: "50m"
        memory: "64Mi"

NetworkPolicy

Controls network traffic between Pods β€” an evolution of Docker network isolation.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
flowchart LR
    FE["frontend"] -->|"allow: 8080"| API["api"]
    API -->|"allow: 5432"| DB["postgres"]
    OTHER["other pods"] -->|"denied"| API
    style API fill:#3b82f6,color:#fff
    style OTHER fill:#ef4444,color:#fff

Monitoring and Logging

Metrics Server

# Node resource usage
kubectl top nodes

# Pod resource usage
kubectl top pods -n production
kubectl top pods --sort-by=cpu
kubectl top pods --sort-by=memory

Log Management

# Pod logs
kubectl logs deployment/web-app -n production
kubectl logs deployment/web-app -n production -f --tail=100

# All containers
kubectl logs deployment/web-app -n production --all-containers

# By label selector
kubectl logs -l app=web -n production

Prometheus + Grafana (Overview)

flowchart LR
    PODS["Pods\n(/metrics)"] --> PROM["Prometheus\n(metrics collection)"]
    PROM --> GRAF["Grafana\n(visualization)"]
    PROM --> ALERT["AlertManager\n(alerts)"]
    style PROM fill:#ef4444,color:#fff
    style GRAF fill:#f59e0b,color:#fff
    style ALERT fill:#8b5cf6,color:#fff
# Install with Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace

Production Checklist

Security

Item Description
RBAC Principle of least privilege
NetworkPolicy Restrict unnecessary Pod communication
Pod Security Run containers as non-root
Secret management Use external secret management tools
Image scanning Scan for vulnerabilities

Pod Security Configuration

spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
        - name: app
          image: myapp:1.0
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL

Reliability

Item Setting
Replicas Minimum 2
PodDisruptionBudget Guarantee minimum running Pods
Probes Configure liveness, readiness, startup
Resources Always set requests/limits
Anti-Affinity Spread Pods across nodes

PodDisruptionBudget

Maintains minimum Pod count during maintenance.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

Pod Anti-Affinity

Spreads Pods across different nodes.

spec:
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: web
                topologyKey: kubernetes.io/hostname

Complete Production Configuration

apiVersion: v1
kind: Namespace
metadata:
  name: production
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    pods: "50"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web
    spec:
      serviceAccountName: web-sa
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app: web
                topologyKey: kubernetes.io/hostname
      containers:
        - name: web
          image: myapp:1.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: "200m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 5
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
          envFrom:
            - configMapRef:
                name: app-config
            - secretRef:
                name: app-secret
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
  namespace: production
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 3000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web-pdb
  namespace: production
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: web

kubectl Command Reference

Category Command Description
Info kubectl get <resource> List resources
kubectl describe <resource> <name> Resource details
kubectl logs <pod> View logs
kubectl top <nodes/pods> Resource usage
Create/Update kubectl apply -f <file> Declarative create/update
kubectl create <resource> Create resource
kubectl scale deployment <name> --replicas=N Scale
kubectl set image deployment/<name> Update image
Delete kubectl delete -f <file> Delete from file
kubectl delete <resource> <name> Delete specific resource
Debug kubectl exec -it <pod> -- /bin/sh Execute command in container
kubectl port-forward <pod> <local>:<remote> Port forward
kubectl cp <pod>:<path> <local-path> Copy files
Rollout kubectl rollout status deployment/<name> Update status
kubectl rollout undo deployment/<name> Rollback
kubectl rollout history deployment/<name> History

Docker to Kubernetes Command Mapping

Docker Command Kubernetes Command
docker run kubectl run / kubectl apply
docker ps kubectl get pods
docker logs kubectl logs
docker exec kubectl exec
docker stop kubectl delete pod
docker-compose up kubectl apply -f
docker-compose down kubectl delete -f
docker volume kubectl get pv/pvc
docker network kubectl get svc/ingress

Summary

Concept Description
Namespace Logical resource isolation
RBAC Role-based access control
ResourceQuota Per-Namespace resource limits
NetworkPolicy Pod-to-Pod network access control
PodDisruptionBudget Minimum Pod guarantee during maintenance
Pod Security Non-root users, read-only filesystem, etc.

Key Takeaways

  1. In production, use Namespaces, RBAC, and ResourceQuota for proper resource management and isolation
  2. Security is defense in depth β€” combine Pod Security, NetworkPolicy, and RBAC
  3. For reliability, configure Probes, PDB, Anti-Affinity, and HPA

Practice Exercises

Exercise 1: Namespace Design

Create three Namespaces (dev, staging, production) and set ResourceQuota for each.

Exercise 2: RBAC

Create RBAC settings allowing a development team full access to the dev Namespace but read-only Pod access in production.

Challenge

Build a 3-tier architecture (Web + API + Database) with Namespaces, RBAC, NetworkPolicy, HPA, and PDB all configured.


References


Conclusion

Over 10 days, you've built on the container skills from the Docker book to master Kubernetes for production operations.

Day Topic
1 Kubernetes overview and architecture
2 Cluster setup and kubectl
3 Pod details and health checks
4 ReplicaSets and Deployments
5 Networking with Services
6 Storage and data persistence
7 ConfigMaps and Secrets
8 Ingress and external access
9 Scaling and update strategies
10 Production readiness

With Docker providing your container foundation and Kubernetes providing orchestration, you now have the skills to build and operate modern cloud-native applications. For next steps, explore Helm, GitOps (ArgoCD), and service meshes (Istio).