一、Swarm 核心架构
1. Swarm 模式 vs 传统 Docker
传统 Docker:
┌─────────────────┐
│ Docker Host │
│ ┌───────────┐ │
│ │ Container │ │
│ └───────────┘ │
└─────────────────┘
Swarm 模式:
┌─────────────────────────────────────┐
│ Docker Swarm Cluster │
│ ┌───────────┐ ┌───────────┐ │
│ │ Manager 1 │ │ Manager 2 │ │
│ └───────────┘ └───────────┘ │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ Worker 1 │ │ Worker 2 │ │
│ │ Container │ │ Container │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────────┘
2. Raft 一致性算法
- Swarm 管理节点使用 Raft 实现一致性
- 要求多数节点(N/2 + 1)在线才能工作
- 推荐节点数量:3、5、7(奇数)
bash
# 查看 Raft 状态
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
x12** manager1 Ready Active Leader 20.10.7
y34** manager2 Ready Active Reachable 20.10.7
z56** manager3 Ready Active Reachable 20.10.7
二、服务部署功能详解
1. 服务创建参数详解
bash
docker service create \
--name web \
# 部署模式
--mode replicated \ # 或 global(每个节点运行一个实例)
--replicas 3 \
# 资源限制
--limit-cpu 0.5 \ # 限制 CPU 使用率
--limit-memory 512M \ # 限制内存
--reserve-cpu 0.1 \ # 预留 CPU
--reserve-memory 128M \ # 预留内存
# 更新策略
--update-delay 10s \ # 更新延迟
--update-parallelism 2 \ # 同时更新数量
--update-failure-action pause \ # 失败时暂停
--update-order start-first \ # 先启动新容器
--update-monitor 30s \ # 监控健康状态时间
# 回滚策略
--rollback-delay 5s \
--rollback-parallelism 1 \
--rollback-failure-action pause \
--rollback-monitor 30s \
--rollback-max-failure-ratio 0.2 \
# 重启策略
--restart-condition on-failure \
--restart-delay 5s \
--restart-max-attempts 3 \
--restart-window 120s \
# 健康检查
--health-cmd "curl -f http://localhost/health || exit 1" \
--health-interval 5s \
--health-retries 3 \
--health-start-period 30s \
--health-timeout 3s \
# 放置约束
--constraint 'node.role==worker' \
--constraint 'node.labels.zone==east' \
--constraint 'node.hostname!=node3' \
--constraint 'engine.labels.operatingsystem==ubuntu' \
# 放置偏好
--placement-pref 'spread=node.labels.datacenter' \
--placement-pref 'spread=node.labels.rack' \
# 网络配置
--network my-overlay \
--publish published=80,target=80,protocol=tcp,mode=ingress \
--publish published=8080,target=80,protocol=tcp,mode=host \
# 存储
--mount type=volume,source=app-data,target=/data,readonly=false \
--mount type=bind,source=/host/path,target=/container/path \
--mount type=tmpfs,target=/tmp,tmpfs-size=1000000 \
# 配置和密钥
--config source=app.conf,target=/app/config.conf \
--secret source=db_password,target=/run/secrets/db_password \
# 环境变量和标签
--env MODE=production \
--env-file .env \
--label com.example.version="1.0" \
--label com.example.description="Web service" \
# 日志
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
# 工作目录和用户
--workdir /app \
--user appuser \
# 主机名和域名
--hostname web-service \
--dns 8.8.8.8 \
--dns-search example.com \
# 容器规格
--host "web:127.0.0.1" \
--entrypoint "/app/start.sh" \
nginx:latest
2. 服务更新策略详解
bash
# 1. 滚动更新(默认)
docker service update \
--image nginx:1.20 \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action rollback \
web
# 2. 分批更新
docker service update \
--image nginx:1.21 \
--update-parallelism 1 \
--update-delay 30s \
--update-order stop-first \
web
# 3. 蓝绿部署模式
# 创建新版本服务
docker service create --name web-v2 --network web-net nginx:1.21
# 逐步迁移流量(通过外部负载均衡器)
# 4. 金丝雀发布
# 先更新部分实例
docker service update --image nginx:1.21 --replicas 1 web
# 验证后扩展新版本
docker service update --image nginx:1.21 --replicas 3 web
三、网络功能详解
1. 网络类型
bash
# 1. Overlay 网络(跨节点通信)
docker network create \
--driver overlay \
--attachable \ # 允许独立容器加入
--subnet 10.0.9.0/24 \
--gateway 10.0.9.1 \
--ip-range 10.0.9.128/25 \
--opt encrypted \ # 网络加密
my-overlay
# 2. Ingress 网络(服务发布)
# 自动创建,用于服务端口发布
docker service create \
--name web \
--publish published=8080,target=80,protocol=tcp,mode=ingress \
nginx
# 3. Host 模式网络
docker service create \
--name web \
--publish published=8080,target=80,protocol=tcp,mode=host \
--mode global \ # host 模式通常与 global 模式一起使用
nginx
# 4. DNSRR(DNS轮询)负载均衡
docker service create \
--name api \
--endpoint-mode dnsrr \ # 不使用 VIP,使用 DNS 轮询
--network my-overlay \
api:latest
2. 网络拓扑
外部请求 → Ingress 网络 → 路由网格 → 服务 VIP → 容器
(端口发布) (所有节点) (虚拟IP) (实际容器)
四、存储功能详解
1. 卷类型
bash
# 1. 本地卷(默认)
docker volume create app-data
# 2. NFS 卷
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/path/to/nfs/share \
nfs-volume
# 3. CIFS/SMB 卷
docker volume create \
--driver local \
--opt type=cifs \
--opt o=username=user,password=pass,file_mode=0777,dir_mode=0777 \
--opt device=//192.168.1.100/share \
cifs-volume
# 4. 绑定挂载
docker service create \
--mount type=bind,src=/host/path,dst=/container/path \
nginx
2. 卷在服务中的使用
yaml
version: '3.8'
services:
db:
image: mysql:8.0
volumes:
# 命名卷
- db_data:/var/lib/mysql
# 绑定挂载
- /host/my.cnf:/etc/mysql/my.cnf:ro
# 临时卷
- type: tmpfs
target: /tmp
tmpfs:
size: 100000000 # 100MB
# 卷驱动选项
- type: volume
source: db_data
target: /data
volume:
nocopy: true # 不复制现有数据
volumes:
db_data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,nolock,soft,rw
device: ":/exports/db_data"
五、配置和密钥管理
1. 配置管理
bash
# 创建配置
echo "server {
listen 80;
server_name localhost;
}" | docker config create nginx-config -
# 查看配置
docker config ls
docker config inspect nginx-config
# 在服务中使用配置
docker service create \
--name web \
--config source=nginx-config,target=/etc/nginx/conf.d/default.conf \
--config source=nginx-config,target=/etc/nginx/conf.d/app.conf,mode=0440,uid=100,gid=101 \
nginx
# 更新配置(创建新版本)
echo "server {
listen 80;
server_name example.com;
}" | docker config create nginx-config-v2 -
# 更新服务配置
docker service update \
--config-rm nginx-config \
--config-add source=nginx-config-v2,target=/etc/nginx/conf.d/default.conf \
web
2. 密钥管理
bash
# 创建密钥
echo "SuperSecretPassword123" | docker secret create db_password -
# 生成随机密钥
openssl rand -base64 32 | docker secret create api_key -
# 从文件创建密钥
docker secret create ssl_cert ./ssl/server.crt
# 在服务中使用密钥
docker service create \
--name db \
--secret source=db_password,target=/run/secrets/db_password \
--secret source=api_key \
--secret source=ssl_cert,target=/etc/ssl/server.crt \
mysql:8.0
# 环境变量中使用密钥
docker service create \
--name app \
--secret source=db_password,target=DB_PASSWORD \
--env DB_PASSWORD_FILE=/run/secrets/db_password \
myapp
六、节点管理和标签
1. 节点操作
bash
# 查看节点详细信息
docker node inspect self --pretty
docker node inspect node1
# 节点可用性管理
docker node update --availability active node1 # 可调度新任务
docker node update --availability pause node1 # 不调度新任务,现有任务继续运行
docker node update --availability drain node1 # 不调度新任务,并迁移现有任务
# 节点角色管理
docker node promote node2 # 提升为管理节点
docker node demote node1 # 降级为工作节点
# 节点标签管理
docker node update --label-add zone=east node1
docker node update --label-add disk=ssd node1
docker node update --label-add gpu=true node1
docker node update --label-rm zone node1
# 引擎标签(Docker Daemon)
dockerd --label com.example.storage=ssd
2. 使用节点标签调度
bash
# 创建带标签的服务
docker service create \
--name db \
--constraint 'node.labels.storage == ssd' \
--constraint 'node.labels.zone == east' \
--constraint 'node.hostname != db-backup-01' \
mysql
# 全局模式 + 约束
docker service create \
--name logging \
--mode global \
--constraint 'node.role == worker' \
--constraint 'node.labels.logging == enabled' \
fluentd
# 放置偏好(尽量分散部署)
docker service create \
--name web \
--replicas 6 \
--placement-pref 'spread=node.labels.zone' \
--placement-pref 'spread=node.labels.rack' \
nginx
七、安全功能
1. TLS 和安全通信
bash
# 使用 TLS 初始化集群
docker swarm init \
--advertise-addr 192.168.1.100 \
--cert-expiry 2160h \ # 证书有效期 90 天
--external-ca protocol=cfssl,url=https://ca.example.com \
--listen-addr 0.0.0.0:2377
# 轮换证书
docker swarm ca --rotate
# 查看证书信息
docker swarm update --cert-expiry 720h
# 限制管理 API 访问
dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
2. 网络安全策略
yaml
version: '3.8'
services:
web:
image: nginx
networks:
- frontend
- backend
deploy:
# 服务级别的安全选项
endpoint_mode: vip # 或 dnsrr
networks:
frontend:
driver: overlay
driver_opts:
encrypted: 'yes' # 启用网络加密
ipam:
config:
- subnet: "10.0.1.0/24"
backend:
driver: overlay
internal: true # 内部网络,不对外暴露
八、监控和日志
1. 服务监控
bash
# 实时查看服务状态
watch docker service ps web
# 查看服务事件
docker service events web
# 查看服务日志
docker service logs \
--tail 100 \
--follow \
--timestamps \
web
# 特定任务的日志
docker service logs web.1.abc123
# 资源使用统计
docker stats $(docker ps -q)
# 检查点(用于调试)
docker checkpoint create \
--checkpoint-dir=/tmp/checkpoints \
mycontainer mycheckpoint
2. 健康检查集成
yaml
version: '3.8'
services:
api:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
start_interval: 5s
deploy:
# 基于健康检查的更新
update_config:
failure_action: rollback
monitor: 60s
max_failure_ratio: 0.3
# 基于健康检查的放置
placement:
constraints:
- "node.health==healthy"
九、高级功能
1. 服务网格集成
bash
# 使用 Consul 作为外部 KV 存储
docker swarm init \
--advertise-addr 192.168.1.100 \
--default-addr-pool 10.10.0.0/16 \
--default-addr-pool-mask-length 24 \
--data-path-addr 192.168.1.100
# 服务发现配置
docker service create \
--name api \
--dns 192.168.1.53 \
--dns-search example.com \
--dns-option timeout:2 \
api:latest
2. 资源预留和限制
yaml
services:
app:
image: resource-intensive-app
deploy:
resources:
limits:
cpus: '2.0'
memory: 1G
pids: 100 # 进程数限制
reservations:
cpus: '0.5'
memory: 512M
devices:
- capabilities: [gpu]
count: 1
driver: nvidia
device_ids: ['0']
3. 故障恢复策略
bash
# 自动故障转移
docker service create \
--name high-availability \
--replicas 5 \
--restart-condition any \
--restart-max-attempts 10 \
--restart-window 120s \
--rollback-delay 0s \
--rollback-failure-action continue \
--rollback-monitor 20s \
--rollback-order stop-first \
ha-app:latest
十、最佳实践和技巧
1. 生产环境配置
bash
# 初始化生产集群
docker swarm init \
--advertise-addr $(hostname -i) \
--default-addr-pool 10.10.0.0/16 \
--default-addr-pool-mask-length 24 \
--data-path-addr $(hostname -i) \
--cert-expiry 2160h \
--max-snapshots 5 \
--snapshot-interval 10000
# 安全加固
docker swarm update \
--task-history-limit 50 \
--dispatcher-heartbeat 5s \
--node-cert-expiry 2160h \
--external-ca protocol=cfssl,url=https://ca.internal.com
2. 性能优化
bash
# 优化网络性能
docker network create \
--driver overlay \
--opt com.docker.network.driver.mtu=1450 \
--opt encrypted=false \ # 在内网中可关闭加密提升性能
perf-net
# 优化存储
docker volume create \
--driver local \
--opt type=xfs \
--opt o=noatime,nodiratime \
fast-volume
3. 备份和恢复
bash
# 备份服务配置
docker service inspect web > web-backup.json
# 备份 Swarm 状态
docker swarm init --force-new-cluster # 在灾难恢复时使用
# 备份卷数据
docker run --rm -v db_data:/volume -v /backup:/backup alpine \
tar czf /backup/db_data_$(date +%Y%m%d).tar.gz -C /volume ./
十一、故障排除
1. 常见问题诊断
bash
# 查看 Swarm 组件状态
docker info | grep -A 10 Swarm
# 检查 Raft 状态
docker node ls --format "table {{.ID}}\t{{.Hostname}}\t{{.ManagerStatus}}"
# 网络问题诊断
docker network inspect -v overlay_network
# 服务调度问题
docker service ps --no-trunc web
# 节点连接问题
docker node inspect --format='{{.Status.State}}' node1
# 查看 Swarm 日志
journalctl -u docker.service | grep swarm
2. 调试命令
bash
# 调试服务创建
docker service create --dry-run nginx
# 强制重新调度
docker service update --force web
# 重置 Swarm(危险操作)
docker swarm leave --force
docker system prune -a -f
docker swarm init
# 清理孤立资源
docker system prune --volumes -f
docker network prune -f
Docker Swarm 是一个功能完整的容器编排平台,提供了企业级的生产环境功能。虽然相比 Kubernetes 功能相对简化,但对于大多数中小型场景已经足够,并且具有更低的运维复杂性和更好的 Docker 集成度。