如何从Docker容器内部连接到机器的本地主机?

所以我有一个运行在docker容器中的Nginx,我有一个运行在localhost上的mysql,我想从Nginx中连接到mysql。MySql在localhost上运行,并且没有向外界公开端口,因此它绑定在localhost上,而不是绑定在机器的ip地址上

是否有任何方法可以从docker容器中连接到此MySql或localhost上的任何其他程序

这个问题与“如何从docker容器中获取docker主机的IP地址”不同,因为docker主机的IP地址可能是网络中的公共IP或私有IP,而这些IP可能在docker容器中可以访问,也可能无法访问(我指的是公共IP,如果托管在AWS或其他地方)。即使您拥有docker主机的IP地址,但这并不意味着您可以从容器内连接到docker主机,因为docker网络可能是覆盖、主机、网桥、MAVLAN、无等,这限制了该IP地址的可访问性

编辑:

如果您使用Docker for mac或Docker for Windows 18.03+,只需使用主机host.Docker.internal(而不是连接字符串中的127.0.0.1)连接到mysql服务即可

如果您正在使用Docker for Linux 20.10.0+,也可以使用主机host.Docker.internal如果您使用--add host host.Docker.internal:host gateway选项启动Docker容器

否则,请阅读下面的内容


TLDR

使用--network=&quot;主持人</在docker run命令中,docker容器中的127.0.0.1将指向您的docker主机

注意:根据文档,此模式仅适用于Docker for Linux


关于docker容器网络模式的说明

Docker在运行容器时提供不同的网络模式。根据您选择的模式,您将以不同的方式连接到docker主机上运行的MySQL数据库

docker run--网络=&quot;桥“;(默认)

默认情况下,Docker创建名为docker0的网桥。docker主机和docker容器在该网桥上都有IP地址

在Docker主机上,键入sudo ip addr show docker0您将获得如下输出:

[[email protected]:~]$sudo ip addr show docker0
4:docker0:&lt;广播、多播、向上、向下\u向上&gt;mtu 1500 qdisc noqueue state UP组默认值
链接/以太56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16范围全局docker0
永远有效\u lft首选\u lft永远有效
inet6 fe80::5484:7aff:fefe:9799/64范围链接
永远有效\u lft首选\u lft永远有效

因此,我的docker主机在docker0网络接口上有IP地址172.17.42.1

现在启动一个新容器并在其上获得一个外壳:docker run--rm-it ubuntu:trusty bash并在容器中键入ip addr show eth0以了解其主要网络接口的设置方式:

[email protected]:/#ip地址显示eth0
863:eth0:&lt;广播,向上,向下\u向上&gt;mtu 1500 qdisc pfifo_快速状态UP组默认qlen 1000
链接/以太66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff:ff
inet 172.17.1.192/16范围全局eth0
永远有效\u lft首选\u lft永远有效
inet6 fe80::6432:13ff:fef0:f1e3/64范围链接
永远有效\u lft首选\u lft永远有效

这里我的容器有IP地址172.17.1.192。现在查看路由表:

[email protected]:/#路线
内核IP路由表
目标网关Genmask标志度量参考使用Iface
默认值172.17.42.1 0.0.0.0 UG 0 0 eth0
172.17.0.0*255.255.0.0 U 0 0 eth0

因此docker主机的IP地址172.17.42.1被设置为默认路由,可以从您的容器访问

[email protected]:/#平172.17.42.1
PING 172.17.42.1(172.17.42.1)56(84)字节的数据。
172.17.42.1中的64字节:icmp_seq=1 ttl=64时间=0.070毫秒
172.17.42.1中的64字节:icmp_seq=2 ttl=64时间=0.201毫秒
172.17.42.1中的64字节:icmp_seq=3 ttl=64时间=0.116毫秒

docker run--网络=&quot;主持人

或者,您可以运行docker容器,并将网络设置设置为host。这样的容器将与docker主机共享网络堆栈,并且从容器的角度来看,localhost(或127.0.0.1)将引用docker主机

请注意,docker容器中打开的任何端口都将在docker主机上打开。这不需要-p-pdocker run选项

我的docker主机上的IP配置:

[[email protected]:~]$ip地址显示eth0
2:eth0:&lt;广播、多播、向上、向下\u向上&gt;mtu 1500 qdisc pfifo_快速状态UP组默认qlen 1000
链接/以太08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255范围全局eth0
永远有效\u lft首选\u lft永远有效
inet6 fe80::a00:27ff:fe98:dcaa/64范围链接
永远有效\u lft首选\u lft永远有效

并从主机模式下的docker容器:

[[email protected]:~]$docker run--rm-it--network=host ubuntu:trusty ip addr show eth0
2:eth0:&lt;广播、多播、向上、向下\u向上&gt;mtu 1500 qdisc pfifo_快速状态UP组默认qlen 1000
链接/以太08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255范围全局eth0
永远有效\u lft首选\u lft永远有效
inet6 fe80::a00:27ff:fe98:dcaa/64范围链接
永远有效\u lft首选\u lft永远有效

正如您所见,docker主机和docker容器共享完全相同的网络接口,因此具有相同的IP地址


从容器连接到MySQL

桥接模式

要以桥接模式从容器访问docker主机上运行的MySQL,您需要确保MySQL服务正在侦听172.17.42.1IP地址上的连接

为此,请确保MySQL配置文件(my.cnf)中有bind address=172.17.42.1bind address=0.0.0

如果需要使用网关的IP地址设置环境变量,可以在容器中运行以下代码:

导出DOCKER\u HOST\u IP=$(路由-n | awk'/UG[\t]/{print$2}')

然后在应用程序中,使用DOCKER\u HOST\u IP环境变量打开到MySQL的连接

注意:如果使用bind address=0.0.0.0您的MySQL服务器将侦听所有网络接口上的连接。这意味着你的MySQL服务器可以通过互联网访问;确保相应地设置防火墙规则

注意2:如果使用bind address=172.17.42.1您的MySQL服务器将不会侦听到127.0.0.1的连接。在docker主机上运行的要连接到MySQL的进程必须使用172.17.42.1IP地址

主机模式

要以主机模式从容器访问docker主机上运行的MySQL,您可以在MySQL配置中保留bind address=127.0.0.1,只需从容器连接到127.0.0.1

[[email protected]:~]$docker run--rm-it--network=host mysql mysql-h 127.0.0.1-uroot-p
输入密码:
欢迎使用MySQL监视器。命令以结束;或\g。
您的MySQL连接id是36
服务器版本:5.5.41-0ubuntu0.14.04.1(Ubuntu)
版权所有(c)20002014,Oracle和/或其附属公司。版权所有。
Oracle是Oracle Corporation和/或其附属公司的注册商标。其他名称可能是其各自所有者的商标。
键入“帮助;”或“\h”以获取帮助。键入“\c”以清除当前输入语句。
mysql&gt;

注意:一定要使用mysql-h 127.0.0.1而不是mysql-h localhost;否则,MySQL客户端将尝试使用unix套接字进行连接

发表评论