从 Docker 容器内部如何连接到宿主机的 localhost

如果你正在使用Docker-for-mac或Docker-for-Windows 18.03+版本,请使用主机名host.docker.internal(而不是连接字符串中的127.0.0.1)来连接到你的MySQL服务。

如果你正在使用Docker-for-Linux 20.10.0+版本,并且你在启动Docker容器时使用了--add-host host.docker.internal:host-gateway选项,或者在你的docker-compose.yml文件中添加了以下代码段:

extra_hosts:
  - "host.docker.internal:host-gateway"

那么你也可以使用主机名host.docker.internal。

否则,请继续阅读以下内容:

TLDR

在你的docker run命令中使用--network="host"选项,那么在你的Docker容器中,127.0.0.1将指向你的Docker主机。

注意:根据文档,此模式仅适用于Linux上的Docker容器。

关于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 
    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主机在docker0网络接口上的IP地址是172.17.42.1。

现在启动一个新的容器并进入其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

查看路由表:

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      0.0.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

另外,你可以运行一个网络设置为主机(host)的Docker容器。这样的容器将与Docker主机共享网络堆栈,并且从容器的角度来看,localhost(或127.0.0.1)将指向Docker主机。请注意,在Docker容器中打开的任何端口也将在Docker主机上打开,而无需使用-p-Pdocker run选项。

我的Docker主机的IP配置:

[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP 
    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 s
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP 
    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服务器将监听所有网络接口上的连接。这意味着您的MySQL服务器可以从Internet上访问;请确保相应地设置防火墙规则。

注意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:

[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套接字进行连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李星星BruceL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值