Eureka与host.docker.internal
问题描述
环境:
- OS : Windows 10
- Java : 11
- Spring : 2.3.11 RELEASE
- Spring Cloud : Hoxton.SR11
注意:我的主机的ip是10.65.7.32(局域网的,要是公网的也不可能放出来)
具体情况
将Eureka和服务提供方部署在同一台主机上时,Eureka显示的服务提供方为host.docker.internal:

同时,网址打不开:

解决方案
解决方案网上基本都能搜到:
① 删除C:\Windows\System32\Drivers\etc\hosts的部分条目。

② 设置eureka.instance.prefer-ip-address为true
③ 设置eureka.instance.hostname
细节剖析
要是直接给解决方案,那倒没什么好写了,接下来来分析一下出现这个问题的原因。
首先,我们知道,host.docker.internal是为了在docker虚拟机中提供宿主机ip的。
因为是虚拟机,所以localhost和127.0.0.1都会被认为是虚拟机的地址,但是我们发现,docker里的虚拟机是可以正常访问互联网的,所以就有了一个办法,把宿主机当做一个路由器,用跨网段访问的方式。

实际上Docker为我们做的事就是更改本机的hosts文件,让host.docker.internal解析成宿主机的网卡的地址。

实际上,ping是可以ping通的。但是我们会发现,在浏览器上就不行了。


但我们可以看到,直接输入ip地址是可以的。
关于这个问题,我没有特别去查相关的资料,不过既然这样,我认为host.docker.internal这个应该是解析不成正常的域名的,所以还是要换成ip.
可是,为什么我发送给Eureka会把服务的地址设为host.docker.internal呢?
让我们直接看看IDE的提示:

原来,当我们不填写hostname的时候,hostname就会从操作系统推导,所以被推成了host.docker.internal。
那么,就有两种方式解决这个问题了:
1 | eureka: |
不过,具有迷惑性的是,无论你采用哪一种方式,在Dashboard上都仍然会有host.docker.internal。但实际上,它们的链接已经变成了真正的地址,可以正常使用了。

再具体一点
再具体一点,看看Eureka的客户端到底发了啥。


现在可以看到了,原来 host.docker.internal:ingredient-service:0是这个实例的id,而hostname就是我们刚刚改的部分。
如果你采用了改hostname的方式,那么这里的hostname就会变成你改成的值。
而如果你采用了改eureka.instance.prefer-ip-address,那么其实hostname的值会变成你的ip地址,也就是这里的10.65.7.32。