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.