关于docker swarm部署springcloud 服务注册实例ip的问题

关于docker swarm部署springcloud注册实例ip的问题

版本

本案例使用版本
SpringCloud: Finchley.SR3

问题描述

搭建docker swarm集群部署一套微服务,集群信息如下

主机ip集群角色
hyper110.18.32.215manager
hyper210.18.32.161worker
hyper310.18.32.68worker

部署服务如下

  1. 注册中心eureka
  2. 配置中心config
  3. 网关中心zuul
  4. xxl定时任务调度中心
  5. activemq-provider消息发送服务
  6. activemq-consuemr消息接收服务
  7. activemq、mysql等

编排脚本如下:

version: "3"
services:
  my-eureka:
    ports:
      - "10101"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == worker]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/my-eureka:1.0

  my-config:
    ports:
      - "10201"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == worker]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/my-config:1.0
    depends_on:
      - my-eureka

  my-zuul:
    ports:
      - "10302"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == worker]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/my-zuul:1.0
    depends_on:
      - my-config

  my-xxl:
    ports:
      - "10310"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/my-xxl:1.0
    depends_on:
      - my-eureka
      - mysql

  activemq-provider:
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == worker]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/activemq-provider:1.0
    depends_on:
      - my-config
      - my-xxl
      - activemq

  activemq-consumer:
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == worker]
      restart_policy:
        condition: on-failure
    image: shuiniudocker/activemq-consumer:1.0
    depends_on:
      - my-config
      - activemq

  mysql:
    ports:
      - "3306:3306"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
    image: mysql:5.5
    volumes:
      - "/home/docker/volumes/mysql/logs:/logs"
      - "/home/docker/volumes/mysql/data:/var/lib/mysql"
    environment:
      - "MYSQL_ROOT_PASSWORD=123456"

  activemq:
    ports:
      - "8161:8161"
      - "61616:61616"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
      restart_policy:
        condition: on-failure
    image: webcenter/activemq
    volumes:
      - "/home/docker/volumes/activemq:/data/activemq/conf"

  portainer:
    image: portainer/portainer
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "9001:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  default:
    external:
      name: test-swarm

test-swarm是自己创建的网络:

docker network create -d overlay --attachable test-swarm

一切似乎没有问题
使用

docker stack deploy my-cloud -c docker-stack.yml

启动服务

问题出现

  1. configserver成功注册到eureka上,但是其他子服务在注册到eureka并获取configserver实例ip后,在获取具体的配置信息时,居然超时了!!!
  2. 明明在自定义的同一网络下。我甚至开始怀疑是不是swarm集群创建有问题,在检查完配置脚本等细节问题浪费了整整半天后,确定不是搭建集群的问题。
  3. 回头仔细观察启动日志发现,获取到的configserver实例ip为10.0.0.x,但此时我并没有发现问题(对docker的网络细节确实不够了解)。因此我觉得成功获取到了实例ip没有问题,转而开始归结于overlay网络延迟,因为overlay确实存在网络性能问题。
  4. 没办法,为了证实这个猜测,我创建了一个bridge类型的网络,在单节点上把所有服务起了一遍,果然没有问题。。这时候我已经要一棒子打死overlay网络了(彻底走偏),但我内心还是不愿意相信,性能再差也不至于完全不通啊。
  5. 不死心的我决定再用手动docker run的方式并指定网络类型为overlay在单节点上启动所有服务,如果还是不通,那overlay就真的洗不清了,然后问题的转折出现了
  6. 我发现服务居然通了!!合着是服务编排的锅?然后再用编排的方式启动了几次,终于发现了问题的症结。我发现当configserver注册实例ip为10.0.0.x时,就会出现上述问题!!!而实例ip为10.0.1.x时,服务畅通无阻!!!
  7. 我删除之前的网络并创建了一个新的overlay网络,指定了它的subnet
docker network create -d overlay --attachable -subnet=192.168.0.0/24 test-swarm
  1. 使用该网络再次启动服务,发现springcloud相关服务有(较大)概率被分配到10.0.0.x ip,剩余服务被分配到192.168.0.x

  2. 此时已经朦胧的感觉到是springcloud注册实例ip跟swarm有某些冲突,但无奈人菜,还是不知道根本原因。于是疯狂在群里求助大佬

  3. 然后在之前加入的XXL开源社区交流群中找到灵感,源于大佬一条回复
    大佬回复

  4. 刚开始我看的比较草率,将其理解为形同于

eureka:
	instance:
		ip-address

如上的配置,于是带着试探性的目的搜索了相关内容,结果越看发现越是那么回事。大致内容是说,nacos客户端在注册实例ip时会有概率注册到swarm自带的ingress网络,然后我再查看ingress的子网范围:

 docker network inspect ingress|grep Subnet

结果
!!!
破案了,原来真是这么回事啊,感谢大佬!
原文链接:https://www.cnblogs.com/zoujiaojiao/p/12752860.html

  1. 问题发现了,但是怎么解决呢?上文说的是针对nacos的配置,那么eureka是否可以用呢。先搜索相关关键字,才发现这个问题一直都存在(所以说网上什么都有,但是得会搜啊),也确实有人提出以同样的配置可以解决该问题。先上手试试:
  2. 在所有配置中加入
spring:
  cloud:
    inetutils:
      preferred-networks: 192.168.0

配置,指定注册实例ip网段

为了简化测试步骤,临时改写编排文件,部署1个eureka和3个configserver
好起来了?
发现所有config实例均为192.168端(内心已经开始狂喜),图中的eureka实例为10.0.0端,但是向下查看实例ip也是192段。猜测大概是因为eureka服务端维护实例的hostnamespring.cloud.inetutils.preferred-networks配置才生效
192段
13. 测试3次!
14. 哈哈成了!

后记

至此我的问题完美解决了,但是中途搜到一份issue提到如此设置后同一服务多个实例instance_id会重复且缓存为第一个副本的instance_id(即使第一个副本运行失败!),具体链接
https://github.com/spring-cloud/spring-cloud-netflix/issues/1820
并且文中详细地提到了解决办法
不知道是不是版本问题,我并没有遇见该问题
问题
问题
因此便不再赘述
让我头疼了整整两天的问题就这样解决了

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页