Docker Swarm 完全指南:从原理到实战

Docker Swarm 完全指南:从原理到实战

前言

在现代应用部署中,单机容器化已经无法满足大规模应用的需求。Docker Swarm 作为 Docker 原生的集群管理和编排工具,提供了一个简单 yet 强大的方式来部署和管理跨多主机的容器化应用。本文将深入探讨 Docker Swarm 的各个方面,从核心概念到实战部署,帮助你掌握生产级的容器编排技术。

一、Docker Swarm 是什么?

1.1 核心定义

Docker Swarm 是 Docker 原生的集群管理和编排工具,它允许用户将多个 Docker 主机聚合成一个虚拟的单一系统,提供高可用性、负载均衡和弹性扩展能力。

1.2 Swarm 模式 vs 单机 Docker

特性 单机 Docker Docker Swarm
主机数量 单台 多台(集群)
高可用性 内置支持
服务发现 手动配置 自动服务发现
负载均衡 需要外部工具 内置负载均衡
扩展性 手动扩展 一键扩展
滚动更新 手动操作 自动滚动更新

1.3 Swarm 在容器编排生态中的位置

  • Docker Swarm:轻量级、易上手、Docker 原生
  • Kubernetes:功能强大、生态丰富、学习曲线陡峭
  • Nomad:灵活、多云支持、相对简单

二、Docker Swarm 架构与工作原理

2.1 集群架构

text 复制代码
┌─────────────────────────────────────────────────┐
│                   Swarm Cluster                 │
│                                                 │
│  ┌─────────────┐    ┌─────────────┐            │
│  │  Manager    │    │  Manager    │            │
│  │   Node      │    │   Node      │            │
│  │ (Leader)    │    │ (Replica)   │            │
│  └─────────────┘    └─────────────┘            │
│          │               │                     │
│          ├───────────────┤                     │
│          ▼               ▼                     │
│  ┌─────────────┐    ┌─────────────┐            │
│  │  Worker     │    │  Worker     │            │
│  │   Node      │    │   Node      │            │
│  └─────────────┘    └─────────────┘            │
│                                                 │
└─────────────────────────────────────────────────┘

2.2 核心组件

Raft 一致性算法

  • 用于 Manager 节点间的状态一致性
  • 需要多数节点在线才能进行集群管理操作
  • 推荐使用 3 或 5 个 Manager 节点实现高可用

Dispatcher

  • 负责将任务分配给合适的节点
  • 监控任务状态并处理故障

Scheduler

  • 根据策略决定任务在哪个节点运行
  • 支持多种调度策略

Node

  • 每个节点都有唯一的 ID 和角色
  • 节点间通过 TLS 进行安全通信

2.3 工作流程

  1. 服务创建:用户通过 Manager 节点创建服务
  2. 调度决策:Scheduler 根据策略选择运行节点
  3. 任务分配:Dispatcher 将任务分配给 Worker 节点
  4. 状态同步:所有节点通过 gossip 协议同步状态
  5. 健康检查:Manager 监控节点和服务状态

三、核心概念详解

3.1 节点(Nodes)

Manager 节点

  • 负责集群管理任务
  • 维护集群状态
  • 调度服务
  • 提供 API 端点

Worker 节点

  • 执行容器任务
  • 接收 Manager 节点的指令
  • 报告任务状态
bash 复制代码
# 查看节点信息
docker node ls

# 查看节点详情
docker node inspect <node-name>

# 提升节点角色
docker node promote <node-name>

# 降级节点角色
docker node demote <node-name>

3.2 服务(Services)

服务是 Swarm 的核心概念,定义了要运行的任务:

bash 复制代码
# 创建服务
docker service create --name web --replicas 3 nginx:latest

# 查看服务
docker service ls

# 查看服务详情
docker service ps web

# 扩展服务
docker service scale web=5

# 更新服务
docker service update --image nginx:1.23 web

3.3 任务(Tasks)

任务是调度的最小单元,对应一个运行的容器:

bash 复制代码
# 查看任务列表
docker service ps <service-name>

# 任务状态包括:New, Pending, Assigned, Preparing, Running, Complete, Failed, Shutdown, Rejected, Orphaned

3.4 集群(Cluster)

集群是一组节点的集合:

bash 复制代码
# 初始化集群
docker swarm init --advertise-addr <MANAGER-IP>

# 加入集群
docker swarm join --token <TOKEN> <MANAGER-IP>:2377

# 查看集群信息
docker info

四、调度策略与模式

4.1 内置调度策略

Spread 策略(默认)

  • 将任务均匀分布 across 所有节点
  • 避免单节点过载
  • 最大化可用性
bash 复制代码
# 使用spread策略(默认)
docker service create --name web --replicas 5 nginx:latest

BinPack 策略

  • 尽可能将任务打包到少数节点
  • 节省资源,提高利用率
  • 可能降低可用性
bash 复制代码
# 使用binpack策略
docker service create --name web --replicas 5 --placement-pref spread=node.labels.zone nginx:latest

Random 策略

  • 随机选择节点
  • 主要用于测试

4.2 高级调度约束

节点标签约束

bash 复制代码
# 给节点添加标签
docker node update --label-add zone=east node1
docker node update --label-add zone=west node2

# 使用标签约束
docker service create \
  --name web \
  --replicas 3 \
  --constraint 'node.labels.zone == east' \
  nginx:latest

资源约束

bash 复制代码
# 基于节点角色
docker service create \
  --name web \
  --constraint 'node.role == manager' \
  nginx:latest

# 基于主机名
docker service create \
  --name web \
  --constraint 'node.hostname != node3' \
  nginx:latest

4.3 放置偏好(Placement Preferences)

bash 复制代码
# 多个放置偏好
docker service create \
  --name web \
  --replicas 6 \
  --placement-pref 'spread=node.labels.datacenter' \
  --placement-pref 'spread=node.labels.rack' \
  nginx:latest

五、Docker Swarm 核心特性

5.1 高可用性

服务副本

bash 复制代码
# 创建高可用服务
docker service create \
  --name database \
  --replicas 3 \
  --update-parallelism 1 \
  --update-delay 10s \
  postgres:13

节点故障转移

  • 自动检测节点故障
  • 在健康节点上重新调度任务
  • 保持期望的副本数量

5.2 滚动更新

bash 复制代码
# 配置滚动更新策略
docker service create \
  --name web \
  --replicas 5 \
  --update-parallelism 2 \
  --update-delay 10s \
  --update-failure-action rollback \
  nginx:1.20

# 触发滚动更新
docker service update \
  --image nginx:1.21 \
  --update-parallelism 1 \
  --update-delay 30s \
  web

5.3 服务回滚

bash 复制代码
# 自动回滚配置
docker service create \
  --name web \
  --replicas 5 \
  --rollback-parallelism 1 \
  --rollback-delay 10s \
  --rollback-max-failure-ratio 0.2 \
  nginx:latest

# 手动回滚
docker service rollback web

5.4 配置和密钥管理

bash 复制代码
# 创建配置
echo "database_url: postgresql://user:pass@db:5432/app" | docker config create app-config -

# 创建密钥
echo "secret-password" | docker secret create db-password -

# 使用配置和密钥
docker service create \
  --name app \
  --config source=app-config,target=/app/config.yaml \
  --secret source=db-password,target=/run/secrets/db-password \
  my-app:latest

六、Swarm 网络管理

6.1 网络架构

Overlay 网络

bash 复制代码
# 创建overlay网络
docker network create \
  --driver overlay \
  --subnet 10.0.0.0/24 \
  --attachable \
  my-overlay-net

Ingress 网络

  • 默认的 overlay 网络
  • 处理入站流量
  • 提供负载均衡

docker_gwbridge 网络

  • 连接 overlay 网络和物理网络
  • 处理出站流量

6.2 服务发现和负载均衡

内部负载均衡

bash 复制代码
# 服务间通过服务名自动发现和负载均衡
docker service create \
  --name web \
  --network my-overlay-net \
  --replicas 3 \
  nginx:latest

# 在另一个服务中可以通过"web"主机名访问
docker service create \
  --name app \
  --network my-overlay-net \
  my-app:latest  # 可以在代码中访问 http://web:80

外部负载均衡

bash 复制代码
# 发布端口到外部
docker service create \
  --name web \
  --publish published=8080,target=80 \
  --replicas 3 \
  nginx:latest

6.3 网络隔离和安全

bash 复制代码
# 创建内部网络(不对外暴露)
docker network create \
  --driver overlay \
  --internal \
  internal-net

# 网络加密
docker network create \
  --driver overlay \
  --opt encrypted \
  secure-net

七、安装和部署实战

7.1 环境准备

准备 3 台 Linux 主机(1 Manager + 2 Workers):

  • Manager: 192.168.1.10
  • Worker1: 192.168.1.11
  • Worker2: 192.168.1.12

7.2 初始化 Swarm 集群

在 Manager 节点上

bash 复制代码
# 初始化Swarm
docker swarm init --advertise-addr 192.168.1.10

# 输出示例:
Swarm initialized: current node (xyz) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-0xxx 192.168.1.10:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

获取加入令牌

bash 复制代码
# 获取worker加入令牌
docker swarm join-token worker

# 获取manager加入令牌
docker swarm join-token manager

在 Worker 节点上

bash 复制代码
# 加入Swarm集群
docker swarm join --token SWMTKN-1-0xxx 192.168.1.10:2377

7.3 验证集群状态

bash 复制代码
# 在Manager节点查看集群状态
docker node ls

# 输出示例:
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
x1y2z3 *   manager1   Ready     Active         Leader           20.10.7
a2b3c4      worker1    Ready     Active                          20.10.7
d4e5f6      worker2    Ready     Active                          20.10.7

八、实战案例:部署高可用 Web 应用

8.1 部署架构

text 复制代码
┌─────────────────────────────────────────────────┐
│                 Swarm Cluster                   │
│                                                 │
│  ┌─────────────┐    ┌─────────────┐            │
│  │  Manager    │    │   Worker    │            │
│  │   Node      │    │   Node      │            │
│  │             │    │             │            │
│  │  ▢ Web      │    │  ▢ Web      │            │
│  │  ▢ Redis    │    │  ▢ Web      │            │
│  │  ▢ Nginx    │    │             │            │
│  └─────────────┘    └─────────────┘            │
│          │               │                     │
│          └───────────────┘                     │
│                  │                             │
│  ┌─────────────┐ │                             │
│  │   Worker    │ │                             │
│  │   Node      │ │                             │
│  │             │ │                             │
│  │  ▢ Web      │ │                             │
│  │  ▢ Redis    │ │                             │
│  └─────────────┘ │                             │
│                  ▼                             │
│            Load Balancer                       │
│                 │                              │
│                 ▼                              │
│            External Users                      │
└─────────────────────────────────────────────────┘

8.2 创建 Overlay 网络

bash 复制代码
# 创建用于应用通信的overlay网络
docker network create \
  --driver overlay \
  --subnet 10.0.1.0/24 \
  --attachable \
  app-network

8.3 部署 Redis 服务

bash 复制代码
# 创建Redis服务
docker service create \
  --name redis \
  --network app-network \
  --replicas 2 \
  --update-parallelism 1 \
  --update-delay 10s \
  --restart-condition any \
  --health-cmd "redis-cli ping" \
  --health-interval 5s \
  --health-timeout 3s \
  --health-retries 3 \
  redis:6-alpine

8.4 部署 Web 应用服务

bash 复制代码
# 创建Web应用服务
docker service create \
  --name webapp \
  --network app-network \
  --replicas 4 \
  --update-parallelism 2 \
  --update-delay 15s \
  --restart-condition any \
  --env REDIS_HOST=redis \
  --env NODE_ENV=production \
  --limit-memory 512M \
  --reserve-memory 256M \
  my-webapp:latest

8.5 部署 Nginx 负载均衡器

bash 复制代码
# 创建Nginx配置
docker config create nginx-config ./nginx.conf

# 创建Nginx服务
docker service create \
  --name nginx \
  --network app-network \
  --publish published=80,target=80,mode=host \
  --publish published=443,target=443,mode=host \
  --config source=nginx-config,target=/etc/nginx/nginx.conf \
  --mode global \
  nginx:alpine

8.6 监控和运维

bash 复制代码
# 查看服务状态
docker service ls

# 查看详细任务状态
docker service ps webapp

# 扩展Web服务
docker service scale webapp=6

# 滚动更新Web服务
docker service update \
  --image my-webapp:2.0 \
  --update-parallelism 1 \
  --update-delay 30s \
  webapp

# 查看服务日志
docker service logs -f webapp

# 监控节点资源
docker node ps $(docker node ls -q)

九、高级部署模式

9.1 全局服务(Global Services)

bash 复制代码
# 在每个节点上运行监控代理
docker service create \
  --name node-exporter \
  --mode global \
  --mount type=bind,source=/proc,target=/host/proc \
  --mount type=bind,source=/sys,target=/host/sys \
  prom/node-exporter:latest

9.2 多架构部署

bash 复制代码
# 部署多架构服务
docker service create \
  --name multi-arch-app \
  --placement-pref 'spread=node.labels.arch' \
  --constraint 'node.labels.arch == x86_64' \
  --constraint 'node.labels.arch == arm64' \
  multi-arch-app:latest

9.3 金丝雀发布

bash 复制代码
# 第一步:部署新版本的部分实例
docker service create \
  --name webapp-canary \
  --network app-network \
  --replicas 2 \
  my-webapp:2.0

# 第二步:验证金丝雀版本
# 第三步:逐步替换旧版本
docker service update \
  --image my-webapp:2.0 \
  --update-parallelism 1 \
  --update-delay 30s \
  webapp

十、故障排查和维护

10.1 常见问题排查

bash 复制代码
# 查看集群健康状态
docker node ls

# 检查服务状态
docker service ls
docker service ps <service-name>

# 查看节点资源使用情况
docker node ps --format pretty $(docker node ls -q)

# 检查网络连接
docker network inspect app-network

# 查看容器日志
docker service logs <service-name>

10.2 集群维护

bash 复制代码
# 排空节点(准备维护)
docker node update --availability drain node1

# 恢复节点
docker node update --availability active node1

# 备份Swarm状态
docker swarm init --force-new-cluster

# 安全离开集群
docker swarm leave --force

10.3 安全最佳实践

bash 复制代码
# 轮换加入令牌
docker swarm join-token --rotate worker
docker swarm join-token --rotate manager

# 使用TLS加密
docker swarm init --advertise-addr <ip> --tlsverify

# 限制管理节点访问
iptables -A DOCKER-USER -p tcp --dport 2377 -j DROP
iptables -A DOCKER-USER -s <trusted-ip> -p tcp --dport 2377 -j ACCEPT

总结

Docker Swarm 提供了一个强大 yet 简单的容器编排解决方案,特别适合中小型企业和刚刚开始容器化旅程的团队。通过本文的深入学习,你应该能够:

  1. 理解 Swarm 的核心架构和工作原理
  2. 掌握关键概念:节点、服务、任务、集群
  3. 配置高级调度策略和放置约束
  4. 部署生产级应用 with 高可用性和滚动更新
  5. 管理 Swarm 网络和安全配置
  6. 进行故障排查和日常维护

Swarm 的优势在于其与 Docker 生态系统的无缝集成和较低的学习曲线,让你能够快速构建和管理生产级的容器化应用。

记住,选择编排工具时应该基于团队的技术水平、应用规模和业务需求。对于大多数场景,Docker Swarm 提供了一个完美的平衡点 between 功能复杂性和易用性。

相关推荐
AAA修煤气灶刘哥2 小时前
从 Timer 到 XXL-Job,定时任务调度的 “进化史”,看完再也不怕漏跑任务~
java·后端·架构
shark_chili2 小时前
深入GPU核心:理解现代并行计算的硬件架构
后端
乘风破浪酱524362 小时前
MyBatis-Plus UserMpper接口示例
后端
无奈何杨2 小时前
风控系统的事中与事后一致性与闭环
前端·后端
这里有鱼汤2 小时前
为什么指数涨你却亏钱?80%的人忽略的市场宽度指标揭晓,我用Python实现了(附源码)
后端·python
ss2732 小时前
基于Springboot + vue实现的高校大学生竞赛项目管理系统
vue.js·spring boot·后端
念念01072 小时前
Flask 博客系统(Flask Blog System)
后端·python·flask
托比-马奎尔3 小时前
初识SpringBoot
java·spring boot·后端