Docker笔记:Docker Swarm 结合 Docker Compose 来部署集群

docker swarm 结合 docker-compose.yml 部署集群

1 )准备 docker-compose.yml的文件, 示例 demo 如下

yml 复制代码
version: "3"
services:
  mysql_c:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    restart: always
    ports:
      - 3306:3306
    volumes:
      - /root/mysql/conf.d:/etc/mysql/conf.d
      - /root/mysql/data:/var/lib/mysql
  goweb1:
    image: gowebimg
    restart: always
    deploy:
      replicas: 6 # 副本数量
      resources: # 资源
        limits: # 配置cpu
          cpus: "0.3" # 设置该容器最多只能使用 30% 的 CPU
          memory: 500M # 设置该容器最多只能使用 500M内存
      restart_policy: # 定义容器重启策略, 用于代替 restart 参数
        condition: on-failure # 只有当容器内部应用程序出现问题才会重启
    depends_on:
      - mysql_c
  nginx:
    image: nginx
    restart: always
    ports:
      - 80:80
    depends_on:
      - goweb1
    volumes:
      - /root/nginx/conf.d/:/etc/nginx/conf.d
    deploy:
      replicas: 6 #副本数量
      resources: #资源
        limits: #配置cpu
          cpus: "0.3" # 设置该容器最多只能使用 30% 的 CPU
          memory: 500M # 设置该容器最多只能使用 500M内存
      restart_policy: # 定义容器重启策略, 用于代替 restart 参数
        condition: on-failure #只有当容器内部应用程序出现问题才会重启
  • 基于 docker-compose可以在一台服务器上创建多个容器
  • 想在多台服务器上一次创建多个容器, 需要结合 Swarm
    • $ docker stack deploy --compose-file docker-compose.yml swarmName
      • swarmName是我们的swarm对应的名称,可以自行随意配置, 比如 goWebSwarm
  • 以上配置的问题是 mysql 没有进行集群
    • mysql 需要单独搭建集群,这里涉及到主从数据库
    • 为了方便起见,直接配置到了 yml 文件里
    • 这里mysql的副本数量不能配置多个
    • 如果多个,就会运行在多台服务器上,会出现数据异常和不一致的问题

2 )搭建集群

  • $ docker swarm init --advertise-addr 192.168.1.10 初始化集群并创建管理节点(当前指定的ip为管理节点)
    • 填入自己主机的ip
  • $ docker swarm join --token SWMTKN-1-52tr219htvsg1volky2tej7pj8bjs2j78q4b6wc9fnt72kkchd-29ohn4mgz191f6oznldvjiw47 192.168.1.10:2377
    • 其他主机加入集群
  • 根据 yml 文件,这里的集群是 nginx 和 goweb的集群,它们都有6个副本,mysql 服务只有一个副本

3 )部署和验证

  • $ docker stack deploy --compose-file docker-compose.yml goWebSwarm 开始部署服务
    • 调用这个命令的时候,首先创建了网络
    • 接着创建3个服务
    • 这3个服务使用了同一个网络,默认这三个服务可以直接连通
  • $ docker service ls 可查看当前运行起来的服务
  • $ docker service ps goWebSwarm 查看当前某个服务
  • 通过 docker-compose 部署,可见生成了3个服务,这三个服务,使用了同一个网络
  • 这里同样存在之前的,mysql服务启动了,接着goWeb服务也启动,但是mysql服务并没有完全可用的状态
    • 可以用之前的脚本解决
    • 可以重启 goWeb项目 (或扩容,缩容来重启)
    • 可以先单独部署 mysql的集群,之后再部署 goWeb 和 Nginx 服务
      • 这种就不属于这里的集群了,mysql集群作为一项单独的集群
      • goWeb应用的配置文件也要对应同步修改

4 )配置部署额外的一台Nginx服务器(非集群内)

  • 额外的NG服务器,用于做路由和转发到集群内的nginx服务器

  • 在集群内的各个主机磁盘上都有 /root/nginx/conf.d/ 目录中都有一个 default.conf 文件

    conf 复制代码
    upstream backend {
      ip_hash;
      server goweb1:8080; # 这里是 goweb1 容器服务的host别名
    }
    
    server {
            listen       80;
            server_name  localhost; # 你的域名地址
            location / {
                  # 设置主机头和客户端真实地址,以便服务器获取客户端真实IP         
                  # 禁用缓存
                  proxy_buffering off; 
                  # 反向代理的地址
                  proxy_pass http://backend;     
            }
            #error_page  404              /404.html;
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root  html;
            }
    }
    • 当访问这个时,nginx将 80 转发到 8080
  • 现在,我们要配置nginx的主机,也就是转发到集群内,进行负载均衡的配置

    conf 复制代码
    upstream backend {
      ip_hash;
      server 192.168.1.10 weight=1; # 集群内的服务 ip 这里有一台 nginx服务器
      server 192.168.1.11 weight=1;
      server 192.168.1.12 weight=1;
      server 192.168.1.13 weight=1;
    }
    
    server {
            listen       80;
            server_name  goweb.xxxx.com; # 你的域名地址 这里本机可以配置 host, 如果在服务器配置 域名解析
            add_header backendCode $upstream_status;
            add_header BackendIP "$upstream_addr;" always;
            location / {
                  # 设置主机头和客户端真实地址,以便服务器获取客户端真实 IP
                  proxy_set_header Host $host;
                  proxy_set_header X-Real-IP $remote_addr;
                  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                  # nginx服务器与被代理服务连接超时时间,代理超时,请求一台超过1s就会转发到其他ip
                  proxy_connect_timeout 1s;
                  # 禁用缓存
                  proxy_buffering off;
                  # 反向代理的地址
                  proxy_pass http://backend;
            }
            #error_page  404              /404.html;
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root  html;
            }
    }
  • 上面用于查看nginx服务器转发节点的配置
    • proxy_set_header X-Real-IP $remote_addr;
    • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    • 加上这个,在浏览器中可以看到转发的服务器,在响应表头,会有一个 BackendIP 的字段
  • 启动 nginx 主机
    • $ docker run -itd --name nginxweb -p 80:80 -v /root/nginx/conf.d:/etc/nginx/conf.d nginx

5 )整体架构如下

  • 第一层 )nginx 服务器接收到请求后转发到集群中的各台主机上

    • 这里是最外面的一层 nginx 作为负载均衡
    • 这台nginx服务器是一台高性能服务器,只负责转发,没有其他处理任务
  • 第二层 )集群里面有各类服务

    • nginx goWeb
      • goWeb 连接到 mysql 或 mysql集群服务
    • nginx goWeb
      • 同上
    • nginx goWeb
      • 同上
    • ...
    • 这个集群内部的nginx服务会动态负载均衡到各个goWeb服务
  • 第三层 )mysql 或 mysql集群

    • 目前我们的mysql 只有一台服务,并且配置在compose文件里
  • 以上三个层,是我们服务端一般的设计方案,当然上面没用到 mysql 集群

  • 以上架构可支持 100W 的访问量 (使用mysql集群)

  • 如果需要负载更多, 可把这套架构复制到多个城市地区

    • 一般情况下,域名解析只能配置到一台服务器
    • 当然,有个动态域名解析,可以支持多台
    • 这样就可以根据请求判断转发到那些服务器

关于 Docker Swarm 的 Raft 一致性算法

  • Raft:一致性算法,在保证大多数管理节点存活的情况下,集群才能使用
  • 所以就要求如果集群的话,manager节点必须 >=3 台
    • manager: 管理节点,用于管理工作节点
  • 如果是两个台,其中一台宕机,剩余的一台也将不可用,以致整个集群不可用
  • 为了利用 swarm 模式的容错特性,Docker 建议您根据组织的高可用性要求实现奇数个节点
  • 当您有多个管理器时,您可以从管理器节点的故障中恢复而无需停机
    • 一个3管理器群最多可以容忍1名管理器的损失
    • 一个5管理器群最多可以同时丢失2个管理器节点
    • 一个N管理器集群最多可以容忍丢失 (N - 1) / 2 管理器
    • Docker 建议一个Swarm集群最多使用7个管理器节点
相关推荐
一水鉴天10 小时前
整体设计 逻辑系统程序 之18 Source 容器(Docker)承载 C/P/D 三式的完整设计与双闭环验证 之2
docker·架构·认知科学·公共逻辑
飞快的蜗牛12 小时前
利用linux系统自带的cron 定时备份数据库,不需要写代码了
java·docker
火星MARK12 小时前
k8s面试题
容器·面试·kubernetes
香吧香13 小时前
Docker Registry 使用总结
docker
赵渝强老师13 小时前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
haicome15 小时前
deepseek部署
docker·ragflow·deepseek 部署
乄bluefox15 小时前
保姆级docker部署nacos集群
java·docker·容器
每天进步一点_JL15 小时前
Docker 是什么?
后端·docker·容器
一叶飘零_sweeeet16 小时前
从 0 到 1 掌控云原生部署:Java 项目的 Docker 容器化与 K8s 集群实战指南
docker·云原生·kubernetes·项目部署
森林猿16 小时前
docker-compose-kafka 4.1.0
docker·容器·kafka