使用 Docker 部署的微服务在 Nacos 里注册成内网地址 导致无法微服务间互相调用的解决方案

遇到问题:

一般情况下,微服务采用docker部署,通常默认采用 bridge 桥接的网络模式,docker 会自动分配一个 172.x.x.x 这样的私有内网地址,存在这样的难题:

  • 由于是 172开头的内部网络地址, 在本机的docker 内是可以访问,而 跨主机 就无法访问。
  • 在使用了nacos 后,nacos 里注册的服务地址是 172 开头的,导致 微服务间调用失败。

解决方法:

1. 采用 host 模式

创建出来的容器没有独立ip,无法产生网络隔离的效果,它占用宿主机的IP。

注意:docker 在 linux 系统 下才支持 host 模式。mac 无法使用,我在这里坑半天。

2. 采用 bridge模式,做端口映射

将 容器的端口号 映射到 宿主机的端口号,在被访问时通过宿主机的IP和端口来访问。

在 使用 springcloud微服务时,单个服务在向注册中心注册的时候可以指定注册ip,这样就不会自动注册成 docker 容器的私有ip。

在 Nacos 下配置:
使用的是nacos注册中心,指定 spring.cloud.nacos.discovery.ip = 宿主机的IP,这样注册到 Nacos 的微服务ip就是这里指定的宿主机IP 了,在Nacos里显示是宿主机的IP, 进行服务间访问的时候也是用这个ip,就不会出现无法访问了。

关键是:

spring.cloud.nacos.discovery.ip = 宿主机的IP

扩展知识

在使用docker run创建Docker容器时,可以用--network标志 选项指定容器的网络模式,Docker有以下4种网络模式:

  • host模式:使用 --net=host 指定。
  • bridge模式:使用 --net=bridge 指定,默认设置。
  • none模式:使用 --net=none 指定。

host模式

host模式类似于Vmware的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。