使用docker swarm搭建ruoyi集群环境

整体目标

项目背景

领导给到了我一个客户,客户商业模式为成本制作,成本核算。其中涉及到大量涉密数据,且与我们现有产品几乎没有兼容点(我们是一套低代码的框架,客户有很多业务二开)

测试环境给到了我6台业务机器,起初其中4台作为业务服务器,一台作为中间件,一台作为mysql。

6台机器均使用私有云部署,配置均为4c8G。

技术选型

直白的讲,物理器部署资源有限。

框架选型

开源框架:选型是ruoyi微服务框架,原因:开源免费,明星star项目,社区活跃,技术相对主流,自己也熟悉。

技术架构图

这是官方的架构图
在这里插入图片描述

系统架构图

这是我结合我们的系统 画的整体系统架构图
在这里插入图片描述

部署选型

部署方式:因为微服务框架和有限的物理机,我必然是选择集群部署的。市面上相对主流的集群部署毋庸置疑是k8s,但是作为一个之前只是后端的开发人员,在没有人指导的情况下,且有期返时间内,部署生产环境集群着实有点为难了。

K8S与docker swarm的横向对比
比较维度 Docker Swarm Kubernetes (k8s)
优点 简单易用 功能强大
与 Docker 集成紧密 高度扩展性
快速部署 广泛社区支持
轻量级 多云支持
缺点 功能相对有限 学习曲线陡峭
扩展性差 资源消耗大
社区和生态较少 部署复杂
适用场景 中小型项目 大规模项目
简单应用 复杂应用
初学者 跨云部署
学习成本
快速上手 深入掌握需要时间
拓展性
有限插件和工具 丰富的插件和工具
社区完善度 较小 庞大
支持较少 丰富的第三方支持

额外提一句:现实中,我们往往以结果为导向。虽然k8s不管是从扩展性,社区活跃度都远远超过docker swarm,但奈何学习成本高,我对于初学者不够友好(PS:国内好多站点被封了,之前用kubeadm部署,刷机后又没有资源站点了)。

学习东西是一个渐进的过程,阶段性的交付和成功,会给自己带来快乐。而一下子上来最难的,只能带来无穷的挫败和自我怀疑,最终陷入无限期的搁置(PS:难度因人而异)

docker swarm 介绍

Docker Swarm 是 Docker 提供的原生容器编排工具。它允许用户将多个 Docker 主机组合在一起,形成一个虚拟的 Docker 集群,并在这个集群上管理和部署容器。Swarm 使得用户可以通过熟悉的 Docker 命令和工具管理大规模的 Docker 容器部署。

部署方式就是一个master节点,其他worker节点加入。管理的最小单位是service,可以使用类似docker-compose的文件进行管理service。同时有多个stack,进行一组service的管理。

部署架构图

这是整体多机网络部署架构图
在这里插入图片描述

基于Redhat构建docker、docker-compose

repo配置

在这里插入图片描述

配置文件如下:

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the #mirrorlist= does not work for you, as a fall back you can try the 
# remarked out baseurl= line instead.
#
#
 
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/BaseOS/$basearch/os/
        http://mirrors.aliyuncs.com/centos/$releasever/BaseOS/$basearch/os/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
 
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/os/
        http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/os/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/os/
        http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/os/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/os/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
 
[PowerTools]
name=CentOS-$releasever - PowerTools - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/PowerTools/$basearch/os/
        http://mirrors.aliyuncs.com/centos/$releasever/PowerTools/$basearch/os/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/PowerTools/$basearch/os/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official


[AppStream]
name=CentOS-$releasever - AppStream - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/
        http://mirrors.aliyuncs.com/centos/$releasever/AppStream/$basearch/os/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/AppStream/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/source/stable
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/source/test
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/$releasever/source/nightly
enabled=0
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/rhel/gpg

redhat因为客户买的没有注册 所以他的资源文件是空的

阿里云镜像

这个因为一些image在国外,配置一下阿里云镜像会拉取快很多

具体路径 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
按照上面的配置就可以

在这里插入图片描述

部署操作

docker

sudo yum install -y yum-utils

sudo yum install docker-ce docker-ce-cli containerd.io

sudo systemctl start docker

sudo systemctl enable docker

docker-compose

sudo curl -L “https://github.com/docker/compose/releases/download/v2.x.x/docker-compose- ( u n a m e − s ) − (uname -s)- (unames)(uname -m)” -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker-compose --version

docker swarm 初始化

docker swarm init

正常情况下,会出现token,如果你没有记录,也可以在manage节点

docker swarm join-token worker

查看对应的swarm的manage的token
在这里插入图片描述

然后再worker节点上 直接直接join就可以了

然后整体的一个node结构如下

在这里插入图片描述

这里我还对hostname做了修改

overlay 网络构建

十分重要

docker network create --driver overlay --subnet=10.10.0.0/24 --gateway=10.10.0.1 sangfor-network

docker中的网络是最为复杂的,同时因为我是跨机之间的网络通讯,这里使用了overlay的配置

然后再整个stack配置文件中,我使用了external: true,使用外部网络

网络查看

正常来说 当你构建完成一个service的构建之后,你要查看这个网络
docker network inspect sangfor-network
在这里插入图片描述

这里面会体现出你的container和对应的ip

需要注意是,当你的使用overlay网络的时候,如果你的某台woker机器上并没有service,那么这个overlay网络是不显示的

同时需要明确的是,查看网络中的container 只有当前机器的container才会显示

yml配置优先网段

需要明确的是,docker container内的网卡是有很多个的,他是哪个可以用就用哪个

所以这里需要结合程序的修改,就是这个preferred-networks,我写了10.10.0网段
在这里插入图片描述

通过这种方式,使得container的ip优先使用这个10.10.0网段

docker-stack部署

这里直接贴我两个的stack文件吧

docker-stack-basic.yml

version : '3.8'
services:
  cloud-mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - /data/cloud/mysql/conf:/etc/mysql/conf.d
      - ./mysql/logs:/logs
      - ./mysql/data:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro
    command: [
      'mysqld',
      '--innodb-buffer-pool-size=80M',
      '--character-set-server=utf8mb4',
      '--collation-server=utf8mb4_unicode_ci',
      '--default-time-zone=+8:00',
      '--lower-case-table-names=1',
      '--default-authentication-plugin=mysql_native_password'
    ]
    environment:
      MYSQL_DATABASE: 'cloud_business'
      MYSQL_ROOT_PASSWORD: 'yourpassword'
      TZ: 'Asia/Shanghai'
    networks:
      - sangfor-network
    deploy:
      placement:
        constraints:
          - node.labels.mysql == true

  cloud-redis:
    container_name: cloud-redis
    image: redis
    build:
      context: ./redis
    ports:
      - "6379:6379"
    volumes:
      - ./redis/conf/redis.conf:/home/ruoyi/redis/redis.conf
      - ./redis/data:/data
    command: redis-server /home/ruoyi/redis/redis.conf
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network
    deploy:
      placement:
        constraints:
          - node.labels.middle == true

networks:
  sangfor-network:
    external: true

docker-stack-sangfor.yml

version : '3.8'
services:
  cloud-portainer:
    image: portainer/portainer-ce:latest
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./portainer/data/:/data
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - "9000:9000"
    deploy:
      placement:
        constraints:
          - node.labels.portainer == true
      resources:
        limits:
          cpus: '0.50'
          memory: 500M
    networks:
      - sangfor-network

  cloud-nacos:
    image: nacos/nacos-server
    build:
      context: ./nacos
    environment:
      - MODE=standalone
      - TZ=Asia/Shanghai
    volumes:
      - ./nacos/logs/:/home/nacos/logs
      - ./nacos/conf/application.properties:/home/nacos/conf/application.properties
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8848:8848"
      - "9848:9848"
      - "9849:9849"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health/liveness"]
      interval: 30s
      timeout: 10s
      retries: 5
    networks:
      - sangfor-network
    deploy:
      placement:
        constraints:
          - node.labels.middle == true

  cloud-nginx:
    image: nginx:1.0
    ports:
      - "80:80"
    volumes:
      - ./nginx/html/dist:/home/cloud/projects/cloud-ui
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/logs:/var/log/nginx
      - ./nginx/conf.d:/etc/nginx/conf.d
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network
    deploy:
      placement:
        constraints:
          - node.labels.master == true

  cloud-gateway:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_gateway:1.0
    ports:
      - "8080:8080"
    environment:
      TZ: Asia/Shanghai
    deploy:
      placement:
        constraints:
          - node.labels.master == true
    networks:
      - sangfor-network

  cloud-auth:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_auth:1.0
    ports:
      - "9200:9200"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network

  cloud-modules-system:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_system:1.0
    ports:
      - "9201:9201"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network

  cloud-modules-gen:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_gen:1.0
    ports:
      - "9202:9202"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network

  cloud-modules-job:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_job:1.0
    ports:
      - "9203:9203"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network

  cloud-modules-file:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_file:1.0
    ports:
      - "9300:9300"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./cloud/uploadPath:/home/cloud/uploadPath
    networks:
      - sangfor-network

  cloud-visual-monitor:
    image: registry.cn-hangzhou.aliyuncs.com/sangfor_authine/cloud_monitor:1.0
    ports:
      - "9100:9100"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - sangfor-network

networks:
  sangfor-network:
    external: true

label标签固定

这里可以看到有些service我是固定在某些机器上的,当然前提是你要给你的机器打标签

标签这么打就行了

docker node update --label-add work_node3=true work_node3

我这边打标签分为几种常见场景

1.外部异构系统需要公用redis和mysql

2.portainer 需要在master节点上监控

3.nacos配置我是固定ip的(这里面应该是可以直接使用service名称代替ip的)

端口开放

有些端口需要对外开放,docker swarm中部分port也要打开

开放端口如下

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent

sudo firewall-cmd --reload

在这里插入图片描述

image托管

我这里偷懒了 我不想搭建harbor了

我直接把我的阿里云镜像仓库贡献出来了

这些相关的操作文档还是很多的

portainer可视化构建

portainer的构建方式在之前的stack中有

他的最大意义在于可视化的操作,降低scale和查看日志都比较方便

贴几张图

在这里插入图片描述

这里面service和stack他会自动抓取的
在这里插入图片描述

对于容器也可以做一些调配
在这里插入图片描述

查看nacos 内网ip

这个很重要,之前我一直跨机服务的时候 调度不通

查到最后是我的内网nacos ip注册的有问题,这也是前面网络声明网段和我使用preferred-networks的原因

记得在服务列表里面查看自己的ip
在这里插入图片描述

异常情况与排查思路

遇到了太多了卡点和异常了,我现在只记得一些关键卡点和排查思路了

Overlay网络问题

最一开始部署的时候,redis和mysql其实使用docker-compose部署的,然后发现我业务内部调用mysql网络不通。

我不服气,我把swarm集群中的网络改成了外部可以访问 增加了–attachable,但最后发现不行。

还是要放在一个网络里面,所以最后我把之前docker-compose build的mysql和redis 切换为stack部署了(切换代价很小,因为都做了挂载,数据不会丢失)

服务无法调度问题

通俗的讲就是我服务到了nginx,做完转发进入gateway 调不通auth权限。

第一反应其实也是网路问题,最后排查思路是 进入到gateway的容器内部

docker exec -it a927a4a68b2d /bin/bash

然后curl auth服务
在这里插入图片描述

这就是ping的通的

但是真实调研的时候 因为使用的是fegin

他们用的是这个serviceName
在这里插入图片描述

这里面的service名称 要等于nacos的名称
在这里插入图片描述

然后域名访问如下:
在这里插入图片描述

这样服务就基本没啥问题了

naocs 配置

这个完全是我因为我不太熟悉导致的问题

这个yml配置里面 就是cloud-auth-dev配置
在这里插入图片描述

naocs配置中心里面配置保持一致就可以‘

相关推荐

  1. nginx: 环境配置

    2024-07-21 13:22:02       25 阅读
  2. 使用DockerNacos

    2024-07-21 13:22:02       28 阅读
  3. Linux环境Hadoop及完全分布式

    2024-07-21 13:22:02       32 阅读
  4. Redis(四) 主从、哨兵、环境

    2024-07-21 13:22:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 13:22:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 13:22:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 13:22:02       45 阅读
  4. Python语言-面向对象

    2024-07-21 13:22:02       55 阅读

热门阅读

  1. 主页目录导航

    2024-07-21 13:22:02       19 阅读
  2. Mechanize:自动化Web交互的利器

    2024-07-21 13:22:02       19 阅读
  3. 增量预训练和微调的区别

    2024-07-21 13:22:02       18 阅读
  4. Allure 和 JUnit 4结合学习

    2024-07-21 13:22:02       18 阅读
  5. vue3 学习笔记17 -- echarts的使用

    2024-07-21 13:22:02       22 阅读
  6. GPT-5一年半后发布

    2024-07-21 13:22:02       17 阅读
  7. 批量下载网易云音乐歌单的Python脚本

    2024-07-21 13:22:02       21 阅读