Docker Swarm教程#

技术介绍#

Docker Swarm是Docker原生的容器编排系统,用于管理和调度容器集群。它允许您将多个Docker主机组成一个集群,作为单一的虚拟系统进行管理。Docker Swarm提供了高可用性、负载均衡、滚动更新等企业级特性。

Docker Swarm核心概念#

  • 节点:Docker Swarm集群中的主机,可以是管理节点或工作节点
  • 服务:在Swarm集群中运行的容器定义,包括镜像、命令、端口等
  • 任务:服务的单个运行实例,是Swarm中的最小调度单位
  • 服务栈:一组相关的服务,通过Docker Compose文件定义
  • 负载均衡:Swarm内置的负载均衡,用于分发服务请求

Docker Swarm架构#

  • 管理节点:负责集群管理、服务调度和状态维护
  • 工作节点:负责运行容器任务
  • Raft一致性算法:确保集群状态的一致性
  • 服务发现:内置的服务发现机制,用于容器间通信

入门级使用#

初始化Docker Swarm#

初始化Docker Swarm集群:

# 在第一个节点上初始化Swarm
# --advertise-addr指定管理节点的IP地址
docker swarm init --advertise-addr 192.168.1.100

# 查看节点状态
docker node ls

# 获取加入工作节点的命令
docker swarm join-token worker

# 获取加入管理节点的命令
docker swarm join-token manager

# 在其他节点上加入Swarm
# 运行从join-token命令获得的命令

基本Docker Swarm命令#

使用Docker Swarm的基本命令:

# 查看节点状态
docker node ls

# 查看服务状态
docker service ls

# 查看任务状态
docker service ps service_name

# 创建服务
docker service create --name web --replicas 3 -p 80:80 nginx:latest

# 扩展服务
docker service scale web=5

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

# 删除服务
docker service rm web

# 查看集群信息
docker info

# 离开Swarm
docker swarm leave --force

基本服务管理#

管理Docker Swarm服务:

# 创建服务
docker service create \
  --name web \
  --replicas 3 \
  --publish 80:80 \
  --restart-condition on-failure \
  --update-delay 10s \
  nginx:latest

# 查看服务详情
docker service inspect web

# 查看服务日志
docker service logs web

# 查看服务的任务
docker service ps web

# 滚动更新服务
docker service update \
  --image nginx:alpine \
  --update-parallelism 2 \
  --update-delay 10s \
  web

# 回滚服务
docker service rollback web

初级使用#

Docker Swarm网络配置#

配置Docker Swarm网络:

# 查看网络
docker network ls

# 创建覆盖网络
docker network create --driver overlay my-network

# 创建服务时使用网络
docker service create \
  --name web \
  --network my-network \
  --replicas 3 \
  nginx:latest

# 创建内部网络
docker network create --driver overlay --internal internal-network

# 创建服务时使用内部网络
docker service create \
  --name db \
  --network internal-network \
  postgres:12

Docker Swarm存储配置#

配置Docker Swarm存储:

# 查看卷
docker volume ls

# 创建服务时使用卷
docker service create \
  --name db \
  --mount type=volume,source=db-data,target=/var/lib/postgresql/data \
  postgres:12

# 使用命名卷
docker volume create --name db-data

# 创建服务时使用命名卷
docker service create \
  --name db \
  --mount type=volume,source=db-data,target=/var/lib/postgresql/data \
  postgres:12

# 使用绑定挂载
docker service create \
  --name web \
  --mount type=bind,source=/path/to/html,target=/usr/share/nginx/html \
  nginx:latest

Docker Swarm服务约束#

使用Docker Swarm服务约束:

# 查看节点标签
docker node inspect --format '{{.Spec.Labels}}' node_name

# 添加节点标签
docker node update --label-add role=worker node_name
docker node update --label-add role=manager node_name

# 创建服务时使用节点约束
docker service create \
  --name web \
  --constraint node.role==worker \
  --replicas 3 \
  nginx:latest

# 使用标签约束
docker service create \
  --name db \
  --constraint node.labels.role==worker \
  --replicas 1 \
  postgres:12

# 使用节点ID约束
docker service create \
  --name cache \
  --constraint node.id==node_id \
  redis:6

中级使用#

Docker Swarm服务栈#

使用Docker Swarm服务栈:

# docker-compose.yml
version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
      update_config:
        parallelism: 2
        delay: 10s
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  db:
    image: postgres:12
    environment:
      POSTGRES_PASSWORD: password
    volumes:
      - db_data:/var/lib/postgresql/data
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager

volumes:
  db_data:

# 部署服务栈
docker stack deploy -c docker-compose.yml myapp

# 查看服务栈
docker stack ls

# 查看服务栈中的服务
docker stack services myapp

# 查看服务栈中的任务
docker stack ps myapp

# 移除服务栈
docker stack rm myapp

Docker Swarm服务配置#

配置Docker Swarm服务:

# 创建服务时配置资源限制
docker service create \
  --name web \
  --replicas 3 \
  --limit-cpu 0.5 \
  --limit-memory 512M \
  --reserve-cpu 0.25 \
  --reserve-memory 256M \
  nginx:latest

# 配置更新策略
docker service create \
  --name web \
  --replicas 3 \
  --update-delay 10s \
  --update-parallelism 2 \
  --update-failure-action rollback \
  nginx:latest

# 配置重启策略
docker service create \
  --name web \
  --replicas 3 \
  --restart-condition on-failure \
  --restart-max-attempts 3 \
  --restart-window 120s \
  nginx:latest

Docker Swarm健康检查#

配置Docker Swarm健康检查:

# 创建服务时配置健康检查
docker service create \
  --name web \
  --replicas 3 \
  --health-cmd "curl -f http://localhost || exit 1" \
  --health-interval 30s \
  --health-timeout 10s \
  --health-retries 3 \
  --health-start-period 40s \
  nginx:latest

# 查看服务的健康状态
docker service ps web

# 查看容器的健康状态
docker inspect --format '{{.State.Health.Status}}' container_id

中上级使用#

Docker Swarm服务发现#

使用Docker Swarm服务发现:

# 创建后端服务
docker service create \
  --name backend \
  --replicas 3 \
  --network my-network \
  -e SERVICE_NAME=backend \
  myapp:backend

# 创建前端服务,通过服务名访问后端
docker service create \
  --name frontend \
  --replicas 3 \
  --network my-network \
  -p 80:80 \
  -e BACKEND_SERVICE=backend \
  myapp:frontend

# 容器内通过服务名访问
docker exec -it container_id /bin/bash
curl http://backend

Docker Swarm负载均衡#

使用Docker Swarm负载均衡:

# 创建服务时配置端口发布
docker service create \
  --name web \
  --replicas 3 \
  --publish published=80,target=80,mode=vip \
  nginx:latest

# 使用主机模式端口发布
docker service create \
  --name web \
  --replicas 3 \
  --publish published=80,target=80,mode=host \
  nginx:latest

# 测试负载均衡
for i in {1..10}; do curl http://localhost; done

Docker Swarm滚动更新#

执行Docker Swarm滚动更新:

# 创建服务
docker service create \
  --name web \
  --replicas 5 \
  --update-parallelism 2 \
  --update-delay 10s \
  --update-failure-action rollback \
  nginx:latest

# 执行滚动更新
docker service update \
  --image nginx:alpine \
  web

# 查看更新状态
docker service ps web

# 回滚更新
docker service rollback web

高级使用#

Docker Swarm高可用性#

配置Docker Swarm高可用性:

# 初始化Swarm集群(至少3个管理节点)
docker swarm init --advertise-addr 192.168.1.100

# 添加其他管理节点
docker swarm join-token manager
# 在其他节点上运行获得的命令

# 查看节点状态
docker node ls

# 测试故障转移
# 停止一个管理节点,查看集群状态

# 重新加入节点
docker swarm join --token token manager_ip:2377

Docker Swarm监控#

监控Docker Swarm集群:

# 部署Prometheus和Grafana
docker stack deploy -c docker-compose.monitoring.yml monitoring

# docker-compose.monitoring.yml
version: '3'
services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    deploy:
      placement:
        constraints:
          - node.role == manager

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    deploy:
      placement:
        constraints:
          - node.role == manager

  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    deploy:
      mode: global

volumes:
  grafana_data:

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'docker'
    static_configs:
      - targets: ['cadvisor:8080']

  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

Docker Swarm安全#

配置Docker Swarm安全:

# 查看集群TLS状态
docker info | grep TLS

# 轮换Swarm CA证书
docker swarm ca --rotate

# 查看节点证书信息
docker node inspect --format '{{.Spec.CertificatesRotateAt}}' node_name

# 更新节点证书
docker node update --cert-expiry 720h node_name

# 配置服务的安全选项
docker service create \
  --name web \
  --replicas 3 \
  --limit-cpu 0.5 \
  --limit-memory 512M \
  --read-only \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  nginx:latest

大师级使用#

Docker Swarm企业级部署#

企业级Docker Swarm部署:

# 准备环境
# 至少3个管理节点,多个工作节点
# 配置负载均衡器(如HAProxy)转发到管理节点

# 初始化Swarm集群
docker swarm init --advertise-addr 192.168.1.100

# 添加管理节点和工作节点

# 配置存储
# 使用分布式存储如GlusterFS或Ceph

# 部署应用栈
docker stack deploy -c docker-compose.prod.yml myapp

# 配置监控和日志
# 使用ELK Stack收集日志
# 使用Prometheus和Grafana监控

# 配置备份
# 定期备份Swarm集群状态

# 配置灾难恢复
# 准备备用集群,定期同步状态

Docker Swarm与外部存储集成#

集成Docker Swarm与外部存储:

# 安装GlusterFS
# 在存储节点上安装GlusterFS
apt install glusterfs-server

# 创建GlusterFS卷
gluster volume create gv0 replica 3 node1:/data/glusterfs node2:/data/glusterfs node3:/data/glusterfs
gluster volume start gv0

# 在Swarm节点上挂载GlusterFS卷
mkdir -p /mnt/glusterfs
mount -t glusterfs node1:/gv0 /mnt/glusterfs

# 创建服务时使用GlusterFS卷
docker service create \
  --name db \
  --mount type=bind,source=/mnt/glusterfs/db-data,target=/var/lib/postgresql/data \
  postgres:12

Docker Swarm与CI/CD集成#

将Docker Swarm与CI/CD集成:

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

build:
  stage: build
  script:
    - docker build -t myregistry.com/myapp:$CI_COMMIT_SHA .
    - docker push myregistry.com/myapp:$CI_COMMIT_SHA

test:
  stage: test
  script:
    - docker run --name test-container myregistry.com/myapp:$CI_COMMIT_SHA npm test

deploy:
  stage: deploy
  script:
    - docker service update --image myregistry.com/myapp:$CI_COMMIT_SHA myapp_web
  only:
    - main

# Jenkins pipeline
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'docker build -t myregistry.com/myapp:$BUILD_NUMBER .'
                sh 'docker push myregistry.com/myapp:$BUILD_NUMBER'
            }
        }
        stage('Test') {
            steps {
                sh 'docker run --name test-container myregistry.com/myapp:$BUILD_NUMBER npm test'
            }
        }
        stage('Deploy') {
            steps {
                sh 'docker service update --image myregistry.com/myapp:$BUILD_NUMBER myapp_web'
            }
        }
    }
}

实战案例#

案例一:部署Web应用#

场景:部署一个高可用的Web应用,包含前端、后端和数据库。

解决方案:使用Docker Swarm部署多服务应用。

实施步骤

  1. 创建Docker Compose文件

    # docker-compose.yml
    version: '3'
    services:
      frontend:
        image: myapp:frontend
        ports:
          - "80:80"
        deploy:
          replicas: 3
          update_config:
            parallelism: 2
            delay: 10s
          restart_policy:
            condition: on-failure
    
      backend:
        image: myapp:backend
        deploy:
          replicas: 3
          update_config:
            parallelism: 2
            delay: 10s
          restart_policy:
            condition: on-failure
    
      db:
        image: postgres:12
        volumes:
          - db_data:/var/lib/postgresql/data
        environment:
          POSTGRES_PASSWORD: password
          POSTGRES_DB: myapp
        deploy:
          replicas: 1
          placement:
            constraints:
              - node.role == manager
    
    volumes:
      db_data:
  2. 部署应用

    docker stack deploy -c docker-compose.yml myapp
  3. 查看部署状态

    docker stack services myapp
    docker stack ps myapp

结果

  • 成功部署了高可用的Web应用
  • 配置了前端、后端和数据库服务
  • 实现了服务的自动扩缩容和滚动更新

案例二:部署微服务架构#

场景:部署一个包含多个微服务的应用架构。

解决方案:使用Docker Swarm部署微服务架构。

实施步骤

  1. 创建网络

    docker network create --driver overlay my-network
  2. 部署微服务

    # 部署用户服务
    docker service create \
      --name user-service \
      --network my-network \
      --replicas 2 \
      myapp:user-service
    
    # 部署订单服务
    docker service create \
      --name order-service \
      --network my-network \
      --replicas 2 \
      myapp:order-service
    
    # 部署产品服务
    docker service create \
      --name product-service \
      --network my-network \
      --replicas 2 \
      myapp:product-service
    
    # 部署API网关
    docker service create \
      --name api-gateway \
      --network my-network \
      --replicas 2 \
      --publish 80:80 \
      myapp:api-gateway
  3. 查看服务状态

    docker service ls
    docker service ps api-gateway

结果

  • 成功部署了微服务架构
  • 配置了多个微服务和API网关
  • 实现了服务的自动发现和负载均衡

案例三:部署ELK Stack#

场景:部署ELK Stack用于日志收集和分析。

解决方案:使用Docker Swarm部署ELK Stack。

实施步骤

  1. 创建Docker Compose文件

    # docker-compose.elk.yml
    version: '3'
    services:
      elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:7.10.0
        environment:
          - discovery.type=single-node
          - ES_JAVA_OPTS=-Xms1g -Xmx1g
        volumes:
          - es_data:/usr/share/elasticsearch/data
        deploy:
          placement:
            constraints:
              - node.role == manager
    
      logstash:
        image: docker.elastic.co/logstash/logstash:7.10.0
        volumes:
          - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
        deploy:
          replicas: 2
    
      kibana:
        image: docker.elastic.co/kibana/kibana:7.10.0
        ports:
          - "5601:5601"
        deploy:
          replicas: 1
          placement:
            constraints:
              - node.role == manager
    
    volumes:
      es_data:
  2. 创建Logstash配置

    # logstash.conf
    input {
      beats {
        port => 5044
      }
    }
    
    filter {
      grok {
        match => { "message" => "%{COMBINEDAPACHELOG}" }
      }
      date {
        match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
        target => "@timestamp"
      }
    }
    
    output {
      elasticsearch {
        hosts => ["elasticsearch:9200"]
        index => "logs-%{+YYYY.MM.dd}"
      }
    }
  3. 部署ELK Stack

    docker stack deploy -c docker-compose.elk.yml elk
  4. 部署Filebeat

    docker service create \
      --name filebeat \
      --mode global \
      --mount type=bind,source=/var/lib/docker/containers,target=/var/lib/docker/containers,ro \
      --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
      docker.elastic.co/beats/filebeat:7.10.0

结果

  • 成功部署了ELK Stack
  • 配置了日志收集和分析系统
  • 实现了日志的集中管理和可视化

总结#

Docker Swarm是一种强大的容器编排系统,通过本教程的学习,您已经掌握了从入门到大师级的Docker Swarm使用技术。

主要技术回顾#

  • 基础操作:Docker Swarm的基本命令和操作
  • 集群管理:初始化和管理Swarm集群
  • 服务管理:创建、扩展和更新服务
  • 网络配置:配置覆盖网络和服务发现
  • 存储管理:配置卷和外部存储
  • 高级功能:滚动更新、健康检查、负载均衡
  • 企业级应用:高可用性、监控、安全配置

最佳实践#

  1. 集群规划:根据应用需求规划集群规模,建议至少3个管理节点以实现高可用性
  2. 网络设计:使用覆盖网络实现服务间通信,使用内部网络提高安全性
  3. 存储策略:使用外部存储如GlusterFS或Ceph实现数据持久化
  4. 服务配置:为服务设置合理的资源限制和更新策略
  5. 监控系统:使用Prometheus和Grafana监控集群和服务状态
  6. 日志管理:使用ELK Stack集中管理和分析日志
  7. 安全加固:定期轮换TLS证书,配置服务的安全选项
  8. 自动化部署:与CI/CD集成,实现自动化构建、测试和部署
  9. 备份策略:定期备份集群状态和应用数据
  10. 灾难恢复:建立灾难恢复计划,准备备用集群

注意事项#

  1. 版本兼容性:确保所有节点使用相同版本的Docker
  2. 资源管理:合理规划节点资源,避免资源争用
  3. 网络配置:确保网络连接稳定,特别是管理节点之间的通信
  4. 存储性能:选择性能合适的存储解决方案,避免存储成为瓶颈
  5. 安全审计:定期进行安全审计,发现和修复安全问题
  6. 容量规划:根据应用负载进行容量规划,确保集群能够应对峰值流量
  7. 升级策略:制定合理的集群升级策略,避免升级过程中的服务中断
  8. 文档化:为集群配置和部署过程创建详细文档,便于维护和故障排查

通过合理学习和使用Docker Swarm,您可以构建高可用、可扩展的容器集群,为应用提供稳定可靠的运行环境。Docker Swarm提供了简单易用的容器编排解决方案,适用于从小型应用到大型企业级应用的各种场景。