nginx - Nginx 从 Docker 容器内部,如何连接到机器的主机?

  显示原文与译文双语对照的内容

所以我有一个 Nginx 运行在 Docker 容器中,我有一个在localhost上运行的MySql,我想从 Nginx 中连接到 MySql 。 MySql在本地主机上运行,不向外部公开端口,因此它在本地主机上绑定,而不是绑定在机器的ip地址上。

是否有任何方法可以在这里 Docker 容器中连接到本机或者任何它的他程序?

时间: 原作者:

关于 Docker 容器网络模式的说明

Docker 提供不同的网络模式,当运行容器时。 根据你选择的模式,你将连接到运行在 Docker 主机上的数据库。

Docker 运行 --net="桥接器"( 默认)

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 -il 在容器类型内 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 主机 172.17.42.1的IP地址被设置为默认路由,并且可以从你的容器访问。


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 运行 --net="主机"

或者,你可以运行一个带有网络设置设置为 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 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 --net=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

桥接模式

要访问在桥模式的容器上运行的MySQL,需要确保MySQL服务监听 172.17.42.1 IP地址上的连接。

为此,请确保在 bind-address = 172.17.42.1 配置文件( my.cnf ) 中有或者 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服务器;确保相应地设置防火墙规则。

注意:如果使用 bind-address = 172.17.42.1,你的MySQL服务器将不侦听对 127.0.0.1的连接。 运行在 Docker 主机上的进程需要连接到 MySQL,它必须使用 172.17.42.1 IP地址。

主机模式

要访问在主机模式 containers主机模式上运行的MySQL,你可以在MySQL配置中保留 bind-address = 127.0.0.1,并且你需要在容器中连接到 127.0.0.1:


[vagrant@docker:~] $ docker run --rm -it --net=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套接字进行连接。

原作者:
...