当前位置: 首页 > 面试题库 >

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

白修谨
2023-03-14
问题内容

所以我有一个Nginx在docker容器中运行,我有一个mysql在本地主机上运行,​​我想从我的Nginx内部连接到MySql。MySql在localhost上运行,并且没有将端口暴露给外界,因此它绑定在localhost上,而不绑定在计算机的IP地址上。

有什么方法可以从此Docker容器中连接到此MySql或localhost上的任何其他程序吗?

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


问题答案:

编辑: 如果您使用的是Docker-for-mac或Docker-for-
Windows

18.03+,只需使用主机host.docker.internal(而不是127.0.0.1连接字符串中的)连接到您的mysql服务。

从Docker 18.09.3开始,这不适用于Linux上的Docker。
一个修复已三月提交的8日,2019年将有望被合并到代码库。在此之前,解决方法是使用qoomon的answer中所述的容器。

2020-01:
取得了一些进展。如果一切顺利,这应该可以在Docker
20.04中找到

TLDR

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

注意:根据文档,此模式仅适用于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.1docker0网络接口上具有IP地址。

现在启动一个新容器并在其上安装一个外壳:docker run --rm -it ubuntu:trusty bash在容器类型内,ip addrshow 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”

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

请注意,您在Docker容器中打开的任何端口都将在Docker主机上打开。而且这不需要-por -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.1IP地址上的连接。

要做到这一点,请确保您有两种bind-address = 172.17.42.1或者bind-address = 0.0.0.0在你的MySQL配置文件(my.cnf中)。

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

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

然后在您的应用程序中,使用DOCKER_HOST_IP环境变量打开与MySQL的连接。

注意: 如果使用bind-address = 0.0.0.0MySQL服务器,它将监听所有网络接口上的连接。这意味着您可以从Internet访问MySQL服务器。确保相应地设置防火墙规则。

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

主机模式

要以 主机模式 从容器访问在docker主机上运行的MySQL ,您可以保持bind-address = 127.0.0.1MySQL配置,而要做的就是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套接字进行连接。



 类似资料:
  • 问题内容: 我正在运行一个docker mysql映像,以下是docker-compose.yml文件的外观: 这很好。 我的问题是:如何从主机(我的Macbook)上的命令行mysql客户端连接到在该容器上运行的MySQL实例? 澄清: 我有一台装有Docker的Macbook 我有一个带有mysql的docker容器 我想从Macbook的终端连接到上述容器上运行的mysql实例 我不想使用命

  • 澄清: 我有一台安装了Docker的macbook 我有一个带有MySQL的docker容器 我想从MacBook上的终端连接到在上述容器上运行的mysql实例 我不想使用命令来实现此操作。相反,我想直接从终端使用客户机(而不通过docker容器隧道进入)。 我没有在本地运行MySQL,所以端口3306应该是打开的,可以随时使用。 我用来启动容器的命令是:

  • 我有一个运行java进程的docker容器,我试图将该进程连接到本地主机上运行的rabbitmq。 以下是我到目前为止所做的步骤: null 能够ping local-ip和curl rabbitmq admin api [{“名称”:“/”,“跟踪”:false}] 当我试图从容器内部telnet时,我得到 由:java.net.ConnectException:在java.net.plains

  • 问题内容: 所以我想连接到我在主机上运行的mongodb(DO Drop,Ubuntu 16.04)。它在localhost 的默认端口上运行。 然后,我使用mup将我的Meteor应用程序部署在我的DO Drop上,该DO Drop使用docker在容器内运行Meteor应用程序。到目前为止,一切都很好。使用标准连接URL将应用程序连接到mongodb。现在我有以下问题: 显然不能在docker

  • 问题内容: 如标题所示。我需要能够检索Docker主机的IP地址和从主机到容器的端口映射,并在容器内部进行操作。 问题答案: 正如@MichaelNeale注意到的那样,没有必要使用此方法(除非仅在构建时需要此IP),因为此IP将在构建时进行硬编码。

  • 我试图在我本地的电脑上使用kafka(Windows10)作为生产者,在docker容器(ubuntu)上使用spark流作为消费者。我的示例在容器中一起工作,但我需要在本地计算机上创建流。 在容器的另一边,我正在监听端口2181来接收流。 我希望你能帮助我。谢了。