Home / Notebooks / DevOps
DevOps
intermediate

Kubernetes Essentials

Essential Kubernetes concepts and commands for container orchestration

March 10, 2024
Updated regularly

Kubernetes Essentials

Quick reference guide for Kubernetes (K8s) fundamentals.

What is Kubernetes?

Kubernetes is an open-source container orchestration platform for:

  • Automated deployment of containerized applications
  • Scaling applications up and down
  • Load balancing across containers
  • Self-healing (restart failed containers)
  • Rolling updates and rollbacks
  • Service discovery and networking
  • Core Concepts

    Cluster Architecture

    Cluster
    ├── Control Plane (Master)
    │   ├── API Server
    │   ├── Scheduler
    │   ├── Controller Manager
    │   └── etcd (data store)
    └── Worker Nodes
        ├── Kubelet (node agent)
        ├── Container Runtime (Docker/containerd)
        └── Kube-proxy (networking)
    

    Key Components

  • Pod: Smallest deployable unit (one or more containers)
  • Node: Worker machine (VM or physical)
  • Cluster: Set of nodes managed by Kubernetes
  • Namespace: Virtual cluster for resource isolation
  • Service: Stable endpoint for accessing pods
  • Deployment: Manages pod replicas and updates
  • ConfigMap: Configuration data
  • Secret: Sensitive data (passwords, tokens)
  • kubectl Commands

    Cluster Information

    # ========== Get Cluster Info ==========
    kubectl cluster-info
    kubectl version
    kubectl get nodes
    
    # ========== Node Details ==========
    kubectl describe node <node-name>
    kubectl top nodes          # Resource usage
    
    # ========== Get All Resources ==========
    kubectl get all
    kubectl get all -A         # All namespaces
    

    Working with Namespaces

    # ========== List Namespaces ==========
    kubectl get namespaces
    kubectl get ns
    
    # ========== Create Namespace ==========
    kubectl create namespace dev
    kubectl create ns prod
    
    # ========== Use Namespace ==========
    kubectl config set-context --current --namespace=dev
    
    # ========== Delete Namespace ==========
    kubectl delete namespace dev
    

    Pods

    # ========== List Pods ==========
    kubectl get pods
    kubectl get pods -o wide        # More details
    kubectl get pods -A             # All namespaces
    kubectl get pods -w             # Watch for changes
    
    # ========== Create Pod (from YAML) ==========
    kubectl apply -f pod.yaml
    
    # ========== Get Pod Details ==========
    kubectl describe pod <pod-name>
    
    # ========== View Logs ==========
    kubectl logs <pod-name>
    kubectl logs <pod-name> -f      # Follow logs
    kubectl logs <pod-name> -c <container-name>  # Specific container
    
    # ========== Execute Command in Pod ==========
    kubectl exec <pod-name> -- <command>
    kubectl exec -it <pod-name> -- /bin/bash     # Interactive shell
    
    # ========== Delete Pod ==========
    kubectl delete pod <pod-name>
    kubectl delete pod <pod-name> --force --grace-period=0  # Force delete
    

    Deployments

    # ========== List Deployments ==========
    kubectl get deployments
    kubectl get deploy
    
    # ========== Create Deployment ==========
    kubectl create deployment nginx --image=nginx:latest
    
    # ========== Create from YAML ==========
    kubectl apply -f deployment.yaml
    
    # ========== Scale Deployment ==========
    kubectl scale deployment <name> --replicas=5
    
    # ========== Update Image ==========
    kubectl set image deployment/<name> <container>=<new-image>
    
    # ========== Rollout Status ==========
    kubectl rollout status deployment/<name>
    kubectl rollout history deployment/<name>
    
    # ========== Rollback ==========
    kubectl rollout undo deployment/<name>
    kubectl rollout undo deployment/<name> --to-revision=2
    
    # ========== Delete Deployment ==========
    kubectl delete deployment <name>
    

    Services

    # ========== List Services ==========
    kubectl get services
    kubectl get svc
    
    # ========== Expose Deployment ==========
    kubectl expose deployment <name> --port=80 --type=LoadBalancer
    
    # ========== Get Service Details ==========
    kubectl describe service <name>
    
    # ========== Delete Service ==========
    kubectl delete service <name>
    

    ConfigMaps and Secrets

    # ========== ConfigMaps ==========
    kubectl create configmap app-config --from-literal=key=value
    kubectl create configmap app-config --from-file=config.properties
    kubectl get configmaps
    kubectl describe configmap app-config
    kubectl delete configmap app-config
    
    # ========== Secrets ==========
    kubectl create secret generic db-secret --from-literal=password=secret123
    kubectl create secret docker-registry regcred --docker-server=<server> --docker-username=<user> --docker-password=<pass>
    kubectl get secrets
    kubectl describe secret db-secret
    kubectl delete secret db-secret
    

    YAML Manifests

    Pod Definition

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        env:
        - name: ENVIRONMENT
          value: "production"
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
    

    Deployment Definition

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            ports:
            - containerPort: 80
            livenessProbe:
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 30
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 5
    

    Service Definition

    # ========== ClusterIP (Internal) ==========
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      type: ClusterIP
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
    
    ---
    # ========== NodePort (External Access) ==========
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-nodeport
    spec:
      selector:
        app: nginx
      type: NodePort
      ports:
      - port: 80
        targetPort: 80
        nodePort: 30080
    
    ---
    # ========== LoadBalancer ==========
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-lb
    spec:
      selector:
        app: nginx
      type: LoadBalancer
      ports:
      - port: 80
        targetPort: 80
    

    ConfigMap Definition

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: app-config
    data:
      database_url: "postgres://db:5432"
      log_level: "info"
      config.properties: |
        property1=value1
        property2=value2
    

    Secret Definition

    apiVersion: v1
    kind: Secret
    metadata:
      name: db-secret
    type: Opaque
    data:
      username: YWRtaW4=         # base64 encoded "admin"
      password: cGFzc3dvcmQxMjM=  # base64 encoded "password123"
    

    Using ConfigMap and Secret in Pod

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-pod
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        # Environment variable from ConfigMap
        - name: DATABASE_URL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_url
        # Environment variable from Secret
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        # Mount ConfigMap as volume
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: app-config
    

    Ingress

    Route external traffic to services:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: app-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx
      rules:
      - host: myapp.example.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
      tls:
      - hosts:
        - myapp.example.com
        secretName: tls-secret
    

    Persistent Volumes

    Store data persistently:

    PersistentVolume (PV)

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-storage
    spec:
      capacity:
        storage: 10Gi
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: standard
      hostPath:
        path: /data
    

    PersistentVolumeClaim (PVC)

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-storage
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 5Gi
      storageClassName: standard
    

    Using PVC in Pod

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-with-storage
    spec:
      containers:
      - name: app
        image: myapp:latest
        volumeMounts:
        - name: data
          mountPath: /app/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: pvc-storage
    

    StatefulSet

    For stateful applications (databases, etc.):

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mongodb
    spec:
      serviceName: mongodb-service
      replicas: 3
      selector:
        matchLabels:
          app: mongodb
      template:
        metadata:
          labels:
            app: mongodb
        spec:
          containers:
          - name: mongodb
            image: mongo:latest
            ports:
            - containerPort: 27017
            volumeMounts:
            - name: data
              mountPath: /data/db
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 10Gi
    

    Jobs and CronJobs

    Job (Run Once)

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: data-migration
    spec:
      template:
        spec:
          containers:
          - name: migration
            image: migration-image:latest
            command: ["./migrate"]
          restartPolicy: OnFailure
      backoffLimit: 3
    

    CronJob (Scheduled)

    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: backup-job
    spec:
      schedule: "0 2 * * *"  # Every day at 2 AM
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: backup
                image: backup-image:latest
                command: ["./backup.sh"]
              restartPolicy: OnFailure
    

    Resource Management

    Resource Requests and Limits

    apiVersion: v1
    kind: Pod
    metadata:
      name: resource-demo
    spec:
      containers:
      - name: app
        image: myapp:latest
        resources:
          requests:
            memory: "256Mi"    # Minimum guaranteed
            cpu: "500m"        # 0.5 CPU cores
          limits:
            memory: "512Mi"    # Maximum allowed
            cpu: "1000m"       # 1 CPU core
    

    Horizontal Pod Autoscaler (HPA)

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: app-hpa
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: app-deployment
      minReplicas: 2
      maxReplicas: 10
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 70
    

    Health Checks

    Liveness and Readiness Probes

    apiVersion: v1
    kind: Pod
    metadata:
      name: health-check-demo
    spec:
      containers:
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 8080
        
        # Liveness: Restart if fails
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        
        # Readiness: Remove from service if fails
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 2
        
        # Startup: Check on container start
        startupProbe:
          httpGet:
            path: /startup
            port: 8080
          initialDelaySeconds: 0
          periodSeconds: 10
          failureThreshold: 30
    

    Debugging

    Common Debugging Commands

    # ========== Check Pod Status ==========
    kubectl get pods
    kubectl describe pod <pod-name>
    
    # ========== View Logs ==========
    kubectl logs <pod-name>
    kubectl logs <pod-name> --previous        # Previous container logs
    
    # ========== Get Events ==========
    kubectl get events --sort-by=.metadata.creationTimestamp
    kubectl get events -n <namespace>
    
    # ========== Exec into Container ==========
    kubectl exec -it <pod-name> -- /bin/bash
    kubectl exec -it <pod-name> -- sh
    
    # ========== Port Forward ==========
    kubectl port-forward <pod-name> 8080:80
    kubectl port-forward service/<service-name> 8080:80
    
    # ========== Debug with Ephemeral Container ==========
    kubectl debug <pod-name> -it --image=busybox
    
    # ========== Check Resource Usage ==========
    kubectl top pods
    kubectl top nodes
    
    # ========== Describe Resources ==========
    kubectl describe deployment <name>
    kubectl describe service <name>
    kubectl describe node <name>
    

    Common Issues

    # ========== ImagePullBackOff ==========
    # Check image name, registry credentials
    kubectl describe pod <pod-name>
    
    # ========== CrashLoopBackOff ==========
    # Check logs for errors
    kubectl logs <pod-name>
    kubectl logs <pod-name> --previous
    
    # ========== Pending Pods ==========
    # Check node resources, scheduling constraints
    kubectl describe pod <pod-name>
    kubectl get nodes
    kubectl top nodes
    

    Best Practices

    Labels and Selectors

    metadata:
      labels:
        app: myapp
        version: v1.0.0
        environment: production
        team: backend
    

    Resource Quotas

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

    Network Policies

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend
    spec:
      podSelector:
        matchLabels:
          app: backend
      policyTypes:
      - Ingress
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: frontend
        ports:
        - protocol: TCP
          port: 8080
    

    Helm (Package Manager)

    Basic Commands

    # ========== Add Repository ==========
    helm repo add stable https://charts.helm.sh/stable
    helm repo update
    
    # ========== Search Charts ==========
    helm search repo nginx
    
    # ========== Install Chart ==========
    helm install myapp stable/nginx
    helm install myapp ./mychart -f values.yaml
    
    # ========== List Releases ==========
    helm list
    helm list -A
    
    # ========== Upgrade Release ==========
    helm upgrade myapp stable/nginx
    helm upgrade myapp ./mychart --set image.tag=v2.0
    
    # ========== Rollback ==========
    helm rollback myapp 1
    
    # ========== Uninstall ==========
    helm uninstall myapp
    

    Tips

  • Use namespaces to organize resources
  • Set resource limits to prevent resource exhaustion
  • Use health checks for reliability
  • Label everything for better organization
  • Use ConfigMaps/Secrets for configuration
  • Monitor logs and metrics regularly
  • Use Helm for complex deployments
  • Version control all YAML files
  • Test in dev before deploying to production
  • Implement autoscaling for variable loads
  • Common Patterns

    Blue-Green Deployment

    # Blue (current version)
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app-blue
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp
          version: blue
      template:
        metadata:
          labels:
            app: myapp
            version: blue
        spec:
          containers:
          - name: app
            image: myapp:v1.0
    
    ---
    # Service points to blue
    apiVersion: v1
    kind: Service
    metadata:
      name: app-service
    spec:
      selector:
        app: myapp
        version: blue  # Switch to green when ready
      ports:
      - port: 80
    

    Sidecar Pattern

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-with-sidecar
    spec:
      containers:
      # Main application
      - name: app
        image: myapp:latest
        ports:
        - containerPort: 8080
      # Sidecar (logging agent)
      - name: log-agent
        image: fluentd:latest
        volumeMounts:
        - name: logs
          mountPath: /var/log
      volumes:
      - name: logs
        emptyDir: {}
    

    Resources

  • Kubernetes Official Documentation
  • kubectl Cheat Sheet
  • Kubernetes By Example
  • Helm Documentation
  • Kubernetes Patterns
  • Topics

    KubernetesDevOpsDockerContainerCloud

    Found This Helpful?

    If you have questions or suggestions for improving these notes, I'd love to hear from you.