Skip to content

Docker_swarm

Chapter 11: Docker Swarm - Container Orchestration

Section titled “Chapter 11: Docker Swarm - Container Orchestration”
  1. Introduction to Container Orchestration
  2. What is Docker Swarm?
  3. Why Docker Swarm?
  4. When to Use Docker Swarm
  5. Docker Swarm Architecture
  6. Setting Up Docker Swarm
  7. Swarm Services and Stacks
  8. Scaling and Load Balancing
  9. Rolling Updates
  10. Swarm Networking
  11. Swarm Security
  12. Best Practices
  13. Hands-on Lab

Before diving into Docker Swarm, let’s understand why we need container orchestration in the first place.

Imagine you have a production application running on Docker containers. As your application grows, you face several challenges:

┌─────────────────────────────────────────────────────────────────────────────┐
│ SCALING CHALLENGES WITHOUT ORCHESTRATION │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Container│ │ Container│ │ Container│ Multiple containers │
│ │ App │ │ App │ │ App │ need management │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └─────────────┼─────────────┘ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Manual Work │ │
│ │ - Health check│ │
│ │ - Restart │ │
│ │ - Scaling │ │
│ │ - Networking │ │
│ │ - Updates │ │
│ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Container orchestration automates the deployment, management, scaling, and networking of containers. It solves these problems:

  1. Automatic Healing - Restart failed containers
  2. Scaling - Scale up/down based on demand
  3. Load Balancing - Distribute traffic across containers
  4. Service Discovery - Find services automatically
  5. Rolling Updates - Update without downtime
  6. Configuration Management - Manage configurations centrally
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTAINER ORCHESTRATION BENEFITS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ORCHESTRATION LAYER │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Health │ │ Auto │ │ Load │ │ │
│ │ │ Monitoring│ │ Scaling │ │ Balancing │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Service │ │ Rolling │ │ Secret │ │ │
│ │ │ Discovery │ │ Updates │ │ Management │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ CONTAINER CLUSTER │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Node 1 │ │Node 2 │ │Node 3 │ │Node 4 │ │ │
│ │ │┌───────┐│ │┌───────┐│ │┌───────┐│ │┌───────┐│ │ │
│ │ ││Container││ ││Container││ ││Container││ ││Container││ │ │
│ │ │└───────┘│ │└───────┘│ │└───────┘│ │└───────┘│ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Docker Swarm is Docker’s native container orchestration platform. It turns a group of Docker hosts into a single, virtual Docker engine.

  • Swarm: A cluster of Docker hosts organized into a swarm mode
  • Node: A Docker instance participating in the swarm
  • Manager Node: Controls swarm operations and task distribution
  • Worker Node: Executes tasks (containers) assigned by managers
  • Service: Definition of tasks to execute on worker nodes
  • Task: A single container running on a worker node
  • Stack: Collection of services that make up an application

Many beginners wonder whether to use Docker Swarm or Kubernetes. Here’s a comparison:

┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM vs KUBERNETES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Feature │ Docker Swarm │ Kubernetes │
│ ─────────────────────┼─────────────────┼───────────────────────────── │
│ Complexity │ Lower │ Higher │
│ Learning Curve │ Gentle │ Steep │
│ Setup │ Simple │ Complex │
│ Scaling │ Easy │ Powerful │
│ Enterprise Ready │ Good │ Excellent │
│ Cloud Native │ Yes │ Yes │
│ Self-Healing │ Yes │ Yes │
│ Rolling Updates │ Yes │ Yes │
│ Custom Resources │ Limited │ Extensive │
│ Community │ Docker │ CNCF │
│ │
│ Best For: │
│ ───────────────────────────────────────────────────────────────────── │
│ • Docker Swarm: Small teams, simple needs, Docker-centric │
│ • Kubernetes: Large scale, complex deployments, multi-cloud │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

  1. Native Docker Integration

    • No additional installation required
    • Uses familiar Docker CLI commands
    • Seamless integration with Docker Compose
  2. Simplicity

    • Easy to set up and configure
    • Low learning curve
    • Perfect for smaller teams
  3. Lightweight

    • Less resource overhead
    • Faster startup times
    • Ideal for limited resources
  4. Built-in Features

    • Load balancing
    • Service discovery
    • Rolling updates
    • Scaling
    • Security (TLS)
┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM ADVANTAGES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ SIMPLE SETUP │ │ NATIVE DOCKER │ │ LIGHTWEIGHT │ │
│ │ │ │ │ │ │ │
│ │ 5 min to get │ │ Same CLI, same │ │ ~50MB overhead │ │
│ │ production │ │ API, seamless │ │ No extra daemons│ │
│ │ ready │ │ integration │ │ │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ ENTERPRISE │ │ BUILT-IN │ │ SECURE BY │ │
│ │ READY │ │ FEATURES │ │ DEFAULT │ │
│ │ │ │ │ │ │ │
│ │ TLS, RBAC, │ │ LB, SD, Rolling │ │ Mutual TLS, │ │
│ │ Secrets, │ │ Updates, Scaling│ │ Encryption │ │
│ │ Secrets, │ │ │ │ │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

  1. Small to Medium Deployments

    • 1-100 containers
    • Single team or small DevOps team
  2. Rapid Prototyping

    • Quick deployment needed
    • Fast iteration cycles
  3. Microservices with Docker

    • Multiple small services
    • Docker Compose users migrating to production
  4. Edge Computing

    • Limited resources
    • Simple orchestration needs
  5. Development/Staging

    • Lightweight testing environments
    • CI/CD pipeline testing
┌─────────────────────────────────────────────────────────────────────────────┐
│ WHEN TO CHOOSE OTHER SOLUTIONS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Choose Kubernetes when: │
│ ───────────────────────── │
│ • Need multi-cloud or hybrid cloud deployments │
│ • Complex custom resource definitions needed │
│ • Large-scale production with thousands of containers │
│ • Need extensive ecosystem and integrations │
│ • Enterprise-grade security and compliance requirements │
│ • Need advanced scheduling and placement strategies │
│ │
│ Choose Docker Swarm when: │
│ ───────────────────────── │
│ • Starting with container orchestration │
│ • Simple microservices architecture │
│ • Already using Docker heavily │
│ • Quick setup is priority │
│ • Limited infrastructure team │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Load Balancer │ │
│ │ (External) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌───────────────────────┼───────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Manager Node │ │ Manager Node │ │ Manager Node │ │
│ │ (Leader) │◄────►│ (Member) │◄────►│ (Member) │ │
│ │ │ │ │ │ │ │
│ │ - Orchestrate │ │ - Replicate │ │ - Replicate │ │
│ │ - API endpoint│ │ - Consensus │ │ - Consensus │ │
│ │ - Scheduler │ │ - RAFT │ │ - RAFT │ │
│ └───────┬───────┘ └───────────────┘ └───────────────┘ │
│ │ │
│ │ Control Plane (Manager) │
│ │ Data Plane (Workers) │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ SWARM CLUSTER │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Worker Node │ │ Worker Node │ │ Worker Node │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │
│ │ │ │ Task 1 │ │ │ │ Task 2 │ │ │ │ Task 3 │ │ │ │
│ │ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │ │
│ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │
│ │ │ │ Task 4 │ │ │ │ Task 5 │ │ │ │ Task 6 │ │ │ │
│ │ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
  1. Cluster Management

    • Maintain cluster state
    • Schedule tasks
    • Handle API requests
  2. Raft Consensus

    • Leader election
    • State replication
    • Fault tolerance
  3. Orchestration

    • Service creation
    • Update orchestration
    • Health monitoring
  1. Task Execution

    • Run containers
    • Report container status
    • Execute tasks assigned by managers
  2. Networking

    • Participate in overlay network
    • Route traffic

Terminal window
# Initialize Docker Swarm (on the first manager node)
docker swarm init --advertise-addr <MANAGER-IP>
# Example
docker swarm init --advertise-addr 192.168.1.10
Terminal window
# Get join token from manager
docker swarm join-token worker
# On worker nodes, run the command provided
docker swarm join --token <WORKER-TOKEN> <MANAGER-IP>:2377
# Example
docker swarm join --token SWMTKN-1-2abc3defghi4jklmnop5qrstuvwxyz 192.168.1.10:2377
Terminal window
# Get manager join token
docker swarm join-token manager
# On new manager nodes, run the command provided
docker swarm join --token <MANAGER-TOKEN> <MANAGER-IP>:2377
Terminal window
# Check swarm status
docker info | grep Swarm
# List nodes in swarm
docker node ls
# List services
docker service ls
# Check node details
docker node inspect <NODE-ID>
# Leave swarm (from worker)
docker swarm leave
# Leave swarm (from manager - forces cluster removal)
docker swarm leave --force
┌─────────────────────────────────────────────────────────────────────────────┐
│ SWARM INITIALIZATION FLOW │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Initialize Swarm │
│ ───────────────────────── │
│ │
│ ┌─────────────┐ │
│ │ Server A │ docker swarm init --advertise-addr 192.168.1.10 │
│ │ (Manager) │────────────────┐ │
│ └─────────────┘ │ │
│ │ │
│ ┌─────────────────────────────┴─────────────────────────────┐ │
│ │ │ │
│ │ • Creates RAFT consensus group │ │
│ │ • Generates worker and manager tokens │ │
│ │ • Starts swarm mode │ │
│ │ • Exposes port 2377 for cluster communication │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Step 2: Add Workers │
│ ──────────────── │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Server B │ │ Server C │ │ Server D │ │
│ │ (Worker) │ │ (Worker) │ │ (Worker) │ │
│ │ │ │ │ │ │ │
│ │ docker │ │ docker │ │ docker │ │
│ │ swarm join │ │ swarm join │ │ swarm join │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Step 3: Add Manager (Optional) │
│ ─────────────────────────────── │
│ │
│ ┌─────────────┐ │
│ │ Server E │ docker swarm join --token manager ... │
│ │ (Manager) │ (Requires odd number for quorum) │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Terminal window
# Create a simple service
docker service create --name my-web --replicas 3 -p 8080:80 nginx
# Create service with environment variables
docker service create --name my-app \
--replicas 5 \
-e NODE_ENV=production \
-e DB_HOST=postgres \
myregistry.io/my-app:latest
# Create service with constraints (run on specific nodes)
docker service create --name database \
--constraint node.labels.disk==ssd \
postgres:15
# Create service with resource limits
docker service create --name api \
--limit-memory 512M \
--limit-cpu 0.5 \
myregistry.io/api:latest
Terminal window
# List services
docker service ls
# Inspect service
docker service inspect my-web
# View service logs
docker service logs my-web
# Update service
docker service update --replicas 5 my-web
# Remove service
docker service rm my-web
Terminal window
# Scale service up
docker service scale my-web=10
# Scale multiple services
docker service scale my-web=5 my-api=3 my-worker=2
┌─────────────────────────────────────────────────────────────────────────────┐
│ SERVICE AND TASK RELATIONSHIP │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Service Definition │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ name: my-web │ │
│ │ image: nginx:latest │ │
│ │ replicas: 3 │ │
│ │ ports: 8080:80 │ │
│ │ update_config: │ │
│ │ parallelism: 1 │ │
│ │ delay: 10s │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ SERVICE │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Task │ │ Task │ │ Task │ ← Container Instance │ │
│ │ │ 1 │ │ 2 │ │ 3 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │
│ │ ┌────┴────────────┴────────────┴────┐ │ │
│ │ │ Task Definition │ │ │
│ │ │ • Container spec │ │ │
│ │ │ • Resource limits │ │ │
│ │ │ • Restart policy │ │ │
│ │ │ • Placement constraints │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Task State Machine: │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ new │──►│pending │──►│assigned│──►│accepted│──►│running │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │rejectd │ │prepare │ │failed │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
max_attempts: 3
api:
image: myapi:latest
environment:
- DB_HOST=postgres
deploy:
replicas: 2
resources:
limits:
cpus: '0.5'
memory: 512M
postgres:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
deploy:
replicas: 1
volumes:
db-data:
Terminal window
# Deploy stack
docker stack deploy -c docker-compose.yml myapp
# List stacks
docker stack ls
# List services in stack
docker stack services myapp
# Remove stack
docker stack rm myapp

Terminal window
# Manual scaling
docker service scale myapp-web=5
# Auto-scaling (using docker-compose with deploy mode)
docker service update --replicas 5 myapp-web
┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM LOAD BALANCING │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ External LB │ │
│ │ (HAProxy, │ │
│ │ Cloud LB) │ │
│ └────────┬────────┘ │
│ │ │
│ │ Incoming Traffic │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ SWARM CLUSTER │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ Internal Load Balancer (Mesh) │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │
│ │ │ │ Virtual IP (VIP) / DNS Resolution │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ Service: myapp-web (replicas: 3) │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │
│ │ │ │ │Node:1 │ │Node:2 │ │Node:3 │ │ │ │ │
│ │ │ │ │Task:1 │ │Task:2 │ │Task:3 │ │ │ │ │
│ │ │ │ │:8080 │ │:8080 │ │:8080 │ │ │ │ │
│ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────────────────────────────────────────┘ │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Routing Mesh Features: │
│ • Automatic load balancing across all containers │
│ • Service discovery via DNS │
│ • External access via published ports │
│ • Internal communication via service names │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# Services can be reached by name
# From any container in the swarm:
curl http://my-web-service
# Or using DNS
ping my-web-service
# Inspect service endpoint
docker service inspect --format '{{json .Endpoint}}' my-web-service

Terminal window
# Update service image
docker service update --image myapp:v2.0 myapp
# Update with custom update configuration
docker service update \
--image myapp:v2.0 \
--update-parallelism 2 \
--update-delay 15s \
--update-failure-action rollback \
myapp
# Rollback to previous version
docker service rollback myapp
# docker-compose.yml with update config
services:
web:
image: myapp:latest
deploy:
replicas: 3
update_config:
parallelism: 2 # Update 2 containers at a time
delay: 10s # Wait 10s between updates
failure_action: rollback # Rollback on failure
monitor: 5s # Monitor for 5s after update
max_failure_ratio: 0.3 # Allow 30% failure
rollback_config:
parallelism: 1
delay: 5s
failure_action: pause
┌─────────────────────────────────────────────────────────────────────────────┐
│ ROLLING UPDATE PROCESS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Initial State: replicas=3, image=v1.0 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ [v1.0] │ │ [v1.0] │ │ [v1.0] │ │
│ │ Running │ │ Running │ │ Running │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ Step 1: Update Task 1 (parallelism=1, delay=10s) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ [v2.0] │ │ [v1.0] │ │ [v1.0] │ │
│ │ Updating ⏳ │ │ Running │ │ Running │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Wait 10s... │
│ │
│ Step 2: Update Task 2 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ [v2.0] │ │ [v2.0] │ │ [v1.0] │ │
│ │ Running ✓ │ │ Updating ⏳ │ │ Running │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Wait 10s... │
│ │
│ Step 3: Update Task 3 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ [v2.0] │ │ [v2.0] │ │ [v2.0] │ │
│ │ Running ✓ │ │ Running ✓ │ │ Running ✓ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ Final State: replicas=3, image=v2.0 │
│ │
│ ROLLBACK PROCESS: │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ [v2.0] │ │ [v2.0] │ │ [v2.0] │ │
│ │ Running ✓ │──►│ Rollingback │──►│ [v1.0] │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Terminal window
# Create an overlay network
docker network create \
--driver overlay \
--attachable \
my-overlay-network
# Use overlay network in service
docker service create \
--name my-service \
--network my-overlay-network \
nginx
┌─────────────────────────────────────────────────────────────────────────────┐
│ SWARM INGRESS NETWORK │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ External Traffic │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ INGRESS NETWORK (Overlay) │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ Routing Mesh │ │ │
│ │ │ • Distributes incoming traffic to any node │ │ │
│ │ │ • Uses IPVS for load balancing │ │ │
│ │ │ • Works at OSI Layer 3 (IP) │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────────────┼───────────────────────────────┐ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ │Node 1 │ │Node 2 │ │Node 3 │ │
│ │ │ │ │ │ │ │ │
│ │ │ ┌─────┐ │ │ ┌─────┐ │ │ ┌─────┐ │ │
│ │ │ │Task │ │ │ │Task │ │ │ │Task │ │ │
│ │ │ │ :80 │ │ │ │ :80 │ │ │ │ :80 │ │ │
│ │ │ └─────┘ │ │ └─────┘ │ │ └─────┘ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Traffic to any node:8080 routes to the correct container │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# List networks
docker network ls
# Inspect network
docker network inspect my-overlay-network
# Remove network
docker network rm my-network

┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM SECURITY LAYERS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ SWARM SECURITY │ │
│ │ │ │
│ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │
│ │ │ MUTUAL TLS │ │ ENCRYPTED │ │ RBAC │ │ │
│ │ │ │ │ NETWORKS │ │ │ │ │
│ │ │ • Node auth │ │ │ │ • Roles │ │ │
│ │ │ • Encrypted │ │ • Data plane │ │ • Policies │ │ │
│ │ │ comms │ │ encryption │ │ • Grants │ │ │
│ │ │ • Certificate │ │ • TLS for │ │ │ │ │
│ │ │ rotation │ │ ingress │ │ │ │ │
│ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │
│ │ │ │
│ │ ┌───────────────┐ ┌───────────────┐ │ │
│ │ │ SECRETS │ │ NODE │ │ │
│ │ │ │ │ LOCKING │ │ │
│ │ │ • Encrypted │ │ │ │ │
│ │ │ at rest │ │ • Rotate │ │ │
│ │ │ • TLS certs │ │ keys │ │ │
│ │ │ • Passwords │ │ • Auto-lock │ │ │
│ │ │ • Keys │ │ │ │ │
│ │ └───────────────┘ └───────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# Create a secret
echo "my-password" | docker secret create db_password -
# Use secret in service
docker service create \
--name my-app \
--secret db_password \
myapp:latest
# Use secret as environment variable
docker service create \
--name my-app \
--secret source=db_password,target=DB_PASSWORD,mode=0400 \
myapp:latest
Terminal window
# Initialize swarm with auto-lock
docker swarm init --autolock
# Or enable on existing swarm
docker swarm update --autolock=true
# Unlock with key
docker swarm unlock
# View unlock key
docker swarm join-token --rotate manager

┌─────────────────────────────────────────────────────────────────────────────┐
│ DOCKER SWARM BEST PRACTICES │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Manager Nodes │
│ ─────────────── │
│ • Use 3 or 5 managers (odd number for quorum) │
│ • Don't run workloads on managers (use constraints) │
│ • Distribute managers across availability zones │
│ • Enable auto-lock for additional security │
│ │
│ 2. Worker Nodes │
│ ───────────── │
│ • Minimum 3 workers for high availability │
│ • Use similar hardware across nodes │
│ • Separate nodes by workload type (compute, memory, I/O) │
│ │
│ 3. Services │
│ ───────── │
│ • Use health checks in container definitions │
│ • Set appropriate replica counts │
│ • Use update delay for gradual rollouts │
│ • Always set resource limits │
│ │
│ 4. Networking │
│ ─────────── │
│ • Use custom overlay networks for isolation │
│ • Enable encryption on sensitive networks │
│ • Limit port exposure to necessary ports only │
│ │
│ 5. Security │
│ ───────── │
│ • Use secrets for sensitive data │
│ • Scan images for vulnerabilities │
│ • Use read-only file systems when possible │
│ • Run containers as non-root users │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Terminal window
# Service with resource limits
docker service create \
--name api \
--limit-memory 512M \
--limit-cpu 0.5 \
--reserve-memory 256M \
--reserve-cpu 0.25 \
myapi:latest
Terminal window
# Service with health check
docker service create \
--name web \
--health-cmd "curl -f http://localhost/ || exit 1" \
--health-interval 30s \
--health-timeout 10s \
--health-retries 3 \
--health-start-period 30s \
nginx

In this hands-on lab, we’ll deploy a complete application stack using Docker Swarm.

  • 3 or more Docker hosts (can be VMs or cloud instances)
  • Docker Engine 19.03 or later
Terminal window
# Step 1: Initialize swarm on first node
docker swarm init --advertise-addr <MANAGER-IP>
# Step 2: Get join tokens
docker swarm join-token worker
docker swarm join-token manager
# Step 3: Join worker nodes (on each worker)
docker swarm join --token <WORKER-TOKEN> <MANAGER-IP>:2377
# Step 4: Verify cluster
docker node ls
# Step 5: Create overlay network
docker network create --driver overlay myapp-network
# Step 6: Deploy stack
docker stack deploy -c <<EOF
version: '3.8'
services:
redis:
image: redis:alpine
networks:
- myapp-network
deploy:
replicas: 1
web:
image: nginx:alpine
ports:
- "80:80"
networks:
- myapp-network
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
worker:
image: myapp-worker:latest
networks:
- myapp-network
deploy:
replicas: 3
networks:
myapp-network:
external: true
EOF
myapp
# Step 7: Monitor deployment
docker stack services myapp
docker service ps myapp_web
# Step 8: Scale the application
docker service scale myapp_web=5
docker service scale myapp_worker=10
# Step 9: Update the application
docker service update --image nginx:latest myapp_web
# Step 10: Check logs
docker service logs myapp_web
# Step 11: Clean up
docker stack rm myapp
docker network rm myapp-network

In this chapter, we’ve covered:

  1. Container Orchestration - Why we need orchestration for production workloads
  2. Docker Swarm - Native Docker container orchestration platform
  3. Architecture - Manager nodes, worker nodes, and their roles
  4. Setup - Initializing and configuring a swarm cluster
  5. Services and Stacks - Deploying applications as services and stacks
  6. Scaling & Load Balancing - Horizontal scaling and built-in load balancing
  7. Rolling Updates - Performing zero-downtime updates
  8. Networking - Overlay networks and routing mesh
  9. Security - TLS, secrets, and RBAC
  10. Best Practices - Production-ready configurations

In the next chapter, we’ll dive into Docker Security (Chapter 12), covering:

  • Container security best practices
  • Seccomp and AppArmor profiles
  • Docker content trust
  • Security scanning