所以我有一个运行在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=";主持人</在
docker run
命令中,docker容器中的127.0.0.1
将指向您的docker主机
注意:根据文档,此模式仅适用于Docker for Linux
关于docker容器网络模式的说明
Docker在运行容器时提供不同的网络模式。根据您选择的模式,您将以不同的方式连接到docker主机上运行的MySQL数据库
docker run--网络=";桥“;(默认)
默认情况下,Docker创建名为docker0
的网桥。docker主机和docker容器在该网桥上都有IP地址
在Docker主机上,键入sudo ip addr show docker0
您将获得如下输出:
[[email protected]:~]$sudo ip addr show docker0
4:docker0:<;广播、多播、向上、向下\u向上>;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:<;广播,向上,向下\u向上>;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--网络=";主持人
或者,您可以运行docker容器,并将网络设置设置为host
。这样的容器将与docker主机共享网络堆栈,并且从容器的角度来看,localhost
(或127.0.0.1
)将引用docker主机
请注意,docker容器中打开的任何端口都将在docker主机上打开。这不需要-p
或-p
docker run
选项
我的docker主机上的IP配置:
[[email protected]:~]$ip地址显示eth0
2:eth0:<;广播、多播、向上、向下\u向上>;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:<;广播、多播、向上、向下\u向上>;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.1
IP地址上的连接
为此,请确保MySQL配置文件(my.cnf)中有bind address=172.17.42.1
或bind 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.1
IP地址
主机模式
要以主机模式从容器访问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>;
注意:一定要使用mysql-h 127.0.0.1
而不是mysql-h localhost
;否则,MySQL客户端将尝试使用unix套接字进行连接