Table of Contents
- Why Kubernetes Matters: Beyond the Hype
- Workshop Prerequisites: What You’ll Need
- Setting Up Your Kubernetes Environment
- Hands-on Labs: From Basics to Advanced
- Real-World Kubernetes Applications: Case Studies
- Troubleshooting Common Kubernetes Issues
- Conclusion
- References
Why Kubernetes Matters: Beyond the Hype
Kubernetes has emerged as the de facto standard for container orchestration for three key reasons:
- Scalability: Automatically scale applications up or down based on demand (e.g., Black Friday traffic spikes).
- Resilience: Self-heal by replacing failed containers, ensuring high availability.
- Portability: Run applications consistently across on-premises, public clouds (AWS, GCP, Azure), and edge environments.
Today, 78% of organizations use Kubernetes in production (CNCF Survey 2023), powering everything from startups to enterprises (e.g., Netflix, Airbnb, Shopify). By mastering Kubernetes, you’ll gain the ability to deploy and manage modern applications efficiently—an in-demand skill in DevOps, SRE, and cloud engineering roles.
Workshop Prerequisites: What You’ll Need
Before diving in, ensure you have the following tools installed:
| Tool | Purpose | Installation Link |
|---|---|---|
kubectl | Kubernetes command-line tool | Kubectl Install Guide |
| Docker | Container runtime (for building images) | Docker Desktop |
| Minikube (Optional) | Local Kubernetes cluster (for development) | Minikube Setup |
| Cloud Account (Optional) | For cloud-based clusters (AWS, GCP, Azure) | AWS Free Tier, GCP Free Tier |
Basic Knowledge: Familiarity with containers (Docker), command-line interfaces (CLI), and YAML syntax will help, but we’ll explain key concepts as we go.
Setting Up Your Kubernetes Environment
We’ll cover two common setups: local development (Minikube) and cloud deployment (Amazon EKS). Choose the one that fits your needs!
3.1 Local Setup with Minikube
Minikube creates a single-node Kubernetes cluster on your laptop, ideal for learning:
- Install Minikube (follow the official guide).
- Start the cluster:
minikube start --driver=docker # Uses Docker as the runtime - Verify the cluster:
kubectl get nodes # Should show a "Ready" node named "minikube"
3.2 Cloud Setup with Amazon EKS (Example)
For production-like environments, use a managed Kubernetes service like AWS EKS:
- Install AWS CLI and configure credentials:
aws configure # Enter your AWS access key, secret key, region, etc. - Install
eksctl(EKS command-line tool):curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp sudo mv /tmp/eksctl /usr/local/bin - Create an EKS cluster (takes ~15 minutes):
eksctl create cluster --name my-eks-cluster --region us-east-1 --nodegroup-name standard-workers --node-type t3.medium --nodes 2 - Verify the cluster:
kubectl get nodes # Should show 2 "Ready" nodes
Hands-on Labs: From Basics to Advanced
Let’s dive into labs that build practical Kubernetes skills, from deploying apps to securing them!
Lab 1: Deploy a Stateless Web Application
Objective: Deploy a simple “Hello World” web app using Kubernetes Deployments and expose it via a Service.
Step 1: Create a Deployment YAML
A Deployment manages a set of identical pods (containers). Create hello-world-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-deploy
spec:
replicas: 2 # Run 2 pods
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world-container
image: gcr.io/google-samples/hello-app:1.0 # Pre-built hello-world image
ports:
- containerPort: 8080 # Port the app listens on
Step 2: Deploy the App
kubectl apply -f hello-world-deployment.yaml
Step 3: Expose the App with a Service
A Service makes the app accessible internally or externally. Create hello-world-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
spec:
selector:
app: hello-world # Matches pods with label "app: hello-world"
ports:
- protocol: TCP
port: 80 # Service port
targetPort: 8080 # Pod port
type: NodePort # Expose on a static port on each node (for local clusters)
# For cloud clusters, use type: LoadBalancer to get a public IP
Apply the Service:
kubectl apply -f hello-world-service.yaml
Step 4: Access the App
- Minikube: Get the node port and access via Minikube IP:
minikube service hello-world-service --url # Returns a URL like http://192.168.49.2:30080 - EKS: Use
kubectl get svc hello-world-serviceto get the LoadBalancer Ingress (public IP), then visithttp://<INGRESS-IP>.
Expected Output: A webpage saying “Hello, World! Version: 1.0”
Lab 2: Scaling and Load Balancing
Objective: Scale the app horizontally and test load balancing across pods.
Step 1: Manual Scaling
Scale the Deployment to 4 pods:
kubectl scale deployment hello-world-deploy --replicas=4
kubectl get pods # Should show 4 running pods
Step 2: Autoscaling with HPA
Use the Horizontal Pod Autoscaler (HPA) to scale based on CPU usage. First, enable metrics-server (required for HPA):
minikube addons enable metrics-server # For Minikube
# For EKS: Follow the [metrics-server guide](https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html)
Create an HPA:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hello-world-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: hello-world-deploy
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # Scale up if CPU > 50%
Apply the HPA:
kubectl apply -f hpa.yaml
Step 3: Test Load Balancing
Use kubectl logs <pod-name> on different pods to see request distribution. Kubernetes Services automatically load-balance traffic across pods!
Lab 3: Stateful Applications with Persistent Storage
Objective: Deploy a stateful application (MySQL) with persistent storage to retain data across pod restarts.
Key Concepts:
- StatefulSet: Manages stateful apps with stable network identities (e.g.,
mysql-0,mysql-1). - PersistentVolume (PV): Cluster-wide storage resource.
- PersistentVolumeClaim (PVC): Request for storage by a pod.
Step 1: Create a PV and PVC
# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce # Mountable by one node at a time
hostPath:
path: /data/mysql # Local path (use AWS EBS/GCP PD in production)
---
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi # Requests 5Gi from the PV
Apply:
kubectl apply -f pv.yaml -f pvc.yaml
Step 2: Deploy MySQL with StatefulSet
# mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql # Headless service for DNS records
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: "password" # Use Secrets in production!
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql # Where MySQL stores data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
Apply and verify:
kubectl apply -f mysql-statefulset.yaml
kubectl get statefulsets # Should show "READY 1/1"
Test Persistence: Delete the pod with kubectl delete pod mysql-0—the new pod will retain data thanks to the PVC!
Lab 4: Configuring and Securing Applications
Objective: Manage configuration (ConfigMaps) and sensitive data (Secrets) securely.
Step 1: ConfigMaps for Non-Sensitive Data
Store app config (e.g., environment variables) in a ConfigMap:
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_COLOR: "blue"
LOG_LEVEL: "info"
Apply:
kubectl apply -f configmap.yaml
Step 2: Secrets for Sensitive Data
Store passwords/tokens in a Secret (base64-encoded):
# Encode "mypassword" as base64
echo -n "mypassword" | base64 # Output: bXlwYXNzd29yZA==
Create secret.yaml:
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
DB_PASSWORD: bXlwYXNzd29yZA== # Encoded password
Apply:
kubectl apply -f secret.yaml
Step 3: Inject Config into a Pod
Update the hello-world-deployment.yaml to use ConfigMap and Secret:
spec:
containers:
- name: hello-world-container
image: gcr.io/google-samples/hello-app:1.0
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: DB_PASSWORD
Apply and verify:
kubectl apply -f hello-world-deployment.yaml
kubectl exec -it <pod-name> -- env | grep APP_COLOR # Should show "blue"
Lab 5: Monitoring and Logging
Objective: Monitor cluster health with Prometheus and Grafana, and aggregate logs with ELK Stack.
Step 1: Deploy Prometheus and Grafana (with Helm)
Helm is a package manager for Kubernetes. Install Helm first:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Add the Prometheus repo and install:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack
Access Grafana:
kubectl port-forward svc/prometheus-grafana 3000:80
Visit http://localhost:3000 (default credentials: admin/prom-operator). Explore dashboards like “Kubernetes Cluster Monitoring”.
Step 2: Log Aggregation with ELK Stack
Deploy Elasticsearch, Logstash, and Kibana (simplified with Helm):
helm repo add elastic https://helm.elastic.co
helm install elasticsearch elastic/elasticsearch --set replicas=1
helm install kibana elastic/kibana
Stream logs to Kibana: Use Filebeat (installed via Helm) to ship pod logs to Elasticsearch. Kibana lets you search and visualize logs!
Real-World Kubernetes Applications: Case Studies
1. Microservices at Netflix
Netflix uses Kubernetes to deploy thousands of microservices (e.g., recommendation engines, video encoding). Each service runs in its own pod, scaled independently based on demand.
2. CI/CD Pipelines at Shopify
Shopify automates deployments with Kubernetes: Code is built into containers, tested in a staging cluster, and promoted to production—all managed via GitOps tools like ArgoCD.
3. Edge Computing at John Deere
John Deere deploys Kubernetes on tractors and farm equipment to process sensor data locally, reducing latency and bandwidth costs.
Troubleshooting Common Kubernetes Issues
| Issue | Troubleshooting Steps |
|---|---|
| Pod stuck in “Pending” | Check node resources: kubectl describe pod <pod-name> → Look for “Insufficient CPU/Memory”. |
| ImagePullBackOff | Verify image name/tag: kubectl describe pod <pod-name> → Check “Events” for image pull errors. |
| Service not reachable | Ensure Service selector matches pod labels: kubectl get svc <svc-name> -o yaml vs kubectl get pods --show-labels. |
| Data loss in stateful apps | Check PVC status: kubectl get pvc → Ensure it’s “Bound”. Verify PV storage backend (e.g., AWS EBS). |
Conclusion
Kubernetes is a powerful tool for modern application deployment, but mastery comes through practice. This workshop covered core concepts—from Deployments and Services to StatefulSets and Secrets—with hands-on labs that mirror real-world scenarios.
As you continue your journey, explore advanced topics like Kubernetes Operators (for managing complex apps), Istio (service mesh), and GitOps (declarative deployments). The Kubernetes ecosystem is vast, but with the foundation built here, you’re ready to tackle production challenges!