从 docker 容器访问主机数据库
Access host database from a docker container
如果我在某个主机上有一个 mysql 数据库 运行,并且该主机也 运行 一个 docker 容器:我将如何访问mysql 来自 运行 主机上 docker 容器内的数据库?
例如,有没有办法将主机端口发布到容器(与 docker 运行 -p 的作用相反)?
关于如何以一致、易于理解和可移植的方式执行此操作,存在多个长期讨论。没有完整的解决方案,但我会 link 你参与下面的讨论。
在任何情况下,您都想尝试使用 --add-host 选项 docker 运行 将主机的 IP 地址添加到容器的 /etc/host 文件中。从那里连接到任何所需端口上的主机是微不足道的:
Adding entries to a container hosts file
You can add other hosts into a container's /etc/hosts file by using
one or more --add-host flags. This example adds a static address for a
host named 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
Note: Sometimes you need to connect to the Docker host, which means
getting the IP address of the host. You can use the following shell
commands to simplify this process:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print }'"
$ docker run --add-host=docker:$(hostip) --rm -it debian
文档:
https://docs.docker.com/engine/reference/commandline/run/
关于从容器访问主机的讨论:
从 Docker 17.06 开始,一个特殊的 Mac-only DNS 名称在 docker 容器中可用,解析为主机的 IP 地址。它是:
docker.for.mac.localhost
文档在这里:
https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support
从 Docker 18.03 开始使用 host.docker.internal。
来自 18.03 文档:
I want to connect from a container to a service on the host
The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name host.docker.internal
, which resolves to the internal IP address used by the host.
The gateway is also reachable as gateway.docker.internal
.
示例:
这是我用于容器内的 MySQL 连接字符串以访问主机上的 MySQL 实例的内容:
mysql://host.docker.internal:3306/my_awesome_database
其他答案对我来说效果不佳。我的容器无法使用 host.docker.internal 解析主机 IP。有两种方式
共享主机网络--net=host:
docker run -it --net=host myimage
使用docker的ip地址,通常是172.17.0.1。
您可以通过调用 ifconfig 命令并获取 docker 接口
的 inet 地址来检查它
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 运行 然后传递给应用程序或者像我一样,映射 jdbc.properties 的位置通过卷到主机上的目录,因此您可以在外部管理文件。
docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage
注意:您的数据库可能不允许外部连接。对于 postgresql,您需要编辑 2 个文件,如 here and here:
所述
编辑 postgresql.conf 以侦听所有地址。默认情况下它将指向本地主机。
listen_addresses = '*'
编辑 pg_hba.conf 以允许来自所有地址的连接。在最后一行添加:
host all all 0.0.0.0/0 md5
重要提示:不建议将最后一步更新数据库访问用于生产用途,除非您真的确定自己在做什么。
仅限Linux
Case 1:-Mysqldb 运行 on localhost not on docker
你可以修复主机Ip来连接并连接到那个
ip 而不是本地主机。
对于 linux dockerhost 是固定的,即 172.17.0.1。所以连接到 172.17.0.1 而不是本地主机。
Case2:- 如果 mysqldb 在 docker 上也是 运行 那么最好的做法是连接 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!");
});
如果我在某个主机上有一个 mysql 数据库 运行,并且该主机也 运行 一个 docker 容器:我将如何访问mysql 来自 运行 主机上 docker 容器内的数据库?
例如,有没有办法将主机端口发布到容器(与 docker 运行 -p 的作用相反)?
关于如何以一致、易于理解和可移植的方式执行此操作,存在多个长期讨论。没有完整的解决方案,但我会 link 你参与下面的讨论。
在任何情况下,您都想尝试使用 --add-host 选项 docker 运行 将主机的 IP 地址添加到容器的 /etc/host 文件中。从那里连接到任何所需端口上的主机是微不足道的:
Adding entries to a container hosts file
You can add other hosts into a container's /etc/hosts file by using one or more --add-host flags. This example adds a static address for a host named 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
Note: Sometimes you need to connect to the Docker host, which means getting the IP address of the host. You can use the following shell commands to simplify this process:
$ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print }'" $ docker run --add-host=docker:$(hostip) --rm -it debian
文档:
https://docs.docker.com/engine/reference/commandline/run/
关于从容器访问主机的讨论:
从 Docker 17.06 开始,一个特殊的 Mac-only DNS 名称在 docker 容器中可用,解析为主机的 IP 地址。它是:
docker.for.mac.localhost
文档在这里: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support
从 Docker 18.03 开始使用 host.docker.internal。
来自 18.03 文档:
I want to connect from a container to a service on the host
The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name
host.docker.internal
, which resolves to the internal IP address used by the host.The gateway is also reachable as
gateway.docker.internal
.
示例: 这是我用于容器内的 MySQL 连接字符串以访问主机上的 MySQL 实例的内容:
mysql://host.docker.internal:3306/my_awesome_database
其他答案对我来说效果不佳。我的容器无法使用 host.docker.internal 解析主机 IP。有两种方式
共享主机网络--net=host:
docker run -it --net=host myimage
使用docker的ip地址,通常是172.17.0.1。 您可以通过调用 ifconfig 命令并获取 docker 接口
的 inet 地址来检查它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 运行 然后传递给应用程序或者像我一样,映射 jdbc.properties 的位置通过卷到主机上的目录,因此您可以在外部管理文件。
docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage
注意:您的数据库可能不允许外部连接。对于 postgresql,您需要编辑 2 个文件,如 here and here:
所述编辑 postgresql.conf 以侦听所有地址。默认情况下它将指向本地主机。
listen_addresses = '*'
编辑 pg_hba.conf 以允许来自所有地址的连接。在最后一行添加:
host all all 0.0.0.0/0 md5
重要提示:不建议将最后一步更新数据库访问用于生产用途,除非您真的确定自己在做什么。
仅限Linux
Case 1:-Mysqldb 运行 on localhost not on docker
你可以修复主机Ip来连接并连接到那个
ip 而不是本地主机。
对于 linux dockerhost 是固定的,即 172.17.0.1。所以连接到 172.17.0.1 而不是本地主机。
Case2:- 如果 mysqldb 在 docker 上也是 运行 那么最好的做法是连接 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!");
});