Kubernetes From Zero To Hero

Kubernetes From Zero To Hero

Reading time1 min
#Kubernetes#Cloud#DevOps#Containerization#ClusterManagement#K8s

Mastering Kubernetes: Zero to Hero via Practical Cluster Management

Theory seldom survives contact with production. Kubernetes, for all its orchestration promises, quickly exposes knowledge gaps when a deployment hits real-world constraints: pod evictions, resource starvation, failed upgrades, or a thundering herd of ephemeral workloads. Tool familiarity and hands-on troubleshooting aren’t optional—they’re critical.

Below: a pragmatic journey through core Kubernetes operations. Skip the “hello world” comfort zone. Aim for command fluency, awareness of trade-offs, and lessons only chaos can teach.


Cluster Bootstrapping: Local vs. Cloud

Environment selection shapes every decision. Cost, latency, and cluster topology all differ between laptop and cloud.

Local: Kind (Kubernetes IN Docker)

Rapid iteration is impossible when deploying to the cloud for every test. Kind (kind.sigs.k8s.io) spins up multi-node clusters locally using Docker containers. Suitable for prototyping, not for simulating node-level hardware failures.

curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind && mv ./kind /usr/local/bin/kind

cat <<EOF | kind create cluster --name dev-sandbox --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
EOF

kubectl get nodes -o wide

Known issue: Kind clusters share the host Docker daemon; filesystem mounts are not persistent between cluster respins.

Cloud: Managed Control Planes

Production clusters favor managed Kubernetes—Amazon EKS, Google GKE, or Azure AKS. API surfaces look similar but operational caveats abound:

  • Versions and feature parity lag upstream (kubectl version can mismatch expected feature sets)
  • Network overlays vary (Calico, Cilium, or cloud-native CNI)
  • Control-plane SLA is external; worker nodes are the engineer’s responsibility.

Quickstart (GKE, default settings):

gcloud container clusters create demo-prod \
  --zone=us-central1-b --num-nodes=3 --cluster-version=1.27
gcloud container clusters get-credentials demo-prod --zone=us-central1-b

kubectl get nodes

Note: GKE enables automatic upgrades by default; production users often disable this to control maintenance windows.


Deploying Applications: Beyond Sample Manifests

A cluster without workloads is irrelevant. The real test: a stateful or stateless application, running at scale, under real resource pressure.

Example: NGINX Deployment (3 replicas)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webserver
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.3-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "200m"
            memory: "64Mi"
          limits:
            cpu: "500m"
            memory: "128Mi"

No production YAML skips explicit resource requests/limits. Starved containers beg for CPU, and noisy neighbors on shared nodes can cause transient failures.

kubectl apply -f deployment.yaml
kubectl rollout status deployment/webserver
kubectl get pods -l app=webserver -o wide

Expose the deployment:

  • Cloud: type: LoadBalancer
  • Local/Kind: type: NodePort (That means you’ll use a cluster node’s IP + port).
apiVersion: v1
kind: Service
metadata:
  name: webserver-svc
spec:
  type: LoadBalancer
  selector:
    app: webserver
  ports:
    - name: http
      port: 80
      targetPort: 80

Real-World Operations: Resources, Auto-Scaling, Saturation

Under resource pressure, Kubernetes schedules ruthlessly. Requests/limits dictate both placement and throttling. Neglected, they produce silent performance issues.

Pod Spec Resource Block:

resources:
  requests:
    cpu: "250m"
    memory: "64Mi"
  limits:
    cpu: "500m"
    memory: "128Mi"

Pods lacking requests may be unschedulable during node pressure. OOMKilled events commonly surface due to ignored memory limits:

state:    Terminated
reason:   OOMKilled
exit code:137

Horizontal Pod Autoscaler (HPA):

kubectl autoscale deployment webserver \
  --cpu-percent=60 --min=2 --max=6

Test autoscaling by load (requires metrics-server installed):

hey -z 30s -c 30 http://<service-ip>
kubectl get hpa webserver

Note: HPA won’t trigger without metrics-server running; missing CRDs or RBAC misconfigurations frequently block autoscaling.


Failure Injection: Pods and Nodes

How robust is your deployment—really? Disruptions simulate what the cloud delivers regularly.

  • Delete pods:
    kubectl delete pod <pod_name>
    
    The ReplicaSet restores count automatically.
  • Node-level disruption:
    kubectl cordon <node_name>
    kubectl drain <node_name> --ignore-daemonsets --delete-emptydir-data
    
    Cordon marks the node unschedulable; drain evicts pods, respecting PodDisruptionBudgets.
    Trade-off: Running stateful workloads on nodes with attached disks may cause volume detach/reattach delays.

PodDisruptionBudget Example

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

This avoids all instances being drained simultaneously in rolling node upgrades.


Controlled Upgrades: Minimize Downtime, Maximize Control

Upgrade strategy distinguishes test from production.

  • Never upgrade directly in production. Mirror the upgrade on a staging environment—identifying breaking CRDs or deprecated APIs early.
  • Control-plane nodes first, workers staggered next; cordon/drain to move workloads off nodes safely.
  • Monitor via kubectl get events, Prometheus, and application-specific dashboards.

On-prem, kubeadm managed clusters:

kubeadm upgrade plan        # review next available versions
kubeadm upgrade apply v1.28.3
apt-get upgrade kubelet kubectl
systemctl restart kubelet
kubectl get nodes   # Confirm all nodes report Ready after restart

Managed cloud:

  • GKE: gcloud container clusters upgrade
  • EKS: eksctl upgrade cluster ...
    Both allow node pool upgrade separately from control-plane, allowing for phased cutovers.

Gotcha: Certain managed upgrades impose restarts on daemonsets, breaking ephemeral logs if not backed by remote storage.


Level Up: Network Policy, State, and Security

Cluster operation does not end at deployment health. Consider:

  • NetworkPolicy: Without it, every pod can talk to every other pod. Implement restrictive policies. Calico and Cilium support advanced selectors.
  • PersistentVolume and StatefulSet: For stateful applications, tie pods to storage lifecycles. Beware that PVC reclaimPolicy can accidentally delete production data on namespace teardown.
  • RBAC: Least privilege model. Don’t run applications with cluster-admin, ever.
  • Monitoring: Integrate Prometheus OP charts; ship logs with Fluentd or Loki. Relying on kubectl logs alone hides issues that vanish on pod restart.

Non-obvious tip:
Enabling audit-log on the API server (--audit-log-path=/var/log/k8s-audit.log) uncovers access patterns, misbehaving scripts, and security gaps invisible via normal metrics.


Epilogue

Kubernetes mastery is earned through command-line friction, error logs at 2 a.m., and a sea of YAML. There’s no shortcut: standing up clusters, debugging failures, tuning autoscalers, and surviving upgrades under a tight SLO is the curriculum.
Even so, completeness is as much about knowing where the cracks are as having everything perfectly parameterized.

Start with Kind. Simulate edge cases. Graduate to managed cloud. Always question defaults.


Curated, real-world Kubernetes and DevOps deep-dives released regularly. Field notes—not just walkthroughs.
Subscribe or request a topic—because next week GKE will “helpfully” upgrade itself, and it pays to be ready.