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)

  1. Resource Planning

    • Analyze application requirements
    • Define resource quotas and limits
    • Set up monitoring basics
  2. 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)

  1. Custom Metrics
  2. Fine-tuned Autoscaling
  3. Pod Disruption Budgets

Phase 3: Optimization (Week 5-6)

  1. Performance Testing
  2. Scaling Policies
  3. Monitoring Refinement

Maintenance Guidelines

Daily Tasks

  1. Monitor HPA/VPA events
  2. Check resource utilization
  3. Review scaling logs

Weekly Tasks

  1. Analyze scaling patterns
  2. Adjust thresholds if needed
  3. Review resource quotas

Monthly Tasks

  1. Capacity planning review
  2. Performance optimization
  3. 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

  1. Slow Scaling

    • Check HPA metrics
    • Verify metrics-server
    • Review scaling thresholds
  2. Resource Constraints

    • Monitor node capacity
    • Check resource quotas
    • Review pod requests/limits
  3. Cluster Autoscaler Issues

    • Verify node group configuration
    • Check cloud provider quotas
    • Review autoscaler logs

Resources