从Docker容器的内部,如何连接到本机的本机? [英] From inside of a Docker container, how do I connect to the localhost of the machine?

查看:196
本文介绍了从Docker容器的内部,如何连接到本机的本机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个Nginx运行在docker容器中,我有一个在localhost上运行的mysql,我想从我的Nginx内连接到MySql。 MySql在本地主机上运行,​​不会将端口暴露给外界,所以它绑定在本地机器上,不受机器的IP地址的束缚。



有没有连接到这个Docks容器中的MySql或localhost上的任何其他程序?

解决方案

关于docker容器联网模式的注意事项



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



docker run --net =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永远preferred_lft永远
inet6 fe80 :: 5484:7aff:fefe:9799/64范围链接
valid_lft永远preferred_lft永远

所以这里我的docker主机在 docker0上的IP地址 172.17.42.1 / code>网络接口。



现在启动一个新的容器并获取一个shell: docker run --rm -it ubuntu :trusty bash -il 并在容器类型 ip addr中显示eth0 以了解其主网络接口的设置方式:

  root @ e77f6a1b3740:/#ip addr show eth0 
863:eth0:< BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast状态UP组默认qlen 1000
link / ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
inet 172.17.1.192/16范围全局eth0
valid_lft永远preferred_lft永远
inet6 fe80 :: 6432:13ff:fef0:f1e3 / 64范围链接
valid_lft永远preferred_lft永远
/ pre>

这里我的容器有IP地址 172.17.1.192 。现在看看路由表:

  root @ e77f6a1b3740:/#route 
内核IP路由表
目的地网关基因组标志度量标准参考使用Iface
默认值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)个字节的数据。
从172.17.42.1 64个字节:icmp_seq = 1 ttl = 64时间= 0.070毫秒
从172.17.42.1 64个字节:icmp_seq = 2 ttl = 64时间= 0.201毫秒
从172.17 64字节.42.1:icmp_seq = 3 ttl = 64 time = 0.116 ms



docker run --net =host



或者,您也可以使用网络设置设置为主机 。这样的容器将与docker主机和容器的角度共享网络堆栈, localhost (或 127.0.0.1 )将指向docker主机。



请注意,您的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状态UP组默认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范围全局eth0
valid_lft永远preferred_lft永远
inet6 fe80 :: a00:27ff:fe98:dcaa / 64范围链接
valid_lft永远preferred_lft永远

主机模式中的码头容器:

  [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状态UP组默认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范围全局eth0
valid_lft永远preferred_lft永远
inet6 fe80 :: a00:27ff:fe98:dcaa / 64范围链接
valid_lft永远preferred_lft永远

您可以看到docker主机和docker容器共享完全相同的网络接口,因此具有相同的IP地址。




从容器连接到MySQL



桥接模式



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



为此,请确保您有 bind-address = 172.17。您的MySQL配置文件(my.cnf)中的42.1 bind-address = 0.0.0.0



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

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

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

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



注意2:如果您使用 bind-address = 172.17.42.1 您的MySQL服务器不会收听 127.0.0.1 之间的连接。在Docker主机上运行的想要连接到MySQL的进程必须使用 172.17.42.1 IP地址。



< h2>主机模式

要在主机模式的容器中访问Docker主机上运行的MySQL,可以保留 bind您的MySQL配置中的-address = 127.0.0.1 ,您需要做的就是从容器连接到 127.0.0.1

  [vagrant @ docker:〜] $ docker运行--rm -it --net =主机mysql mysql -h 127.0.0.1 -uroot -p 
输入密码:
欢迎使用MySQL监视器。命令以;或\g。
您的MySQL连接ID为36
服务器版本:5.5.41-0ubuntu0.14.04.1(Ubuntu)

版权所有(c)2000,2014,Oracle和/或其分支机构。版权所有。

Oracle是Oracle Corporation和/或其附属公司的注册商标。其他名称可能是其各自所有者的商标。

输入'help;'或'\h'来寻求帮助。键入'\c'以清除当前的输入语句。

mysql>


So I have a Nginx running inside a docker container, I have a mysql running on localhost, I want to connect to the MySql from within my Nginx. The MySql is running on localhost and not exposing a port to the outside world, so its bound on localhost, not bound on the ip address of the machine.

Is there any way to connect to this MySql or any other program on localhost from within this docker container?

解决方案

Note on docker container networking modes

Docker offers different networking modes when running containers. Depending on the mode you choose you would connect to your MySQL database running on the docker host differently.

docker run --net="bridge" (default)

Docker creates a bridge named docker0 by default. Both the docker host and the docker containers have an IP address on that bridge.

on the Docker host, type sudo ip addr show docker0 you will have an output looking like:

[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

So here my docker host has the IP address 172.17.42.1 on the docker0 network interface.

Now start a new container and get a shell on it: docker run --rm -it ubuntu:trusty bash -il and within the container type ip addr show eth0 to discover how its main network interface is set up:

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

Here my container has the IP address 172.17.1.192. Now look at the routing table:

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

So the IP Address of the docker host 172.17.42.1 is set as the default route and is accessible from your container.

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 --net="host"

Alternatively you can run a docker container with network settings set to host. Such a container will share the network stack with the docker host and from the container point of view, localhost (or 127.0.0.1) will refer to the docker host.

Be aware that any port opened in your docker container would be opened on the docker host. And this without requiring the -p or -P docker run option.

IP config on my docker host:

[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

and from a docker container in host mode:

[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

As you can see both the docker host and docker container share the exact same network interface and as such have the same IP address.


Connecting to MySQL from containers

bridge mode

To access MySQL running on the docker host from containers in bridge mode, you need to make sure the MySQL service is listening for connections on the 172.17.42.1 IP address.

To do so, make sure you have either bind-address = 172.17.42.1 or bind-address = 0.0.0.0 in your MySQL config file (my.cnf).

If you need to set an environment variable with the IP address of the gateway, you can run the following code in a container :

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

then in your application, use the DOCKER_HOST_IP environment variable to open the connection to MySQL.

Note: if you use bind-address = 0.0.0.0 your MySQL server will listen for connections on all network interfaces. That means your MySQL server could be reached from the Internet ; make sure to setup firewall rules accordingly.

Note 2: if you use bind-address = 172.17.42.1 your MySQL server won't listen for connections made to 127.0.0.1. Processes running on the docker host that would want to connect to MySQL would have to use the 172.17.42.1 IP address.

host mode

To access MySQL running on the docker host from containers in host mode, you can keep bind-address = 127.0.0.1 in your MySQL configuration and all you need to do is to connect to 127.0.0.1 from your containers:

[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>

这篇关于从Docker容器的内部,如何连接到本机的本机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆