kubernetes

Make it easy - This repository contains notes and resources for learning Kubernetes.

Core Kubernetes concepts, runnable sample manifests, and cloud provider comparisons for learners and many more.

Table of Contents

Why Kubernetes?

In modern application development, containers (like those created with Docker) have become the standard way to package and run applications. They provide consistency across different environments. However, managing hundreds or thousands of containers manually across multiple machines is a significant challenge.

This is where Container Orchestration comes in. Kubernetes (often abbreviated as K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications.

It solves key challenges by providing:

What is a Pod?

A Pod is the smallest and simplest deployable unit in the Kubernetes object model. It represents a single instance of a running process in your cluster.

Key characteristics of a Pod:

Understand how Kubernetes abstracts, provisions, attaches, secures, expands, and retires storage for Pods. This section goes beyond basics: volume categories, PV/PVC lifecycle, StorageClasses, CSI, snapshots, expansion, security, and best practices.

1. Volume categories

Category Examples (type) Lifecycle Typical use
Ephemeral (per Pod) emptyDir, configMap, secret, downwardAPI, projected, ephemeral (CSI inline) Deleted when Pod gone Scratch, config injection, credentials
Node‑attached host path hostPath, local (local PV) Tied to specific node Single-node fast IO, caches (avoid for portability)
Persistent (cluster) persistentVolumeClaim (backed by cloud disks, NFS, filesystems, block, etc.) Survives Pod restarts & rescheduling (until PV reclaim) Databases, stateful apps
Special emptyDir{.medium=Memory}, tmpfs, block mode PVs Pod lifetime / PV lifetime High-speed temp, raw block devices

Notes:

2. PV (PersistentVolume) & PVC (PersistentVolumeClaim)

3. Access modes (capability depends on backend)

4. Provisioning models

Static provisioning:

Dynamic provisioning (preferred):

5. StorageClass essentials

Fields: provisioner, parameters, reclaimPolicy (Delete Retain), allowVolumeExpansion, volumeBindingMode (Immediate WaitForFirstConsumer), mountOptions.

Example (AWS gp3 conceptually; adapt to your cloud):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
    name: fast-retain
provisioner: ebs.csi.aws.com          # cloud / CSI provisioner
parameters:
    type: gp3
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

6. Reclaim policies

7. CSI (Container Storage Interface)

Modern storage drivers are CSI-based (cloud disks, EFS/Azure Files/NFS, SAN vendors). Benefits: pluggable, features (snapshots, volume cloning, expansion, raw block, ephemeral inline).

Inspect installed drivers:

kubectl get csidrivers

8. Snapshots & cloning (if driver supports)

Example snapshot objects (conceptual):

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
    name: csi-snapclass
driver: ebs.csi.aws.com
deletionPolicy: Delete
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
    name: db-snap-2025-08-21
spec:
    volumeSnapshotClassName: csi-snapclass
    source:
        persistentVolumeClaimName: db-data

9. Security & access

10. Example: Static PV + PVC + Pod

apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv-local-1
spec:
    capacity:
        storage: 5Gi
    accessModes:
        - ReadWriteOnce
    storageClassName: ""           # Ensures it only binds to PVCs without a class
    persistentVolumeReclaimPolicy: Retain
    hostPath:
        path: /mnt/data/pv-local-1
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-claim-1
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 5Gi
    storageClassName: ""            # Match the PV above
---
apiVersion: v1
kind: Pod
metadata:
    name: app-with-pv
spec:
    containers:
    - name: web
        image: nginx:stable
        volumeMounts:
        - name: app-storage
            mountPath: /usr/share/nginx/html
    volumes:
    - name: app-storage
        persistentVolumeClaim:
            claimName: pvc-claim-1

11. Example: Dynamic provisioning Deployment

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-dynamic-1
spec:
    storageClassName: standard
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
    name: web-dyn
spec:
    replicas: 1
    selector:
        matchLabels:
            app: web-dyn
    template:
        metadata:
            labels:
                app: web-dyn
        spec:
            containers:
            - name: nginx
                image: nginx:stable
                volumeMounts:
                - name: web-data
                    mountPath: /usr/share/nginx/html
            volumes:
            - name: web-data
                persistentVolumeClaim:
                    claimName: pvc-dynamic-1

12. Example: Volume expansion (after initial apply)

Edit PVC size (if allowVolumeExpansion: true):

kubectl patch pvc pvc-dynamic-1 -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
kubectl get pvc pvc-dynamic-1

13. Quick commands

# List storage classes & drivers
kubectl get storageclass
kubectl get csidrivers

# Describe PVC binding events
kubectl describe pvc pvc-dynamic-1

# Show PV lifecycle
kubectl get pv

# Snapshot list (if CRDs installed)
kubectl get volumesnapshotclasses 2>/dev/null || echo 'snapshot CRDs not installed'

14. Best practices & anti‑patterns

Summary:


  1. Persistent Volumes and Persistent Volume Claims
  1. Access modes
  1. Static vs Dynamic Storage provisioning
  1. Reclaim policies
  1. StorageClass
  1. Examples — provisioning a Pod with persistent storage

Below are two compact examples:

# --- persistent-volume (admin)
apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv-local-1
spec:
    capacity:
        storage: 5Gi
    accessModes:
        - ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    hostPath:
        path: /mnt/data/pv-local-1

# --- persistent-volume-claim (user)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-claim-1
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 5Gi

# --- pod that uses the PVC
apiVersion: v1
kind: Pod
metadata:
    name: app-with-pv
spec:
    containers:
    - name: web
        image: nginx:stable
        volumeMounts:
        - mountPath: /usr/share/nginx/html
            name: app-storage
    volumes:
    - name: app-storage
        persistentVolumeClaim:
            claimName: pvc-claim-1
# --- persistent-volume-claim (user requests dynamic provisioning)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-dynamic-1
spec:
    storageClassName: standard
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 10Gi

# --- deployment that uses the dynamically provisioned PVC
apiVersion: apps/v1
kind: Deployment
metadata:
    name: web-dyn
spec:
    replicas: 1
    selector:
        matchLabels:
            app: web-dyn
    template:
        metadata:
            labels:
                app: web-dyn
        spec:
            containers:
            - name: nginx
                image: nginx:stable
                volumeMounts:
                - name: web-data
                    mountPath: /usr/share/nginx/html
            volumes:
            - name: web-data
                persistentVolumeClaim:
                    claimName: pvc-dynamic-1

Summary

Quick commands

# See storage classes
kubectl get storageclass

# Create PVC and check binding
kubectl apply -f pvc-dynamic-1.yaml
kubectl get pvc pvc-dynamic-1
kubectl describe pvc pvc-dynamic-1

Cloud Provider Comparison

Moved to a dedicated document: GKE vs AKS vs EKS to keep this introduction concise.

Express Your Support If this repo has been beneficial, show your appreciation with a ⭐