Kubernetes Scalability Best Practices - Building Resilient Applications
Learn proven strategies for scaling Kubernetes applications effectively. From resource management to autoscaling, discover how to build and maintain highly available and performant clusters.
Introduction
Kubernetes scalability is crucial for maintaining application performance and reliability as your workload grows. This comprehensive guide covers proven strategies, practical implementations, and real-world examples for building highly scalable Kubernetes clusters.
Understanding Scalability Components
1. Horizontal Pod Autoscaling (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: 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: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 60
2. Vertical Pod Autoscaling (VPA)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: '*'
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 1
memory: 1Gi
controlledResources: ["cpu", "memory"]
3. Cluster Autoscaling
apiVersion: autoscaling.k8s.io/v1
kind: ClusterAutoscaler
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
scaleDown:
enabled: true
delayAfterAdd: 10m
delayAfterDelete: 10s
delayAfterFailure: 3m
scaleUp:
enabled: true
maxNodesTotal: 100
nodeGroups:
- name: default-node-group
minSize: 1
maxSize: 10
Implementation Best Practices
1. Resource Management
Resource Quotas
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
Limit Ranges
apiVersion: v1
kind: LimitRange
metadata:
name: resource-limits
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 200m
memory: 256Mi
max:
cpu: 2
memory: 2Gi
min:
cpu: 100m
memory: 128Mi
2. Pod Disruption Budgets
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: my-app
3. Node Affinity and Anti-Affinity
apiVersion: apps/v1
kind: Deployment
metadata:
name: high-availability-app
spec:
replicas: 3
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- high-performance
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- high-availability-app
topologyKey: kubernetes.io/hostname
Monitoring and Metrics
1. Prometheus Configuration
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-monitor
spec:
selector:
matchLabels:
app: my-app
endpoints:
- port: metrics
interval: 15s
path: /metrics
2. Custom Metrics Adapter
apiVersion: custom.metrics.k8s.io/v1beta1
kind: MetricRule
metadata:
name: queue-metrics
spec:
metricsQuery: sum(rate(queue_size[2m]))
resourceQuery:
resource: pods
groupBy:
- metadata.namespace
- metadata.name
Implementation Roadmap
Phase 1: Foundation (Week 1-2)
-
Resource Planning
- Analyze application requirements
- Define resource quotas and limits
- Set up monitoring basics
-
Basic Autoscaling
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: basic-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
Phase 2: Advanced Configuration (Week 3-4)
- Custom Metrics
- Fine-tuned Autoscaling
- Pod Disruption Budgets
Phase 3: Optimization (Week 5-6)
- Performance Testing
- Scaling Policies
- Monitoring Refinement
Maintenance Guidelines
Daily Tasks
- Monitor HPA/VPA events
- Check resource utilization
- Review scaling logs
Weekly Tasks
- Analyze scaling patterns
- Adjust thresholds if needed
- Review resource quotas
Monthly Tasks
- Capacity planning review
- Performance optimization
- Cost analysis
Tools and Integration
1. Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
2. Kube State Metrics
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: kube-system
spec:
selector:
matchLabels:
app: kube-state-metrics
replicas: 1
template:
metadata:
labels:
app: kube-state-metrics
spec:
containers:
- name: kube-state-metrics
image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.9.2
ports:
- containerPort: 8080
name: metrics
CNCF Tools for Scalability
CNCF Graduated Tools
1. Kubernetes Metrics Server
Core metrics pipeline for autoscaling:
# Install Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Verify installation
kubectl get deployment metrics-server -n kube-system
# Check node metrics
kubectl top nodes
# Check pod metrics
kubectl top pods --all-namespaces
2. Prometheus (CNCF Graduated)
For comprehensive monitoring and metrics:
# Install Prometheus Stack
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
# Port forward Prometheus
kubectl port-forward -n monitoring svc/prometheus-operated 9090:9090
# Port forward Grafana
kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
# Check HPA metrics
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
3. etcd (CNCF Graduated)
Distributed key-value store for Kubernetes:
# Check etcd health
kubectl exec -it -n kube-system etcd-master -- etcdctl endpoint health
# Monitor etcd metrics
kubectl exec -it -n kube-system etcd-master -- etcdctl endpoint status -w table
# Backup etcd
ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
CNCF Incubating Tools
1. Linkerd (CNCF Graduated)
Service mesh for traffic management:
# Install Linkerd CLI
curl -sL https://run.linkerd.io/install | sh
# Check prerequisites
linkerd check --pre
# Install Linkerd
linkerd install | kubectl apply -f -
# Enable mTLS
linkerd inject deployment/my-app | kubectl apply -f -
# Monitor service metrics
linkerd stat deployments
2. Thanos (CNCF Incubating)
Highly available Prometheus setup:
# Install Thanos
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install thanos bitnami/thanos \
--namespace monitoring \
--create-namespace
# Query metrics
thanos query \
--http-address=0.0.0.0:9090 \
--store=thanos-sidecar-0:10901
# Check store status
thanos tools bucket web \
--objstore.config-file=bucket_config.yaml
Scalability Management Commands
1. Horizontal Pod Autoscaling
# Create HPA
kubectl autoscale deployment my-app --cpu-percent=80 --min=2 --max=10
# Check HPA status
kubectl get hpa
kubectl describe hpa my-app
# Monitor HPA events
kubectl get events --field-selector reason=ScalingReplicaSet
# Custom metrics HPA
kubectl apply -f - <<EOF
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: custom-metrics-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_requests
target:
type: AverageValue
averageValue: 1k
EOF
2. Vertical Pod Autoscaling
# Install VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
# Create VPA
kubectl apply -f - <<EOF
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Auto"
EOF
# Check VPA recommendations
kubectl describe vpa my-app-vpa
3. Cluster Autoscaling
# Enable Cluster Autoscaler (AWS)
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
containers:
- command:
- ./cluster-autoscaler
- --cloud-provider=aws
- --nodes=2:10:my-node-group
EOF
# Monitor autoscaling
kubectl logs -f deployment/cluster-autoscaler -n kube-system
# Check autoscaling status
kubectl get nodes -w
Performance Testing Commands
# Load testing with hey
hey -n 1000 -c 100 http://my-app.default.svc.cluster.local
# Check pod resource usage
kubectl top pods --containers=true
# Monitor node resources
kubectl describe nodes | grep -A 5 "Allocated resources"
# Check API server latency
kubectl get --raw /metrics | grep apiserver_request_latencies_summary
Scalability Audit Commands
# Check cluster capacity
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, capacity: .status.capacity}'
# List resource quotas
kubectl get resourcequotas --all-namespaces
# Check pod distribution
kubectl get pods -o wide --all-namespaces
# Monitor scaling events
kubectl get events --field-selector reason=ScalingReplicaSet
# Check service endpoints
kubectl get endpoints --all-namespaces
Resource Management Commands
# Set resource requests/limits
kubectl set resources deployment my-app \
--requests=cpu=200m,memory=512Mi \
--limits=cpu=500m,memory=1Gi
# Check resource allocation
kubectl describe nodes | grep -A 8 "Allocated resources"
# Monitor resource usage
kubectl top nodes
kubectl top pods --all-namespaces
# Check pod QoS class
kubectl get pods -o custom-columns=NAME:.metadata.name,QoS:.status.qosClass
Network Performance Commands
# Test network connectivity
kubectl run nettest --image=nicolaka/netshoot --rm -it -- bash
# Inside pod:
# mtr kubernetes.default.svc.cluster.local
# iperf3 -s
# Monitor network metrics
kubectl exec -it <pod-name> -- netstat -s
# Check DNS resolution time
kubectl run dnstest --image=busybox --rm -it -- time nslookup kubernetes.default
# Monitor service latency
kubectl exec -it <pod-name> -- curl -w "@curl-format.txt" -o /dev/null -s http://service-name
Best Practices for Different Workloads
1. Stateless Applications
apiVersion: apps/v1
kind: Deployment
metadata:
name: stateless-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
2. Stateful Applications
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: stateful-app
spec:
serviceName: stateful-service
replicas: 3
updateStrategy:
type: RollingUpdate
podManagementPolicy: Parallel
3. Batch Jobs
apiVersion: batch/v1
kind: Job
metadata:
name: batch-job
spec:
parallelism: 3
completions: 10
backoffLimit: 4
Troubleshooting Guide
Common Issues and Solutions
-
Slow Scaling
- Check HPA metrics
- Verify metrics-server
- Review scaling thresholds
-
Resource Constraints
- Monitor node capacity
- Check resource quotas
- Review pod requests/limits
-
Cluster Autoscaler Issues
- Verify node group configuration
- Check cloud provider quotas
- Review autoscaler logs