编辑:
如果您使用的是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="host"
在您的命令中使用docker run
,然后127.0.0.1
在您的 docker 容器中将指向您的 docker 主机。
注意:根据文档,此模式仅适用于 Docker for Linux 。
docker 容器网络模式注意事项
Docker在运行容器时提供了不同的网络模式。根据您选择的模式,您将连接到在 docker 主机上运行的 MySQL 数据库。
docker run --network="bridge" (默认)
Docker 创建一个docker0
默认命名的网桥。docker 主机和 docker 容器在该网桥上都有一个 IP 地址。
在 Docker 主机上,键入sudo ip addr show docker0
您将看到如下输出:
[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::5484:7aff:fefe:9799/64 scope link
valid_lft forever preferred_lft forever
所以这里我的 docker 主机172.17.42.1
在docker0
网络接口上有 IP 地址。
现在启动一个新容器并在其上获取一个 shell:docker run --rm -it ubuntu:trusty bash
并在容器类型ip addr show eth0
中发现它的主网络接口是如何设置的:
root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
inet 172.17.1.192/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
valid_lft forever preferred_lft forever
这里我的容器有 IP 地址172.17.1.192
。现在查看路由表:
root@e77f6a1b3740:/# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.42.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 * 255.255.0.0 U 0 0 0 eth0
因此 docker 主机的 IP 地址172.17.42.1
被设置为默认路由,并且可以从您的容器中访问。
root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms
搬运工运行--network =“主机”
或者,您可以运行一个将网络设置设置为host
. 这样的容器将与 docker 主机共享网络堆栈,从容器的角度来看,localhost
(或127.0.0.1
)将引用 docker 主机。
请注意,在您的 docker 容器中打开的任何端口都将在 docker 主机上打开。这不需要-p
or-P
docker run
选项。
我的 docker 主机上的 IP 配置:
[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
并从主机模式下的 docker 容器中:
[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
如您所见,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.0
如果需要使用网关的 IP 地址设置环境变量,可以在容器中运行以下代码:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
然后在您的应用程序中,使用DOCKER_HOST_IP
环境变量打开与 MySQL 的连接。
注意:如果您使用bind-address = 0.0.0.0
MySQL 服务器将侦听所有网络接口上的连接。这意味着可以从 Internet 访问您的 MySQL 服务器;确保相应地设置防火墙规则。
注意 2:如果您使用bind-address = 172.17.42.1
MySQL 服务器,则不会侦听与127.0.0.1
. 在 docker 主机上运行的想要连接到 MySQL 的进程必须使用172.17.42.1
IP 地址。
主机模式
要从主机模式下的容器访问在 docker 主机上运行的 MySQL ,您可以保留bind-address = 127.0.0.1
MySQL 配置,您需要做的就是127.0.0.1
从容器连接到:
[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
注意:使用mysql -h 127.0.0.1
和不使用mysql -h localhost
;否则 MySQL 客户端将尝试使用 unix 套接字进行连接。