大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
在使用Docker部署应用时,Docker推荐的方式是将应用及其所依赖的服务(MySQL,Redis等)均使用Docker部署,并通过link或自定义网络相连接。但是,当应用所依赖的服务被安装在宿主机上时,我们需要让容器中的应用能够访问到部署在宿主机上的服务。本文将介绍实现这一目的的几种方案,并分析其优缺点。
首先我们需要了解一些关于Docker网络的基础知识。
Docker网络
Docker提供了5种网络类型,这里介绍其中常见的两种:bridge及host
Bridge
Bridge是Docker默认使用的网络类型。如图,网络中的所有容器可以通过IP互相访问。Bridge网络通过网络接口docker0
与主机桥接,可以在主机上通过ifconfig docker0
查看到该网络接口的信息。
Host
Host模式下,容器的网络接口不与宿主机网络隔离。在容器中监听相应端口的应用能够直接被从宿主机访问。host网络仅支持Linux。
方案
方案1:使用host模式
通过docker run
启动容器时加入–net=host
参数,或在compose文件中指定network_mode: “host”
,例如:
version: '3'
services:
foo:
container_name: "foo"
image: "foo/bar"
ports:
- "8000:8000"
network_mode: "host"
restart: always
该参数指定该容器使用host网络模式,因此也无需映射端口。
优点
- 最简单粗暴的解决方案,方便快捷。
缺点
- host网络没有与宿主机网络隔离,可能引发安全隐患或端口冲突。
- 仅适用于Linux。
方案2:使用docker0网络的默认网关地址
在默认的bridge模式下,docker0网络的默认网关即是宿主机。在Linux下,docker0网络通常会分配一个172.17.0.0/16的网段,其网关通常为172.17.0.1;macOS下的网段则为192.168.65.0/24,网关为192.168.65.1。在容器中使用该IP地址即可访问宿主机上的各种服务。
需要注意的是,这种情况下,经由docker0网桥而来的流量不经过宿主机的本地回环,因此需要将宿主机上的应用(MySQL,Redis等)配置为监听0.0.0.0。
优点
- 避免了方案1的缺点
缺点
- 此IP并不一定完全固定,可能会因系统及配置而发生变化。
- 容器经由docker0网桥无法访问到监听地址是127.0.0.1的应用。需要将MySQL等配置为监听0.0.0.0。
方案3:Docker提供的指向宿主机的DNS
macOS版Docker提供了一个指向宿主机的域名docker.for.mac.host.internal 。在需要访问宿主机服务时使用此域名即可。其实现原理有人进行了如下研究:
Understanding the ‘docker.for.mac.localhost’ behavior – Docker Desktop for Mac – Docker Forums
优点
- 该DNS是动态的,能够适用于不同的网络环境及配置。
缺点
- 容器经由docker0网桥无法访问到监听地址是127.0.0.1的应用。需要将MySQL等配置为监听0.0.0.0。
- 仅适用于macOS。实际上,已经有人在GitHub上提出Issue,请求在Linux上添加类似的特性。
方案4:在容器中获取宿主机地址
在Dockerfile的CMD部分添加如下一条命令:
ip -4 route list match 0/0 | awk ‘{
print $3 “host.docker.internal”}’ >> /etc/hosts
ip -4 route list match 0/0
命令会列出当前系统的默认网关,并将host.docker.internal
域名解析至它。
请注意ip命令并不一定随镜像附带,如果没有的话,使用apt install iproute2
安装。
优点
- 结合了方案2和3的优点
缺点
- 容器经由docker0网桥无法访问到监听地址是127.0.0.1的应用。需要将MySQL等配置为监听0.0.0.0。
遇到的问题
在使用网桥的时候遇到一个问题
在微服务中使用springCloud gateway作为网关,其中一个服务实例使用docker进行部署,mac系统,使用网桥方案3,服务能够正常启动,正常注册,直接将api调用地址指向docker没问题,可以正常调用api,通过网关调用api时提示没有服务,查看调用地址发现指向docker中的内网地址172.xx.xx.xx ,这样导致通过网关是无法调用到api的,服务虽然能够注册成功,但也没有意义,目前没能够想到解决方案,先记录一下
原文地址:https://blog.nyan.im/posts/3981.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/171611.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...