从码头容器访问主机数据库

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

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

171063 次浏览

关于如何以一致的、易于理解的和可移植的方式实现这一点,有几个长期的讨论。没有完整的解决方案,但我会链接到下面的讨论。

在任何情况下,您都可以尝试使用—— add-host 选项 to docker run 将主机的 ip 地址添加到容器的/etc/host 文件中。从这里开始,在任何需要的端口上连接到主机就变得很简单了:

向容器主机文件添加条目

您可以使用以下命令将其他主机添加到容器的/etc/hosts 文件中 一个或多个—— add-host 标志 主机名为 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 地址 命令来简化这个过程:

 $ 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

从 Docker 17.06开始,在解析为主机 IP 地址的 Docker 容器中提供了一个特殊的 Mac 专用 DNS 名称。它是:

Docker.for.mac.localhost

文档在这里: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support

从 Docker 18.03开始使用 主机,码头,内部

来自18.03的文档:

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

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

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

例子: 下面是我在容器中用于访问主机上的 MySQL 实例的 MySQL 连接字符串:

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

其他的答案对我不起作用。我的容器无法使用 主机,码头,内部解析主机 ip。有两种方法

  1. 共享主机网络——网络 = 主机:

    docker run -it --net=host  myimage
    
  2. Using docker's ip address, which is usually 172.17.0.1. You can check it by calling ifconfig command and grabbing inet addr of docker interface

    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
    

Once you have this ip address, you can pass it as an argument to docker run and then to application or as I do it, map the location of jdbc.properties via volume to the directory on host machine, so you can manage the file externally.

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

注意: 您的数据库可能不允许外部连接。在 postgreql 的情况下,您需要编辑2个文件,如 给你给你所述:

  1. 编辑 postgreql.conf 来监听所有地址,默认情况下它会指向 localhost。

    listen_addresses = '*'
    
  2. Edit pg_hba.conf to allow connections from all addresses. Add on the last line:

    host     all             all             0.0.0.0/0               md5
    

IMPORTANT: Last step updating database access is not recommended for production use unless you are really sure what you are doing.

< p > 只适用于 Linux < br > 在 localhost 上运行的 Mysqldb 不在 docker < br > 你可以修复主机 Ip 来连接它 Ip 代替 localhost 因为 linux dockerhost 是固定的,它是 172.17.0。所以请连接到 172.17.0而不是 localhost。 < br > 如果 mysqldb 也在 docker 上运行,那么最好的做法是连接到 码头集装箱名称,而不是 IP 地址。
所以 docker-compose 文件应该是这样的

version: '3.8'
services:
mysqldb:
image: mysql:5.7
restart: unless-stopped
env_file: ./.env
environment:
- MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
- MYSQL_DATABASE=$MYSQLDB_DATABASE
ports:
- $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
volumes:
- db:/var/lib/mysql
producer:
build: .
ports:
- '$LOCAL_PORT:$DOCKER_PORT'
depends_on:
- mysqlsb
volumes:
- ./:/usr/src/app

现在不使用 ip 或 localhost 连接 mysqlsb

var mysql = require('mysql');


var con = mysql.createConnection({
host: mysqldb,
user: "yourusername",
password: "yourpassword"
});


con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});