一、文档说明
本文档面向Docker初学者及运维人员,系统讲解Docker Swarm核心概念、YAML配置文件参数含义,并结合实操示例,帮助你理解并落地Docker Swarm集群编排技术。

二、Docker Swarm 核心概念
你需要先理解Docker Swarm的核心定义和组件,才能更好地掌握其编排逻辑,以下是关键概念的通俗解释:
2.1 什么是Docker Swarm
Docker Swarm是Docker官方提供的轻量级集群编排工具,无需额外安装,与Docker引擎深度集成。它能将多台Docker主机(物理机/虚拟机)组成一个“Swarm集群”,统一管理集群内的容器部署、扩展、负载均衡和故障恢复,解决单主机Docker无法满足的分布式部署需求。
核心特点:
- 原生集成:基于Docker引擎,学习成本低;
- 高可用:支持多管理节点容错,单个节点故障不影响集群;
- 轻量化:相比K8s更简单,适合中小型应用场景;
- 声明式编排:通过YAML定义服务状态,Swarm自动维护。
2.2 核心组件
组件 | 定义与作用 |
节点(Node) | 集群中的每一台Docker主机,分两类: |
服务(Service) | 集群中容器编排的核心单位,定义容器的运行规则(镜像、端口、副本数等)。分两种类型: |
任务(Task) | 服务的最小执行单元,本质是一个运行中的容器实例。管理节点将服务拆分为任务,调度到工作节点,任务故障时会自动重建。 |
栈(Stack) | 多个关联服务的集合,通过YAML文件定义,支持一键部署复杂应用(如前端+后端+数据库)。 |
负载均衡 | Swarm内置DNS和VIP(虚拟IP): |
Raft共识算法 | 管理节点间的一致性协议,保证只有一个“主管理节点”决策,多管理节点时自动同步配置,实现高可用。 |
三、Docker Swarm YAML 配置参数详解
Docker Swarm通过docker-stack.yml(兼容docker-compose.yml)定义服务配置,核心是services节点,以下按“参数类型+含义+示例”拆解关键参数。
3.1 配置文件基础结构
首先明确YAML文件的基础框架,版本需与Docker引擎兼容(推荐3.8+,适配Docker 20.10+):
# 核心框架示例version: '3.8' # Compose语法版本(必填,Swarm需3.0+)services: # 服务集合(核心节点,必填) web: # 自定义服务名(集群内唯一) # 服务具体配置参数networks: # 自定义网络(可选,服务间通信)volumes: # 自定义数据卷(可选,数据持久化)secrets: # 密钥(可选,存储敏感信息)configs: # 配置项(可选,存储非敏感配置文件)3.2 核心参数分类讲解
(1)容器基础配置(必选/高频)
参数 | 含义 | 示例 |
image | 指定容器镜像(必填,优先级高于build),格式:镜像名:标签 | image: nginx:1.25 (使用nginx 1.25版本) |
build | 本地构建镜像(替代image),指定Dockerfile路径 | build: ./nginx (Dockerfile在当前目录nginx文件夹下) |
command | 覆盖容器默认启动命令(推荐列表格式,避免解析问题) | command: ["nginx", "-g", "daemon off;"] |
entrypoint | 覆盖容器入口点(ENTRYPOINT),与command配合使用 | entrypoint: ["/usr/sbin/nginx"] |
environment | 设置容器环境变量(列表/字典格式),敏感信息建议用secrets | ```yaml |
environment: |
- TZ=Asia/Shanghai # 列表格式 MYSQL_ROOT_PASSWORD: 123456 # 字典格式
| `env_file` | 从外部文件加载环境变量(优先级低于environment)| ```yamlenv_file: - ./.env # 环境变量文件路径 - ./app.env``` || `user` | 指定容器运行的用户(用户名/UID)| `user: "1000"` 或 `user: nginx` |#### (2)网络配置(服务通信/外部访问)| 参数 | 含义 | 示例 ||--------------|----------------------------------------------------------------------|----------------------------------------------------------------------|| `ports` | 映射容器端口到宿主机(Swarm推荐`published/target`格式),支持协议指定 | ```yamlports: - "8080:80" # 简写:宿主机8080 -> 容器80(tcp默认) - target: 8080 published: 8080 protocol: tcp mode: host # 模式:host(宿主机端口独占)/ingress(Swarm负载均衡,默认)``` || `networks` | 关联自定义网络(需在顶层`networks`定义)| ```yamlservices: web: networks: - my-networknetworks: my-network: driver: overlay # Swarm集群网络必须用overlay驱动``` || `hostname` | 容器主机名(集群内服务间可通过主机名访问)| `hostname: web-node-1` || `dns` | 自定义容器DNS服务器 | `dns: 8.8.8.8` |#### (3)存储配置(数据持久化)| 参数 | 含义 | 示例 ||--------------|----------------------------------------------------------------------|----------------------------------------------------------------------|| `volumes` | 挂载数据卷/宿主机目录(Swarm推荐命名卷)| ```yamlservices: web: volumes: - nginx-data:/usr/share/nginx/html # 命名卷挂载 - ./conf:/etc/nginx/conf.d:ro # 宿主机目录挂载(ro只读)volumes: nginx-data: # 顶层定义命名卷,默认local驱动``` || `tmpfs` | 挂载临时文件系统(容器重启后数据丢失)| `tmpfs: /tmp`(容器内/tmp目录为临时存储)|| `storage_opt`| 容器存储驱动选项(如指定存储大小)| `storage_opt: size=10G`(限制容器存储10GB)|#### (4)调度与高可用配置(Swarm核心)| 参数 | 含义 | 示例 ||--------------|----------------------------------------------------------------------|----------------------------------------------------------------------|| `deploy` | Swarm专属部署配置(核心!包含副本数、调度策略、重启策略等)| ```yamldeploy: replicas: 3 # 服务副本数(复制服务) mode: replicated # 服务类型:replicated/global placement: # 节点调度规则 constraints: # 节点约束(只部署到符合条件的节点) - node.role == worker # 仅部署到工作节点 - node.labels.env == prod # 仅部署到打了env=prod标签的节点 preferences: # 调度偏好(非强制) - spread: node.labels.zone # 按zone标签分散部署 resources: # 资源限制 limits: # 资源上限 cpus: '0.5' # 最多使用0.5核CPU memory: 512M # 最多使用512MB内存 reservations: # 资源预留(保证分配) cpus: '0.2' memory: 256M restart_policy: # 重启策略 condition: on-failure # 重启条件:on-failure/any/unless-stopped max_attempts: 3 # 最大重启次数 delay: 5s # 重启延迟 update_config: # 滚动更新配置 parallelism: 1 # 每次更新1个副本 delay: 10s # 副本更新间隔 failure_action: rollback # 更新失败回滚 rollback_config: # 回滚配置 parallelism: 1 delay: 10s``` || `healthcheck`| 容器健康检查(Swarm根据检查结果重启故障容器)| ```yamlhealthcheck: test: ["CMD", "curl", "-f", "http://localhost"] # 检查命令 interval: 30s # 检查间隔 timeout: 10s # 超时时间 retries: 3 # 重试次数(失败3次标记为不健康) start_period: 30s # 容器启动后延迟检查``` |#### (5)密钥与配置项(敏感信息/配置文件)| 参数 | 含义 | 示例 ||--------------|----------------------------------------------------------------------|----------------------------------------------------------------------|| `secrets` | 挂载敏感信息(如密码、证书,Swarm加密存储)| ```yamlservices: db: secrets: - source: mysql-root-pass # 密钥名 target: /run/secrets/mysql-pass # 容器内挂载路径 mode: 0400 # 文件权限secrets: mysql-root-pass: file: ./mysql-pass.txt # 从本地文件加载 # 或从Docker Secrets创建:external: true``` || `configs` | 挂载非敏感配置文件(如nginx.conf,比卷挂载更安全)| ```yamlservices: web: configs: - source: nginx-conf target: /etc/nginx/nginx.confconfigs: nginx-conf: file: ./nginx.conf``` |### 3.3 完整YAML示例(Nginx服务)```yamlversion: '3.8'services: nginx: image: nginx:1.25 command: ["nginx", "-g", "daemon off;"] environment: - TZ=Asia/Shanghai ports: - target: 80 published: 80 protocol: tcp mode: ingress networks: - nginx-network volumes: - nginx-data:/usr/share/nginx/html deploy: replicas: 2 mode: replicated placement: constraints: - node.role == worker resources: limits: cpus: '0.5' memory: 256M restart_policy: condition: on-failure max_attempts: 3 update_config: parallelism: 1 delay: 10s healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 30s timeout: 10s retries: 3networks: nginx-network: driver: overlay # Swarm集群网络驱动volumes: nginx-data: driver: local # 本地数据卷3.4 完整多服务Stack编排示例(MySQL+Redis+微服务)
3.4.1 场景说明
模拟中小型微服务架构部署场景:
- MySQL:作为核心数据库,开启数据持久化,通过secrets管理root密码,限制资源使用;
- Redis:作为微服务缓存,开启RDB持久化,仅允许集群内访问;
- Spring Boot微服务:业务服务,连接MySQL和Redis,对外暴露API端口,配置健康检查和自动重启。
3.4.2 完整YAML配置(带详细注释)
version: '3.8'# 1. 定义集群网络(所有服务接入同一overlay网络,实现内网通信)networks:microservice-network: driver:overlay# Swarm集群必须用overlay驱动 attachable:true# 允许外部容器接入(可选)# 2. 定义数据卷(持久化MySQL/Redis数据)volumes:mysql-data:# MySQL数据卷 driver:localredis-data:# Redis数据卷 driver:local# 3. 定义密钥(存储MySQL敏感密码,避免硬编码)secrets:mysql-root-password:# root密码密钥 file:./mysql-root-pass.txt# 本地文件存储密码(需提前创建)mysql-app-password:# 微服务连接数据库的密码 file:./mysql-app-pass.txt# 4. 核心服务配置services:# 4.1 MySQL服务mysql: image:mysql:8.0# 稳定版MySQL 8.0 environment: -TZ=Asia/Shanghai -MYSQL_DATABASE=app_db# 自动创建业务数据库 -MYSQL_USER=app_user # 创建微服务专用用户 # 从secrets加载密码(避免硬编码) -MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root-password -MYSQL_PASSWORD_FILE=/run/secrets/mysql-app-password networks: -microservice-network volumes: -mysql-data:/var/lib/mysql# 挂载数据卷持久化数据 # 可选:挂载自定义my.cnf配置文件 # - ./my.cnf:/etc/mysql/conf.d/my.cnf:ro secrets: -mysql-root-password -mysql-app-password deploy: replicas:1# MySQL建议单副本(多副本需主从) placement: constraints: -node.role==worker# 仅部署到工作节点 -node.labels.db==mysql# 仅部署到打了db=mysql标签的节点(可选) resources: limits:# 资源上限 cpus:'1.0' memory:1G reservations:# 资源预留 cpus:'0.5' memory:512M restart_policy: condition:unless-stopped# 除非手动停止,否则一直重启 healthcheck: # 健康检查:连接数据库并执行简单查询 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$(cat /run/secrets/mysql-root-password)"] interval:10s timeout:5s retries:5 start_period:30s# 容器启动后延迟30s再检查(MySQL启动慢)# 4.2 Redis服务redis: image:redis:7.0# Redis 7.0稳定版 command: ["redis-server", "--appendonly", "no", "--save", "900", "1", "--save", "300", "10"] # 开启RDB持久化 environment: -TZ=Asia/Shanghai networks: -microservice-network volumes: -redis-data:/data# 持久化Redis数据 deploy: replicas:1# 单副本(集群需Redis Cluster) placement: constraints: -node.role==worker resources: limits: cpus:'0.5' memory:512M restart_policy: condition:unless-stopped healthcheck: test: ["CMD", "redis-cli", "ping"] interval:5s timeout:3s retries:3# 4.3 Spring Boot微服务app-service: # 替换为你自己的微服务镜像(需提前推送到镜像仓库或集群节点本地存在) image:your-registry/app-service:1.0.0 environment: -TZ=Asia/Shanghai # 微服务配置(通过服务名访问MySQL/Redis,Swarm内置DNS解析) -SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/app_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai -SPRING_DATASOURCE_USERNAME=app_user -SPRING_DATASOURCE_PASSWORD_FILE=/run/secrets/mysql-app-password -SPRING_REDIS_HOST=redis -SPRING_REDIS_PORT=6379 ports: -target:8080 published:8080 protocol:tcp mode:ingress# Swarm负载均衡,所有节点均可访问8080端口 networks: -microservice-network secrets: -mysql-app-password deploy: replicas:2# 微服务部署2个副本,实现负载均衡 placement: constraints: -node.role==worker resources: limits: cpus:'1.0' memory:1G restart_policy: condition:on-failure max_attempts:5 delay:10s update_config: parallelism:1# 滚动更新:每次更新1个副本 delay:20s # 副本更新间隔20s failure_action:rollback# 更新失败自动回滚 healthcheck: # 检查微服务健康接口(需微服务实现/actuator/health端点) test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval:15s timeout:5s retries:3 start_period:60s# 微服务启动较慢,延迟检查3.4.3 部署前准备
- 创建密码文件(与YAML同目录):# 创建MySQL root密码文件
echo "YourRootPass123!" > mysql-root-pass.txt
# 创建微服务数据库用户密码文件
echo "YourAppPass456!" > mysql-app-pass.txt
# 限制文件权限(安全最佳实践)
chmod 600 mysql-root-pass.txt mysql-app-pass.txt - 准备微服务镜像:
- 将微服务打包为Docker镜像,并推送到集群可访问的镜像仓库(如Harbor、Docker Hub);
- 替换YAML中image: your-registry/app-service:1.0.0为实际镜像地址。
- (可选)给节点打标签(匹配MySQL的调度约束):# 在目标工作节点执行,标记该节点为MySQL专用
docker node update --label-add db=mysql worker-node-1
3.4.4 部署命令
# 1. 部署整个栈(命名为microservice-stack)docker stack deploy -c docker-stack.yml microservice-stack# 2. 查看栈内服务状态docker stack services microservice-stack# 3. 查看微服务副本日志(排查问题)docker service logs -f microservice-stack_app-service# 4. 扩缩容微服务(如扩容到3个副本)docker service scale microservice-stack_app-service=3# 5. 移除整个栈docker stack rm microservice-stack四、实操部署命令(补充)
写完YAML后,通过以下命令部署到Swarm集群:
# 1. 初始化Swarm集群(仅在管理节点执行)docker swarm init --advertise-addr 你的管理节点IP# 2. 添加工作节点(根据init输出的命令执行)docker swarm join --token 令牌 管理节点IP:2377# 3. 部署栈(基于YAML文件)docker stack deploy -c docker-stack.yml nginx-stack# 4. 查看服务状态docker stack services nginx-stack# 5. 扩缩容服务docker service scale nginx-stack_nginx=3# 6. 移除栈docker stack rm nginx-stack五、总结
核心关键点回顾
- Docker Swarm核心:轻量级集群编排工具,核心组件是节点(管理/工作)、服务、任务,通过Raft算法保证管理节点高可用;
- YAML配置核心:services节点是核心,deploy参数是Swarm专属(副本数、调度、更新策略),ports推荐published/target格式,敏感信息用secrets;
- 多服务编排要点:
- 所有服务接入同一overlay网络,通过服务名实现内网通信,避免端口冲突;
- 数据库/缓存类服务建议单副本+数据卷持久化,微服务可多副本实现负载均衡;
- 敏感信息(密码、证书)必须用secrets管理,禁止硬编码在YAML中;
- 为所有服务配置healthcheck和restart_policy,提升服务可用性;
- 最佳实践:
- 管理节点至少3个保证高可用,工作节点按需扩展;
- 用overlay网络实现服务间通信,避免宿主机端口冲突;
- 通过healthcheck和restart_policy保证服务可用性;
- 敏感信息用secrets,非敏感配置用configs,避免硬编码。
适用场景
Docker Swarm适合中小型应用、快速落地的集群场景,相比K8s学习成本低、运维简单;若需复杂编排(如自动扩缩容、高级网络策略),可考虑K8s。