Introduction to Kubernetes
Kubernetes (K8s) is a container orchestration platform that automates deployment, scaling, and management of containerized applications across clusters of machines.
Core Kubernetes Concepts
Pods - Smallest Deployable Units
yaml
# pod.yaml - Basic Pod configuration
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Deployments - Managing Pod Replicas
yaml
# deployment.yaml - Deployment configuration
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:1.21
ports:
- containerPort: 80
env:
- name: ENV
value: "production"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
Services - Exposing Applications
yaml
# service.yaml - Service configuration
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer # ClusterIP, NodePort, LoadBalancer
Complete Web Application Example
Frontend Deployment
yaml
# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
labels:
tier: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
tier: frontend
spec:
containers:
- name: react-app
image: myregistry/frontend:v1.0.0
ports:
- containerPort: 3000
env:
- name: REACT_APP_API_URL
value: "http://backend-service:8000"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
---
# Frontend Service
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
Backend Deployment
yaml
# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
labels:
tier: backend
spec:
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
tier: backend
spec:
containers:
- name: api-server
image: myregistry/backend:v1.0.0
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
- name: REDIS_URL
value: "redis://redis-service:6379"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
---
# Backend Service
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- port: 8000
targetPort: 8000
type: ClusterIP
Database Deployment
yaml
# postgres-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: POSTGRES_DB
value: "myapp"
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
---
# Database Service
apiVersion: v1
kind: Service
metadata:
name: postgres-service
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
type: ClusterIP
ConfigMaps and Secrets
ConfigMap for Configuration
yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
debug=true
log_level=info
max_connections=100
nginx.conf: |
server {
listen 80;
location / {
proxy_pass http://backend-service:8000;
}
}
Secret for Sensitive Data
yaml
# secret.yaml apiVersion: v1 kind: Secret metadata: name: db-secret type: Opaque data: username: dXNlcg== # base64 encoded 'user' password: cGFzcw== # base64 encoded 'pass' url: cG9zdGdyZXNxbDovL3VzZXI6cGFzc0Bwb3N0Z3Jlcy1zZXJ2aWNlOjU0MzIvbXlhcHA=
Persistent Storage
yaml
# persistent-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data/postgres
---
# Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Ingress for External Access
yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8000
Essential kubectl Commands
bash
# Cluster information kubectl cluster-info kubectl get nodes kubectl describe node node-name # Working with resources kubectl get pods kubectl get deployments kubectl get services kubectl get all # Detailed information kubectl describe pod pod-name kubectl describe deployment deployment-name # Logs and debugging kubectl logs pod-name kubectl logs -f deployment/backend # Follow logs kubectl exec -it pod-name -- /bin/bash # Apply configurations kubectl apply -f deployment.yaml kubectl apply -f . # Apply all YAML files in directory # Delete resources kubectl delete pod pod-name kubectl delete deployment deployment-name kubectl delete -f deployment.yaml # Scale deployments kubectl scale deployment nginx-deployment --replicas=5 # Port forwarding (for testing) kubectl port-forward service/backend-service 8080:8000
Deployment Strategies
Rolling Update
yaml
# Rolling update strategy (default)
apiVersion: apps/v1
kind: Deployment
metadata:
name: rolling-update-app
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Max extra pods during update
maxUnavailable: 1 # Max unavailable pods during update
template:
# ... pod template
Blue-Green Deployment
yaml
# Blue deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
labels:
version: 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.0
---
# Green deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
labels:
version: green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: myapp:v2.0.0
---
# Service switches between blue and green
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
version: blue # Change to 'green' for deployment
ports:
- port: 80
targetPort: 8000
Monitoring and Health Checks
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: healthy-app
spec:
replicas: 3
selector:
matchLabels:
app: healthy-app
template:
metadata:
labels:
app: healthy-app
spec:
containers:
- name: app
image: myapp:latest
ports:
- containerPort: 8000
# Liveness probe - restart if fails
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# Readiness probe - remove from service if fails
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# Startup probe - for slow starting applications
startupProbe:
httpGet:
path: /startup
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 10
Namespace Organization
yaml
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
env: production
---
# Deploy to specific namespace
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
namespace: production # Specify namespace
spec:
# ... deployment spec
Resource Management
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: resource-managed-app
spec:
replicas: 3
selector:
matchLabels:
app: resource-app
template:
metadata:
labels:
app: resource-app
spec:
containers:
- name: app
image: myapp:latest
resources:
requests: # Guaranteed resources
memory: "256Mi"
cpu: "250m"
limits: # Maximum resources
memory: "512Mi"
cpu: "500m"
env:
- name: JAVA_OPTS
value: "-Xmx400m -XX:+UseContainerSupport"
Getting Started Commands
bash
# Install kubectl (varies by OS) # macOS: brew install kubectl # Linux: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # Start local cluster (minikube) minikube start kubectl config use-context minikube # Deploy application kubectl apply -f deployment.yaml kubectl apply -f service.yaml # Check status kubectl get pods -w # Watch pods kubectl get services # Access application kubectl port-forward service/frontend-service 8080:80 # Visit http://localhost:8080 # Clean up kubectl delete deployment,service,configmap,secret --all minikube stop