无法从 docker 容器连接到数据库 [重复]
Posted
技术标签:
【中文标题】无法从 docker 容器连接到数据库 [重复]【英文标题】:Can't connect to db from docker container [duplicate] 【发布时间】:2019-11-11 06:38:12 【问题描述】:我在服务器和 dockerized 项目上安装了 mysql 服务器,数据库不可公开访问,只能从服务器内部访问。它也被本地非 dockerized 应用程序使用。 我想从 docker 内部连接到它,但它仍然不能公开访问,我尝试了 172.17.0.1 但连接被拒绝。 当前的 bind_address 是 127.0.0.1,您建议 bind_address 是什么??
【问题讨论】:
我们需要更多信息。你是如何启动 docker 容器的?端口暴露了吗? 是的,它是端口暴露的并且具有共享卷,就是这样 数据库是否在容器内运行? 不,那会容易得多@BMitch 在那种情况下,我相信这是重复的。我刚刚在那里发布了一个答案,总结了不同的解决方案以及何时使用它们。关于这个问题还有许多其他好的答案,希望对您有用。 【参考方案1】:您可以通过host
网络模式运行应用程序,这将使容器能够连接到主服务器(docker 主机)的本地主机,同时保持bind-address
指向127.0.0.1
。
所以如果你使用 docker cli,你需要像这样运行你的应用程序:
docker run --network=host myappimage
如果是docker-compose
,您将使用 is in your service:
network_mode: host
【讨论】:
这很有趣,但在我的情况下它不起作用我没有从容器运行 MySQL,它在服务器上,按原样将它绑定到 0.0.0.0 会将它暴露在服务器之外,我认为你的意思是 -p 不是 -v @t2149573,对不起,我一开始就错了,我已经更新了我的答案【参考方案2】:首先尝试更好地描述我从您的问题中理解的内容:
你有一个安装了 mysql 的主机(不是 dockerized,而是直接 在您的主机上)
您有一些客户端应用程序连接到您的主机中的那个 MySQL 使用您的 localhost IP 和 mysql 端口(假设: 默认为 127.0.0.1:3306)
现在您创建了一个带有另一个应用程序的 docker 容器(在 容器)你想与你的 MySQL 服务器连接, 它仍在您的主机中运行,可在本地访问,但 out 您的新容器(或任何其他容器)
您希望您的 dockerized 服务保持隔离,与容器之外的其他任何东西(当然是 MySQL 服务器)没有其他联系
⚠️ 好吧,我将首先排除使用 --net=host 的选项(即使它可以在类似情况下工作以允许您的服务“存在”在主机的网络中) ) 因为您不希望您的容器可以从其他主机的进程中使用,也不能访问其他任何内容(host networking 会发生这种情况)
连接到主机中的 [non-dockerized] 服务
✔️ 在这种情况下,您实际需要做的(从容器内的应用程序)连接到 Docker 主机的 IP
但不是常规本地网络中的 IP(例如:192.168.1.5)或公共/wlan 网络中的 IP,而是 docker 分配给 docker 网络本身中的主机的 IP(docker 创建的网络)在您的容器之间进行通信)
默认情况下(如果您没有为容器指定任何其他网络设置),您的容器应该使用 docker 的 bridge network,它是在主机中设置的(而不是在容器内)并且通常命名为 docker0
因此,只需找到与您的主机对应的 IP,并将其用作您的 mysql 客户端的 bind_address(例如:jdbc:mysql://172.X.XX.XX:3306
或 $dbhost = "172.X.XX.XX";
等)
我的 Docker 主机 IP 地址是什么?
好的...如何找到 docker 分配给我的主机的 IP(用于 docker 桥接网络的 IP)?
手动您可以列出您当前分配的所有 IP 地址,以找到与该 docker0 网络对应的一个:
ip -4 addr
或者直接过滤你想要的更好:
ip -4 addr show docker0
你会得到类似这样的输出:
3: docker0: mtu 1500 qdisc noqueue
inet 172.17.0.1/16 brd 172.17.255.255 作用域全局 docker0
valid_lft 永远首选_lft 永远
并复制inet
之后出现的ip
自动地
我喜欢使用这个脚本直接获取我当前 docker 的主机 IP(在跨多个主机进行测试时特别有用):
ip -4 addr show docker0 | awk '$1=="inet" print $2' | cut -d/ -f1
只需将它放在分配给某个环境变量的某个方便的地方(例如,在您的/.bashrc
中):
export DOCKER_HOST_IP="$(ip -4 addr show docker0 | awk '$1=="inet" print $2' | cut -d/ -f1 )"
希望它有用!
【讨论】:
实际上这是我在问题中所说的第一件事,它仅在我将数据库更改为可公开访问时才有效。绑定到 127.0.0.1 的 mysql 只能通过此接口访问,即使 docker 网关(172.17.0.1)也无法看到它。我想我会尝试 --net=host 看看它是否适合我,我认为这是目前唯一合乎逻辑的解决方案。不过,感谢您的冗长回答,如果数据库可以公开访问,这是一个很好的参考 非常感谢您的详细回答。以上是关于无法从 docker 容器连接到数据库 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
从 docker-compose 文件连接到 Postgres docker 容器 [重复]
无法从 Spring Boot Docker 容器连接到本地 MySQL 数据库服务器