本文详解如何使用Docker Swarm部署高可用WordPress集群,实现零停机更新和自动故障转移。

为什么用Docker Swarm而非Kubernetes

方案 复杂度 适用场景
Docker Compose 单机开发/测试
Docker Swarm 中小规模生产(< 100节点)
Kubernetes 大规模生产(> 100节点)

初始化Docker Swarm集群

创建管理节点(Manager)

# 在主节点初始化Swarm
docker swarm init --advertise-addr 192.168.1.10

# 输出:
# Swarm initialized: current node (abc123) is now a manager.
# To add a worker to this swarm, run the following command:
#     docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

添加工作节点(Worker)

# 在其他服务器上运行(从初始化输出中复制命令)
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

# 在管理节点验证
docker node ls

# 输出:
# ID                           HOSTNAME   STATUS  AVAILABILITY  MANAGER STATUS
# abc123 *   manager-1  Ready   Active        Leader
# def456    worker-1    Ready   Active
# ghi789    worker-2    Ready   Active

创建Docker Swarm服务

创建Overlay网络

# Overlay网络:跨主机容器通信
docker network create --driver overlay wp_network

# 查看网络
docker network ls

部署MySQL服务

# 创建MySQL服务(1副本,仅管理节点运行)
docker service create \
  --name mysql \
  --network wp_network \
  --mount type=volume,target=/var/lib/mysql \
  --env MYSQL_ROOT_PASSWORD=secret \
  --env MYSQL_DATABASE=wordpress \
  --env MYSQL_USER=wp_user \
  --env MYSQL_PASSWORD=wp_pass \
  --constraint 'node.role==manager' \  # 仅在管理节点运行
  mysql:8.0

# 查看服务
docker service ls

# 输出:
# ID          NAME    MODE        REPLICAS  IMAGE         PORTS
# abc123      mysql   replicated  1/1       mysql:8.0

部署WordPress服务

# 创建WordPress服务(3副本,负载均衡)
docker service create \
  --name wordpress \
  --network wp_network \
  --mount type=volume,target=/var/www/html \
  --env WORDPRESS_DB_HOST=mysql:3306 \
  --env WORDPRESS_DB_USER=wp_user \
  --env WORDPRESS_DB_PASSWORD=wp_pass \
  --env WORDPRESS_DB_NAME=wordpress \
  --replicas 3 \  # 3个副本(高可用)
  --publish published=80,target=80 \
  wordpress:php8.2-apache

# 查看副本状态
docker service ps wordpress

# 输出:
# ID        NAME          IMAGE          NODE      DESIRED STATE
# abc123    wordpress.1  wordpress:...  worker-1  Running
# def456    wordpress.2  wordpress:...  worker-2  Running
# ghi789    wordpress.3  wordpress:...  manager-1  Running

使用Docker Stack(推荐)

创建docker-stack.yml

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    networks:
      - wp_network
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_pass
    deploy:
      placement:
        constraints:
          - node.role == manager  # 仅在管理节点运行
      restart_policy:
        condition: on-failure

  wordpress:
    image: wordpress:php8.2-apache
    networks:
      - wp_network
    ports:
      - 80:80
    volumes:
      - wp_data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: mysql:3306
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: wp_pass
      WORDPRESS_DB_NAME: wordpress
    deploy:
      replicas: 3
      update_config:
        parallelism: 1       # 每次更新1个副本
        delay: 10s           # 间隔10秒
        failure_action: rollback  # 失败回滚
      restart_policy:
        condition: on-failure

  redis:
    image: redis:7-alpine
    networks:
      - wp_network
    volumes:
      - redis_data:/data
    deploy:
      replicas: 1

networks:
  wp_network:
    driver: overlay

volumes:
  mysql_data:
  wp_data:
  redis_data:

部署Stack

# 部署Stack(一次性创建所有服务)
docker stack deploy -c docker-stack.yml wp_stack

# 查看Stack服务
docker stack services wp_stack

# 输出:
# ID          NAME              MODE        REPLICAS  IMAGE
# abc123      wp_stack_mysql    replicated  1/1       mysql:8.0
# def456      wp_stack_wordpress  replicated  3/3       wordpress:...
# ghi789      wp_stack_redis    replicated  1/1       redis:7-alpine

数据持久化

问题:容器重启后数据丢失

Docker容器文件系统是临时的!
→ 必须使用Volume或Bind Mount持久化数据

使用NFS共享存储(多节点)

# 在NFS服务器上
sudo apt install nfs-kernel-server -y
echo "/srv/nfs/wp_data *(rw,sync,no_subtree_check)" | sudo tee -a /etc/exports
sudo systemctl restart nfs-kernel-server

# 在每个Docker节点上挂载NFS
sudo mount -t nfs 192.168.1.100:/srv/nfs/wp_data /mnt/wp_data

# 在docker-stack.yml中使用
volumes:
  wp_data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.1.100,rw"
      device: ":/srv/nfs/wp_data"

滚动更新(零停机)

更新WordPress版本

# 更新服务镜像(滚动更新)
docker service update \
  --image wordpress:php8.3-apache \
  --update-parallelism 1 \
  --update-delay 10s \
  wp_stack_wordpress

# 监控更新过程
docker service ps wp_stack_wordpress

# 输出:
# ID        NAME              IMAGE                DESIRED STATE  CURRENT STATE
# abc123    wp_stack_wordpress.1  wordpress:php8.3  Running        Running 2 minutes ago
# def456    _ wp_stack_wordpress.1  wordpress:php8.2  Shutdown       Shutdown 2 minutes ago

回滚(更新失败)

# 回滚到上一个版本
docker service rollback wp_stack_wordpress

# 查看回滚状态
docker service ps wp_stack_wordpress

负载均衡

Docker Swarm内置负载均衡

外部请求 → 任意节点IP:80 
         → Docker Swarm Routing Mesh(自动路由)
         → 某个WordPress容器(负载均衡)

使用外部负载均衡器(推荐)

# Nginx负载均衡到Swarm节点
upstream docker_swarm {
    server 192.168.1.10:80;  # manager-1
    server 192.168.1.11:80;  # worker-1
    server 192.168.1.12:80;  # worker-2
}

server {
    listen 80;
    location / {
        proxy_pass http://docker_swarm;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

监控Docker Swarm

使用Portainer(可视化)

# 部署Portainer Agent(每个节点)
docker run -d \
  --name portainer_agent \
  --network host \
  --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  portainer/agent:2.19.4

# 部署Portainer Server(管理节点)
docker run -d \
  --name portainer \
  --network wp_network \
  --publish 9443:9443 \
  --mount type=volume,src=portainer_data,dst=/data \
  portainer/portainer-ce:2.19.4

访问:https://manager-ip:9443

使用Prometheus + Grafana

# monitoring-stack.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    networks:
      - wp_network
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090

  grafana:
    image: grafana/grafana:latest
    networks:
      - wp_network
    ports:
      - 3000:3000
    volumes:
      - grafana_data:/var/lib/grafana

networks:
  wp_network:
    driver: overlay

volumes:
  grafana_data:

2026年Docker Swarm趋势

趋势一:Docker Swarm与Kubernetes互操作

Docker Swarm → 使用kompose转换 → Kubernetes YAML
→ 小集群用Swarm,大集群迁移到K8s

趋势二:Rootless模式(安全增强)

# 以非root用户运行Docker守护进程
dockerd --userns-remap=default

# 防止容器逃逸(提升安全性)

趋势三:镜像签名与验证(内容信任)

# 启用Docker Content Trust(DCT)
export DOCKER_CONTENT_TRUST=1

# 推送签名镜像
docker push my-registry/wordpress:latest
# 现在拉取时必须验证签名

故障排除

问题一:服务无法启动

# 查看服务日志
docker service logs wp_stack_wordpress

# 查看容器详情
docker inspect wp_stack_wordpress.1.abc123

问题二:Overlay网络不通

# 检查防火墙(Swarm需要以下端口)
# TCP 2377(集群管理)
# TCP/UDP 7946(节点通信)
# UDP 4789(Overlay网络)

# 开放端口
sudo ufw allow 2377/tcp
sudo ufw allow 7946/tcp
sudo ufw allow 7946/udp
sudo ufw allow 4789/udp

问题三:数据卷锁定(NFS)

# 错误:volume is in use
# 解决:强制移除
docker volume rm -f wp_data

# 或更推荐:使用全局卷驱动
docker plugin install --grant-all-permissions vieux/sshfs

决策建议

  • < 10个节点 → Docker Swarm(简单易用)
  • 10-100个节点 → Docker Swarm或轻量Kubernetes(k3s)
  • > 100个节点 → 全功能Kubernetes
  • 开发/测试 → Docker Compose(无需Swarm)

总结

Docker Swarm提供了比Compose更强的生产特性(高可用、滚动更新、Overlay网络),但比Kubernetes简单10倍。2026年,对于中小型WordPress部署,Docker Swarm仍是最佳选择。

立即行动:在你的测试服务器上运行 docker swarm init,体验Docker Swarm的强大功能。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。