Docker Swarm 功能详细讲解

一、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 集成度。

相关推荐
阳宗德12 小时前
基于CentOS Linux release 7.1实现了Oracle Database 11g R2 企业版容器化运行
linux·数据库·docker·oracle·centos
·云扬·12 小时前
MySQL运维效率提升:实用SQL语句合集
运维·sql·mysql
Connie145112 小时前
K8s修改Kubelet过程(命令版本)
容器·kubernetes·kubelet
草莓熊Lotso12 小时前
脉脉独家【AI创作者xAMA】| 多维价值与深远影响
运维·服务器·数据库·人工智能·脉脉
liulilittle12 小时前
libxdp: No bpffs found at /sys/fs/bpf
linux·运维·服务器·开发语言·c++
Byte Beat12 小时前
ubuntu安装docker
linux·ubuntu·docker
HIT_Weston12 小时前
88、【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(二)
linux·运维·ubuntu
七七powerful12 小时前
docker28.1.1和docker-compose v.2.35.1安装
java·docker·eureka
single-life12 小时前
不借助docker desktop 本地windows安装nabula
windows·docker·容器·nebula
liulilittle12 小时前
AF_XDP开发环境(Ubuntu24.04.3)
linux·运维·服务器·ubuntu