从Docker容器访问主机数据库


131

如果我在某个主机上运行mysql数据库,并且该主机也正在运行docker容器:我如何从主机上运行的docker容器中访问mysql数据库?

例如,是否有一种方法可以将主机端口发布到容器(与docker run -p的作用相反)?


1
如果MySQL服务器正在侦听端口,那么容器是否不能像其他任何Internet连接一样连接到该端口上的主机?
jwodder

Answers:


87

关于如何以一致,易于理解和可移植的方式执行此操作,已有许多长期讨论。尚无完整的解决方案,但我会将您链接到下面的讨论。

无论如何,您都想尝试使用--add-host选项在docker run中尝试将主机的IP地址添加到容器的/ etc / host文件中。从那里可以很容易地在任何所需的端口上连接到主机:

将条目添加到容器主机文件

您可以使用一个或多个--add-host标志将其他主机添加到容器的/ etc / hosts文件中。本示例为名为docker的主机添加静态地址:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

注意:有时您需要连接到Docker主机,这意味着获取主机的IP地址。您可以使用以下shell命令来简化此过程:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

说明文件:

https://docs.docker.com/engine/reference/commandline/run/

关于从容器访问主机的讨论:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023


它也会在NGINX反向代理后面工作吗?
kta

89

从18.03文档:

我想从容器连接到主机上的服务

主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们建议您连接到特殊的DNS名称host.docker.internal,该解析为主机使用的内部IP地址。

网关也可以通过访问gateway.docker.internal

示例:这是我用于在容器内访问主机上的MySQL实例的MySQL连接字符串的方法:

mysql://host.docker.internal:3306/my_awesome_database

31
只是提示:到目前为止,这仅适用于Mac和Win
flp 18-4-25

您保存了我的一天:)
amjad

4
赞成。不仅是因为答案,还因为您应该通过示例使用它。
granadaCoder

非常感谢我花了2个小时来实现这一目标。
Ashish Bainade

对于那些好奇的人,仍然没有@flp所写的Linux支持。这是github问题
GAltelino


24

从Docker 18.03开始使用host.docker.internal


2
怎么样 ?您能举一个使用它的例子吗?
danfromisrael

为什么不运行dockerized mysql?
伊戈尔·德奥利维拉

不适用于我Docker version 18.03.0-ce, build 0520e24
scythargon

@IgorDeOliveiraSá想象以下情况,在开发环境中,您有一些数据库可以在生产环境上侦听127.0.0.1:3306,而数据库在侦听127.0.0.1:3306,本地是本地数据库,生产是云的代理,您必须在本地dockerise mysql,并在生产环境中找到另一个解决方案,或者您可以从docker连接到端口,这两种情况都适用
Drachenfels

1
docker.for.mac.localhost在我身上工作18.03.1-ce-mac65
cdignam

21

其他答案对我而言效果不佳。我的容器无法使用host.docker.internal解析主机ip 。有两种方法

  1. 共享主机网络--net = host:

    docker run -it --net=host  myimage
    
  2. 使用docker的ip地址,通常是172.17.0.1。您可以通过调用ifconfig命令并抓住docker接口的inet addr进行检查

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

一旦有了该IP地址,就可以将其作为参数传递给docker run,然后传递给应用程序,或者像我一样,通过卷将jdbc.properties的位置映射到主机上的目录,以便可以从外部管理文件。

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

注意:您的数据库可能不允许外部连接。对于postgresql,您需要编辑2个文件,如此此处所述

  1. 编辑postgresql.conf以侦听所有地址。默认情况下,它将指向localhost。

    listen_addresses = '*'
    
  2. 编辑pg_hba.conf以允许来自所有地址的连接。在最后一行添加:

    host     all             all             0.0.0.0/0               md5
    

重要说明:建议不要在生产中使用最后一步更新数据库访问权限,除非您确实确定自己在做什么。


--net = host在CI环境下为我工作,非常感谢!
萨米
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.