Sobes.tech
Middle+

How to implement auto-scaling in Docker Swarm, and is it possible?

sobes.tech AI

Answer from AI

Yes, autoscaling in Docker Swarm is possible. It is implemented through service updates to change the number of replicas based on metrics or events, as well as with external tools.

Main approaches:

  1. Built-in capabilities (Declarative Service Scaling):

    • Manually changing the number of replicas using docker service scale.
    • Automating this process with scripts or external monitoring tools.
  2. External tools/integrations:

    • Monitoring tools (Prometheus, Grafana) for collecting metrics (CPU, memory, network activity).
    • Scripts or specialized autoscalers (e.g., Docker Swarm Autoscaler) for making scaling decisions based on these metrics.
    • Integration with cloud providers offering their own autoscaling mechanisms managing Swarm instances.

The autoscaling process using external tools typically includes:

  • Monitoring: Collecting metrics about service load.
  • Analysis: Comparing current metrics with set thresholds.
  • Action: Calling docker service scale or updating the service to increase/decrease the number of replicas.

Example of a script for basic CPU load-based autoscaling (pseudocode):

# !/bin/bash

SERVICE_NAME="my_web_service"
THRESHOLD_CPU=70  # CPU percentage
MAX_REPLICAS=10
MIN_REPLICAS=2
INTERVAL=60 # seconds

while true; do
  # Get average CPU usage for the service
  AVG_CPU=$(docker stats --no-stream --format "{{.CPUPerc}}" $(docker service ps -q $SERVICE_NAME) 2>/dev/null | sed 's/%//g' | awk '{ sum += $1 } END { print sum / NR }')

  CURRENT_REPLICAS=$(docker service inspect $SERVICE_NAME --format "{{.Spec.Replicas}}")

  if (( $(echo "$AVG_CPU > $THRESHOLD_CPU" | bc -l) )) && [ "$CURRENT_REPLICAS" -lt "$MAX_REPLICAS" ]; then
    NEW_REPLICAS=$((CURRENT_REPLICAS + 1))
    echo "High CPU usage ($AVG_CPU%), scaling service $SERVICE_NAME to $NEW_REPLICAS replicas"
    docker service scale $SERVICE_NAME=$NEW_REPLICAS
  elif (( $(echo "$AVG_CPU < ($THRESHOLD_CPU * 0.8)" | bc -l) )) && [ "$CURRENT_REPLICAS" -gt "$MIN_REPLICAS" ]; then
    NEW_REPLICAS=$((CURRENT_REPLICAS - 1))
    echo "Low CPU usage ($AVG_CPU%), scaling service $SERVICE_NAME to $NEW_REPLICAS replicas"
    docker service scale $SERVICE_NAME=$NEW_REPLICAS
  else
    echo "CPU usage ($AVG_CPU%) within limits for service $SERVICE_NAME ($CURRENT_REPLICAS replicas)"
  fi

  sleep $INTERVAL
done

Docker Swarm does not have a built-in horizontal autoscaler like Kubernetes' Horizontal Pod Autoscaler (HPA), but its functionality can be achieved using the methods mentioned above.