Kubernetes Basics
Container orchestration with Kubernetes - pods, services, deployments, and scaling.
5 min read
What is Kubernetes?#
Kubernetes (K8s) automates deployment, scaling, and management of containerized applications:
┌─────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Node │ │ Node │ │ Node │ │
│ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │
│ │ │ Pod │ │ │ │ Pod │ │ │ │ Pod │ │ │
│ │ └─────┘ │ │ └─────┘ │ │ └─────┘ │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────┘
When to Use Kubernetes#
| Use K8s When | Avoid K8s When |
|---|---|
| Multiple services | Single app |
| Need auto-scaling | Low traffic |
| High availability required | Small team |
| Complex deployments | Simple deployment |
| Microservices | Monolith |
Key Concepts#
| Concept | Description |
|---|---|
| Pod | Smallest deployable unit (one or more containers) |
| Deployment | Manages pod replicas and updates |
| Service | Network endpoint to access pods |
| ConfigMap | Configuration data |
| Secret | Sensitive data (passwords, keys) |
| Ingress | External HTTP/HTTPS routing |
Local Development#
bash
# Install minikube (local K8s)
brew install minikube
# Start cluster
minikube start
# Enable addons
minikube addons enable ingress
minikube addons enable metrics-server
# Access dashboard
minikube dashboard
Pod#
Smallest deployable unit:
yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
bash
kubectl apply -f pod.yaml
kubectl get pods
kubectl logs my-app
kubectl exec -it my-app -- /bin/sh
Deployment#
Manages multiple pod replicas:
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v1.0.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
bash
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl rollout status deployment/my-app
kubectl scale deployment/my-app --replicas=5
Service#
Expose pods to network:
yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP # Internal only
---
# LoadBalancer for external access (cloud)
apiVersion: v1
kind: Service
metadata:
name: my-app-lb
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
Service Types#
yaml
# ClusterIP - Internal only (default)
type: ClusterIP
# NodePort - Expose on each node's IP
type: NodePort
# LoadBalancer - Cloud load balancer
type: LoadBalancer
# ExternalName - DNS alias
type: ExternalName
ConfigMap & Secrets#
yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
NODE_ENV: "production"
LOG_LEVEL: "info"
API_URL: "https://api.example.com"
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
database-url: "postgresql://user:pass@host:5432/db"
jwt-secret: "super-secret-key"
Use in deployment:
yaml
spec:
containers:
- name: app
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
Ingress#
HTTP routing to services:
yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-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: my-app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
tls:
- hosts:
- myapp.example.com
secretName: tls-secret
Horizontal Pod Autoscaler#
Auto-scale based on metrics:
yaml
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Complete Application#
yaml
# k8s/app.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
NODE_ENV: "production"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DATABASE_URL: "postgresql://..."
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: myregistry/my-app:v1.0.0
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
---
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Common Commands#
bash
# Apply configuration
kubectl apply -f k8s/
# Get resources
kubectl get pods
kubectl get services
kubectl get deployments
kubectl get ingress
# Describe resource
kubectl describe pod my-app-xxx
# Logs
kubectl logs my-app-xxx
kubectl logs -f my-app-xxx # Follow
# Execute in pod
kubectl exec -it my-app-xxx -- /bin/sh
# Port forward (local testing)
kubectl port-forward service/my-app-service 8080:80
# Rolling update
kubectl set image deployment/my-app app=my-app:v2.0.0
kubectl rollout status deployment/my-app
kubectl rollout undo deployment/my-app # Rollback
Key Takeaways#
- Start with Deployments - Not bare pods
- Use health probes - Readiness and liveness
- Set resource limits - Prevent runaway containers
- Use ConfigMaps/Secrets - Externalize configuration
- Consider managed K8s - GKE, EKS, AKS for production
Continue Learning
Ready to level up your skills?
Explore more guides and tutorials to deepen your understanding and become a better developer.