从 Docker 容器内部,如何连接到机器的本地主机?
P粉787820396
P粉787820396 2023-08-23 11:55:48
0
2
627
<p>我有一个 Nginx 在 docker 容器内运行。我有一个在主机系统上运行的 MySql。我想从我的容器内连接到 MySql。 MySql 仅绑定到本地主机设备。</p> <p>有什么方法可以从这个 docker 容器内连接到这个 MySql 或本地主机上的任何其他程序吗?</p> <p>这个问题与“如何从docker容器内获取docker主机的IP地址”不同,因为docker主机的IP地址可能是网络中的公共IP或私有IP,可能或可能无法从 docker 容器内访问(我的意思是公共 IP,如果托管在 AWS 或其他地方)。即使您拥有 docker 主机的 IP 地址,也不意味着您可以从容器内连接到 docker 主机,因为您的 Docker 网络可能是覆盖网络、主机网络、网桥网络、macvlan 网络、none 网络等,这限制了容器的可达性该 IP 地址。</p>
P粉787820396
P粉787820396

全部回复(2)
P粉517090748

适用于所有平台

Docker v 20.10 及更高版本(自 2020 年 12 月 14 日起)

使用您的内部 IP 地址或连接到特殊 DNS 名称 host.docker.internal,该名称将解析为主机使用的内部 IP 地址。

这是出于开发目的,不适用于 Docker Desktop 之外的生产环境。

Linux 警告

要在 Linux 上的 Docker 中启用此功能,请将 --add-host=host.docker.internal:host-gateway 添加到您的 docker 命令启用该功能。

要在 Linux 上的 Docker Compose 中启用此功能,请将以下行添加到容器定义中:

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

根据一些用户的说法,特殊的 DNS 名称仅在 Docker 的默认bridge 网络中有效,而在自定义网络中无效。

对于旧版 macOS 和 Windows 版本的 Docker

Docker v 18.03 及更高版本(自 2018 年 3 月 21 日起)

使用您的内部 IP 地址或连接到特殊 DNS 名称 host.docker.internal,该名称将解析为主机使用的内部 IP 地址。

Linux 支持待定 https://github.com/docker/for-linux/issues /264

对于旧版 macOS 版本的 Docker

Docker for Mac v 17.12 至 v 18.02

与上面相同,但使用docker.for.mac.host.internal

Docker for Mac v 17.06 至 v 17.11

与上面相同,但使用docker.for.mac.localhost代替。

适用于 Mac 17.05 及更低版本的 Docker

要从 docker 容器访问主机,您必须将 IP 别名附加到您的网络接口。您可以绑定任何您想要的 IP,只要确保您没有将其用于其他任何地方即可。

sudo ifconfig lo0 别名 123.123.123.123/24

然后确保您的服务器正在侦听上述 IP 或 0.0.0.0。如果它正在监听本地主机127.0.0.1,它将不接受连接。

然后只需将你的docker容器指向这个IP就可以访问主机了!

要进行测试,您可以在容器内运行类似 curl -X GET 123.123.123.123:3000 的内容。

别名将在每次重新启动时重置,因此如有必要,请创建启动脚本。

此处的解决方案和更多文档:https ://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms

P粉019353247

编辑:

如果您使用Docker-for-macDocker-for-Windows 18.03+,使用主机 host.docker.internal (而不是 127.0.0.1 在您的连接字符串中)。

如果您使用的是 Docker-for-Linux 20.10.0+,您还可以使用主机 host.docker.internal if您使用 --add-host host.docker.internal:host-gateway 选项启动了 Docker 容器,或者在 docker-compose.yml 文件中添加了以下代码段:

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

否则,请阅读下文


TLDR

docker run 命令中使用 --network="host",然后 docker 容器中的 127.0.0.1 将指向您的码头工人主机。

注意:此模式仅适用于 Linux 版 Docker,根据文档。 p>


关于 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 主机在 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

这里我的容器的 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

docker run --network="host"

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

请注意,在 docker 容器中打开的任何端口都将在 docker 主机上打开。这不需要 -p 或 -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.1bind-address = 0.0.0.0 )。

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

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print }')

然后在您的应用程序中,使用 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 套接字进行连接。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板