如何基于现有Docker Compose文件搭建Docker Swarm实现跨三台主机部署与扩容?
Great question! Docker Swarm is absolutely the right tool for this job—it’s lightweight, integrates seamlessly with Docker Compose syntax, and handles multi-host orchestration, service scaling, and load balancing out of the box. Here’s a step-by-step, scriptable solution tailored to your needs:
First, we’ll create a Swarm cluster across your three hosts. One host acts as the manager (orchestrates deployment), and the other two are workers (run your services).
Scripted Cluster Initialization
You can automate this with a bash script—just make sure you’ve set up passwordless SSH between all hosts first so the script can run commands remotely.
#!/bin/bash # Replace these values with your actual host IPs and SSH user MANAGER_IP="192.168.1.100" WORKER_IPS=("192.168.1.101" "192.168.1.102") SSH_USER="your-ssh-user" # Initialize Swarm on the manager if not already active if ! docker info | grep -q "Swarm: active"; then echo "Initializing Swarm manager on $MANAGER_IP..." docker swarm init --advertise-addr $MANAGER_IP fi # Get the worker join token (quiet mode to avoid extra output) WORKER_TOKEN=$(docker swarm join-token worker -q) # Add worker nodes to the cluster for WORKER_IP in "${WORKER_IPS[@]}"; do echo "Joining worker node $WORKER_IP..." ssh $SSH_USER@$WORKER_IP "docker swarm join --token $WORKER_TOKEN $MANAGER_IP:2377" done # Wait for all nodes to reach "Ready" state echo "Waiting for all nodes to be ready..." until [ $(docker node ls | grep -c "Ready") -eq 3 ]; do sleep 5 done echo "Swarm cluster is ready!"
Rename your existing docker-compose.yml to docker-stack.yml (Swarm’s preferred naming) and add Swarm-specific deploy sections to control scaling, placement, and redundancy.
Here’s a tailored example for your services:
version: '3.8' services: rest-api: image: your-java-api-image:latest # Replace with your actual image deploy: replicas: 3 # Spin up 3 instances (one per host, if possible) placement: spread: node.hostname # Distribute instances across different hosts restart_policy: condition: on-failure # Auto-restart if the service crashes ports: - "8080:8080" # Swarm's routing mesh will load-balance traffic to all instances environment: - MONGO_URI=mongodb://mongo:27017/your-db - REDIS_HOST=redis depends_on: - mongo - redis mongo: image: mongo:latest deploy: placement: constraints: [node.hostname == host1] # Pin to a specific host for data persistence restart_policy: condition: on-failure volumes: - mongo-data:/data/db # Persist MongoDB data redis: image: redis:latest deploy: placement: constraints: [node.hostname == host2] # Pin to another specific host restart_policy: condition: on-failure volumes: - redis-data:/data # Persist Redis data volumes: mongo-data: redis-data:
Key notes for this config:
- rest-api: The
spreadplacement rule ensures your 3 instances are distributed across your 3 hosts (ideal for high availability). Swarm’s built-in routing mesh will automatically load-balance incoming traffic on port 8080 to all instances. - Mongo/Redis: These are stateful services, so we pin them to specific hosts with
constraintsto avoid data loss (since local volumes are tied to individual hosts).
Add this to your deployment script (after the cluster initialization steps) to deploy your services with a single command:
# Deploy the stack to the Swarm cluster echo "Deploying services..." docker stack deploy -c docker-stack.yml my-app-stack # Verify the deployment echo "Checking service status:" docker stack services my-app-stack
Running docker stack deploy is Swarm’s equivalent of docker-compose up -d—it creates or updates services across the cluster.
- To scale your
rest-apilater (e.g., to 5 instances), run:docker service scale my-app-stack_rest-api=5 - Check running service instances with:
docker stack ps my-app-stack - Update services (e.g., a new Java API image) by re-running
docker stack deploy -c docker-stack.yml my-app-stack—Swarm will perform a rolling update with zero downtime.
内容的提问来源于stack exchange,提问作者Philippe

