Docker Swarm 部署多环境集群时,服务配置很多都是共用的,如果把每个环境的配置都分别保存未免有些啰嗦,而且一旦有变更就需要修改多个文件,这时就可以对配置文件进行拆分。
一个常见的多环境部署方案是 local staging production 三环境部署。local 是开发人员在本地开发和测试使用的,staging 是系统预览环境,用来在系统上线前测试并发现问题,production 环境则是线上生产环境。
这三个环境很可能只有部分参数不同,例如 replicas 数量、数据库的用户名密码、开放端口等。而不太重要的一些参数(比如滚动更新配置、labels等)很有可能是共用的,如果把每个环境的配置都分别保存为一个 yaml 文件未免有些啰嗦,一旦有变更还要修改多个文件。
这时就可以拆分 compose 文件,像下面这样
version: "3.8"
services:  # wordpress 服务的公共配置  wordpress:    ports:      - 8080:80    networks:      - overlay    deploy:      restart_policy:        condition: any        delay: 5s        max_attempts: 3        window: 120s      rollback_config:        parallelism: 1        delay: 0s        monitor: 10s        order: stop-first      update_config:        parallelism: 1        delay: 10s        monitor: 10s        order: start-first
networks:  overlay:version: "3.8"
services:  wordpress:    image: wordpress # staging 环境使用的镜像版本    environment:      WORDPRESS_DB_HOST: db:3306 # staging 环境的连接配置    deploy:      mode: replicated      replicas: 1 # staging 环境不需要多个实例version: "3.8"
services:  wordpress:    image: wordpress # production 环境使用的镜像版本    environment:      WORDPRESS_DB_HOST: online-db:3306 # production 环境的连接配置    deploy:      mode: replicated      replicas: 3 # production 环境的实例数量执行 docker stack deploy -c base.yaml -c staging.yaml 命令就是用 staging 环境的配置去部署,它会将 base.yaml 和 staging.yaml 的内容进行合并。将 staging.yaml 替换为 prod.yaml 就可以用 production 的配置进行部署了。
另外一个技巧是,如果一个 compose 文件定义了多个 service,那不同的 service 也可能有相同的重启策略、回滚策略等,这时可以用 yaml 的锚点技巧优化 compose 文件定义,例如
version: "3.8"
# 在 docker compose 文件中,以 x- 开头的字段会被识别为变量x-deploy-defaults: &deploy-defaults  restart_policy:    condition: any    delay: 5s    max_attempts: 3    window: 120s  rollback_config:    parallelism: 1    delay: 0s    monitor: 10s    order: stop-first  update_config:    parallelism: 1    delay: 10s    monitor: 10s    order: start-first
x-healthcheck-defaults: &healthcheck-defaults  interval: 30s  timeout: 5s  retries: 3  start_period: 10s
services:  # 第一个服务  wordpress:    image: wordpress    deploy:      <<: *deploy-defaults # 插入前面定义的 deploy-defaults 变量    healthcheck:      <<: *healthcheck-defaults # 插入前面定义的 healthcheck-defaults 变量      test: ["CMD", "curl", "-f", "http://localhost"]
  # 第二个服务  wordpress-2:    image: wordpress    deploy:      <<: *deploy-defaults # 插入前面定义的 deploy-defaults 变量    healthcheck:      <<: *healthcheck-defaults # 插入前面定义的 healthcheck-defaults 变量      test: ["CMD", "curl", "-f", "http://localhost"]