Day 23: Introduction to Orchestration - Docker Swarm

Learning Objectives: By the end of this lesson, you will be able to:

  • Understand container orchestration concepts and benefits
  • Set up and configure Docker Swarm clusters
  • Deploy and manage services across multiple nodes
  • Implement load balancing and service discovery in Swarm
  • Configure rolling updates and scaling strategies

1. Welcome and Introduction (5 minutes)

Icebreaker Activity

“Imagine you’re running a popular e-commerce website during Black Friday. You have dozens of containers running across multiple servers, and you need to ensure they’re all healthy, automatically replace failed instances, and scale up when traffic increases. How would you coordinate all these moving parts without going insane? Today we’ll learn how Docker Swarm makes orchestrating containers across multiple machines feel like conducting a symphony.”

Lesson Overview

  • Duration: 90 minutes
  • Prerequisites: Docker fundamentals, multi-container applications, basic networking concepts
  • Materials Needed: Multiple virtual machines or cloud instances, Docker installed on each

2. Learning Objectives and Session Outline (5 minutes)

What We’ll Cover Today:

  1. Orchestration Fundamentals - Understanding why orchestration is needed
  2. Docker Swarm Architecture - Managers, workers, and cluster concepts
  3. Service Management - Creating, scaling, and updating services
  4. Networking and Load Balancing - Service discovery and traffic distribution
  5. High Availability - Fault tolerance and recovery strategies

Success Criteria:

By the end of this session, you should be able to set up a Docker Swarm cluster, deploy multi-service applications with proper load balancing, and implement rolling updates with zero downtime.

3. Foundation Knowledge (15-20 minutes)

Core Concepts

What is Container Orchestration?

Container orchestration automates the deployment, scaling, networking, and management of containerized applications across multiple hosts. It solves the challenges that arise when running containers at scale.

Real-World Analogy: Think of orchestration like an air traffic control system at a busy airport. Without orchestration, you have individual pilots (containers) trying to coordinate landing and takeoff on their own, leading to chaos. With orchestration, you have a centralized system that manages traffic flow, handles emergencies, and ensures everything runs smoothly.

Why This Matters: As applications grow beyond a single machine, manual container management becomes impossible. Orchestration provides automated scaling, health monitoring, service discovery, and rolling updates.

Docker Swarm vs Other Orchestrators

  • Docker Swarm: Built into Docker, simple to set up, good for smaller clusters
  • Kubernetes: Most popular, feature-rich, steep learning curve
  • Apache Mesos: Highly scalable, complex setup
  • Nomad: Simple, lightweight, good for mixed workloads

Swarm Architecture Components

  • Manager Nodes: Control the cluster, make scheduling decisions, maintain cluster state
  • Worker Nodes: Run containers based on manager instructions
  • Services: Declarative way to run and scale containers
  • Tasks: Individual container instances running on nodes
  • Overlay Networks: Multi-host networking for service communication

Key Terminology

  • Cluster: Group of Docker engines participating in swarm mode
  • Node: Individual Docker engine instance in the swarm
  • Service: Definition of tasks to execute on worker nodes
  • Task: Running container instance and its configuration
  • Replica: Number of identical tasks running across the cluster
  • Routing Mesh: Built-in load balancer for service traffic

4. Detailed Explanation and Examples (25-30 minutes)

Understanding Docker Swarm Architecture

Docker Swarm uses a declarative model where you describe the desired state of your application, and Swarm ensures that state is maintained. If a container fails, Swarm automatically replaces it. If a node goes down, Swarm reschedules the containers on healthy nodes.

Manager Node Responsibilities

  • Cluster Management: Maintain cluster membership and node health
  • Orchestration: Schedule services across worker nodes
  • API Endpoint: Provide the Docker API for cluster management
  • Raft Consensus: Ensure consistency across manager nodes

Worker Node Responsibilities

  • Task Execution: Run containers as assigned by managers
  • Health Reporting: Report container and node status to managers
  • Resource Provision: Provide CPU, memory, and storage for containers

Service Discovery and Load Balancing

Swarm provides built-in service discovery through DNS and automatic load balancing through the routing mesh:

  • DNS-based Discovery: Services can find each other by name
  • Routing Mesh: Distributes incoming traffic across healthy replicas
  • Session Affinity: Can be configured for stateful applications

Service Management Patterns

Replicated Services

Most common service type where you specify the number of replica tasks:

docker service create \
  --name web \
  --replicas 3 \
  --publish 80:80 \
  nginx:alpine

Global Services

Runs exactly one task on every node (useful for monitoring or logging):

docker service create \
  --name monitoring \
  --mode global \
  --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  monitoring-agent:latest

Rolling Updates

Swarm can update services with zero downtime:

docker service update \
  --image nginx:1.21 \
  --update-delay 30s \
  --update-parallelism 1 \
  web

Networking in Docker Swarm

Overlay Networks

Enable communication between containers across different nodes:

# Create overlay network
docker network create \
  --driver overlay \
  --subnet=10.0.9.0/24 \
  my-overlay

# Create service using the network
docker service create \
  --name app \
  --network my-overlay \
  --replicas 3 \
  my-app:latest

Ingress Network

Built-in overlay network that handles external traffic routing:

  • Automatically created when swarm is initialized
  • Provides load balancing for published ports
  • Routes traffic to healthy service replicas

Common Misconceptions

  1. Misconception: Docker Swarm is deprecated Reality: Docker Swarm is actively maintained and suitable for many use cases

  2. Misconception: You need dedicated machines for manager nodes Reality: Manager nodes can also run application workloads

5. Live Coding Demonstration (20-25 minutes)

Example 1: Setting Up Docker Swarm Cluster

# Initialize swarm on manager node
docker swarm init --advertise-addr 192.168.1.100

# Output will provide join command for workers:
# docker swarm join --token SWMTKN-1-xxx... 192.168.1.100:2377

# On worker nodes, run the join command
docker swarm join \
  --token SWMTKN-1-4f1b7b... \
  192.168.1.100:2377

# Verify cluster status
docker node ls

# Example output:
# ID            HOSTNAME   STATUS  AVAILABILITY  MANAGER STATUS
# abc123...     manager1   Ready   Active        Leader
# def456...     worker1    Ready   Active
# ghi789...     worker2    Ready   Active

Example 2: Deploying Multi-Service Application

# docker-stack.yml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - nginx_config:/etc/nginx/conf.d
    networks:
      - frontend
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      placement:
        constraints:
          - node.role == worker

  api:
    image: myapp/api:v1.0
    networks:
      - frontend
      - backend
    environment:
      - DATABASE_URL=postgresql://user:pass@database:5432/myapp
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
      update_config:
        parallelism: 1
        delay: 15s
      restart_policy:
        condition: on-failure

  database:
    image: postgres:13
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - backend
    secrets:
      - db_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.database == true
      restart_policy:
        condition: on-failure

  redis:
    image: redis:6-alpine
    networks:
      - backend
    deploy:
      replicas: 1
      resources:
        limits:
          memory: 256M
      placement:
        constraints:
          - node.role == worker

networks:
  frontend:
    driver: overlay
    attachable: true
  backend:
    driver: overlay
    internal: true

volumes:
  postgres_data:
  nginx_config:

secrets:
  db_password:
    external: true

configs:
  nginx_config:
    external: true

Deploy the stack:

# Create secrets and configs
echo "mySecretPassword" | docker secret create db_password -

# Deploy the stack
docker stack deploy -c docker-stack.yml myapp

# Check stack status
docker stack ls
docker stack services myapp
docker stack ps myapp

# View service logs
docker service logs myapp_web
docker service logs -f myapp_api

Example 3: Service Management and Scaling

# Scale services
docker service scale myapp_api=4
docker service scale myapp_web=5

# Update service with new image
docker service update \
  --image myapp/api:v1.1 \
  --update-delay 30s \
  --update-parallelism 1 \
  myapp_api

# Monitor update progress
docker service ps myapp_api

# Rollback if needed
docker service rollback myapp_api

# Inspect service configuration
docker service inspect myapp_web --pretty

# Force service recreation
docker service update --force myapp_web

Example 4: Advanced Networking and Load Balancing

# Create custom overlay network with encryption
docker network create \
  --driver overlay \
  --subnet=10.0.10.0/24 \
  --opt encrypted \
  secure-network

# Create service with custom network
docker service create \
  --name secure-app \
  --network secure-network \
  --replicas 3 \
  --publish mode=host,target=80,published=8080 \
  nginx:alpine

# Test load balancing
for i in {1..10}; do
  curl http://localhost:8080
done

# Check service endpoint resolution
docker service inspect secure-app \
  --format '{{.Endpoint.VirtualIPs}}'

# Create service with placement preferences
docker service create \
  --name distributed-app \
  --replicas 6 \
  --placement-pref 'spread=node.labels.zone' \
  my-app:latest

Example 5: High Availability Configuration

# Promote worker to manager for HA
docker node promote worker1

# Add labels to nodes for placement
docker node update --label-add zone=us-west-1a worker1
docker node update --label-add zone=us-west-1b worker2
docker node update --label-add ssd=true worker1

# Drain node for maintenance
docker node update --availability drain worker2

# Check node status
docker node ls
docker node inspect worker1 --pretty

# Remove node from swarm
docker node rm worker3

# Leave swarm (run on node to be removed)
docker swarm leave

# Backup swarm state (run on manager)
docker swarm unlock-key --rotate

Example 6: Monitoring and Troubleshooting

# Monitor cluster events
docker system events --filter type=service

# Check cluster info
docker system info | grep -A 10 "Swarm:"

# Inspect service tasks
docker service ps myapp_web --no-trunc

# Get detailed task information
docker inspect <task-id>

# View service constraints and placement
docker service inspect myapp_database \
  --format '{{.Spec.TaskTemplate.Placement}}'

# Check overlay network connectivity
docker run --rm --network myapp_frontend \
  alpine ping api

# Analyze resource usage
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

6. Hands-On Practice (30-40 minutes)

Exercise 1: Multi-Node Swarm Setup (15 minutes)

Objective: Create a 3-node Docker Swarm cluster with proper high availability

Instructions:

  1. Set up 3 virtual machines or cloud instances
  2. Initialize swarm with one manager node
  3. Join 2 worker nodes to the cluster
  4. Promote one worker to manager for HA
  5. Deploy a test service and verify it runs across nodes

Verification Commands:

# Check cluster health
docker node ls

# Verify service distribution
docker service ps test-service

# Test failover by stopping Docker on one node

Exercise 2: Deploy Microservices Application (20 minutes)

Objective: Deploy a complete microservices application with proper networking and scaling

Requirements:

  • Frontend web service (3 replicas)
  • API service (2 replicas)
  • Database service (1 replica, specific node placement)
  • Redis cache (1 replica)
  • Proper network segmentation
  • Load balancing and service discovery

Starter Stack File:

version: '3.8'

services:
  # TODO: Define your services here
  
networks:
  # TODO: Define networks
  
volumes:
  # TODO: Define volumes

secrets:
  # TODO: Define secrets

Exercise 3: Rolling Update and Rollback (5 minutes)

Objective: Perform zero-downtime updates and handle rollback scenarios

Challenge:

  • Deploy initial version of an application
  • Update to a new version with rolling update strategy
  • Simulate a problematic update that needs rollback
  • Monitor the update process and verify zero downtime

Extension Ideas:

  • Implement health checks to automatically detect failed updates
  • Configure update failure actions
  • Test different update parallelism settings

7. Common Pitfalls and Troubleshooting (10 minutes)

Frequent Swarm Issues

  1. Problem: Services not starting or staying in pending state Cause: Insufficient resources, placement constraints, or image pull failures Solution: Check node resources, constraints, and image availability

  2. Problem: Network connectivity issues between services Cause: Incorrect network configuration or firewall rules Solution: Verify overlay networks and ensure proper ports are open

  3. Problem: Manager node election issues Cause: Network partitions or insufficient manager nodes Solution: Maintain odd number of managers and ensure network connectivity

Debugging Commands

# Check service status and errors
docker service ps --no-trunc service-name

# Inspect failed tasks
docker inspect task-id

# View service logs across all replicas
docker service logs service-name

# Check network connectivity
docker run --rm --network network-name alpine nslookup service-name

# Verify port publishing
docker service inspect service-name --format '{{.Endpoint.Ports}}'

# Check node resources
docker node ls --format "table {{.Hostname}}\t{{.Status}}\t{{.Availability}}"

Performance Optimization

  • Resource Allocation: Set appropriate resource limits and reservations
  • Placement Strategies: Use node labels and constraints for optimal placement
  • Network Optimization: Use overlay networks efficiently
  • Update Strategies: Configure appropriate update parallelism and delays

8. Best Practices and Professional Tips (5 minutes)

Cluster Management

  • High Availability: Run odd number of manager nodes (3 or 5 for production)
  • Backup Strategy: Regular backups of swarm state and data volumes
  • Security: Use TLS encryption and rotate join tokens regularly
  • Monitoring: Implement comprehensive monitoring for nodes and services

Service Design

  • Stateless Services: Design services to be stateless when possible
  • Health Checks: Implement proper health checks for automatic recovery
  • Resource Limits: Set appropriate CPU and memory limits
  • Update Strategy: Plan rolling update strategies with proper delays

Production Considerations

  • Secrets Management: Use Docker secrets for sensitive configuration
  • Logging: Centralize logging with appropriate log drivers
  • Networking: Design network topology for security and performance
  • Disaster Recovery: Plan for node failures and cluster recovery

9. Summary and Review (5 minutes)

Key Takeaways

  1. Orchestration Benefits: Automated scaling, health monitoring, and service management
  2. Swarm Simplicity: Easy to set up and manage compared to other orchestrators
  3. Built-in Features: Load balancing, service discovery, and rolling updates included
  4. High Availability: Multiple manager nodes ensure cluster resilience

Quick Review Questions

  1. What’s the difference between a service and a task in Docker Swarm?
  2. How does the routing mesh provide load balancing for services?
  3. What considerations are important when planning rolling updates?

For Instructors

Teaching Tips

  • Use visual diagrams to explain swarm architecture and networking
  • Demonstrate both successful operations and failure scenarios
  • Emphasize hands-on practice with real multi-node clusters
  • Show comparison with single-host Docker to highlight orchestration benefits

Assessment Ideas

  • Set up and manage multi-node swarm clusters
  • Deploy complex applications with proper networking and scaling
  • Troubleshoot common swarm issues and implement solutions

Adaptation Notes

  • Beginners: Focus on basic swarm concepts and simple service deployment
  • Advanced: Cover advanced topics like custom schedulers and integration with external systems
  • Resource Constraints: Use virtual machines or cloud instances for multi-node practice
  • Time Management: Balance theory with extensive hands-on cluster management