我有一个Nginx在码头集装箱里运行。我在主机系统上运行了MySql。我想从我的容器中连接到MySql。MySql仅绑定到本地主机设备。

是否有任何方法可以从这个docker容器连接到这个MySql或本地主机上的任何其他程序?

这个问题与“如何从docker容器中获取docker主机的IP地址”不同,因为docker主机IP地址可以是网络中的公共IP或私有IP,而这些IP可能在docker容器内无法访问(如果托管在AWS或其他地方,我指的是公共IP)。即使你有docker主机的IP地址,这并不意味着你可以从容器内连接到docker主机,因为你的docker网络可能是overlay、host、bridge、macvlan、none等,这限制了该IP地址的可达性。


当前回答

Linux解决方案(内核>=3.6)。

好的,本地主机服务器有一个默认的docker接口docker0,IP地址为172.17.0.1。容器以默认网络设置--net=“bridge”启动。

为docker0接口启用route_localnet:$sysctl-w net.ipv4.conf.docker0.route_localnet=1将这些规则添加到iptables:$iptables-t nat-I预路由-I docker0-d 172.17.0.1-p tcp--dport 3306-j DNAT--to 127.0.0.1:3306$iptables-t filter-I INPUT-I docker0-d 127.0.0.1-p tcp--dport 3306-j ACCEPT创建具有从“%”访问权限的MySQL用户,这意味着-来自任何人,不包括本地主机:CREATE USER“USER”@“%”IDENTIFIED BY“password”;在脚本中将mysql服务器地址更改为172.17.0.1。

从内核文档中:

route_localnet-BOOLEAN:在路由时,不要将环回地址视为火星源或目的地。这允许将127/8用于本地路由目的(默认为FALSE)。

其他回答

在修复程序未合并到主分支之前,只需从容器内部运行主机IP即可:

ip -4 route list match 0/0 | cut -d' ' -f3

(正如@Mahoney在这里所建议的)。

对于我来说,在主机上执行此命令以获取ip的做法是:

docker run busybox ping -c 1 host.docker.internal | awk 'FNR==2 {print $4}' | sed s'/.$//'

或在mac上

docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'

码头组合.yml

version: '3.8'

services:
  spring-app-container:
    image: spring-app:1
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "50800:50800"

适用于所有平台

Docker v 20.10及以上(自2020年12月14日起)

使用内部IP地址或连接到特殊DNS名称host.docker.internal,该名称将解析为主机使用的内部IP地址。

在Linux上,使用Docker命令,将--add host=host.Docker.internal:host gateway添加到Docker命令以启用此功能。

要在Linux上的Docker Compose中启用此功能,请在容器定义中添加以下行:

extra_hosts:
    - "host.docker.internal:host-gateway"

对于较旧的macOS和Windows版本的Docker

Docker v 18.03及以上(自2018年3月21日起)

使用内部IP地址或连接到特殊DNS名称host.docker.internal,该名称将解析为主机使用的内部IP地址。

Linux支持待定https://github.com/docker/for-linux/issues/264

对于Docker的旧macOS版本

Mac版本17.12至18.02的Docker

同上,但改用docker.for.mac.host.internal。

Mac版Docker 17.06至17.11

同上,但改用docker.for.mac.localhost。

适用于Mac 17.05及以下版本的Docker

要从docker容器访问主机,必须将IP别名附加到网络接口。您可以绑定任何您想要的IP,只需确保您没有将其用于其他任何内容。

sudo ifconfig lo0别名123.123.123.123/24

然后确保您的服务器正在侦听上面提到的IP或0.0.0.0。如果它在本地主机127.0.0.1上侦听,它将不接受连接。

然后只需将docker容器指向该IP,即可访问主机!

为了测试,可以在容器内运行类似curl-X GET 123.123.123.123:3000的命令。

别名将在每次重新启动时重置,因此如果需要,请创建启动脚本。

此处的解决方案和更多文档:https://docs.docker.com/docker-for-mac/networking/#use-案例和解决方案

你需要知道网关!我使用本地服务器的解决方案是在0.0.0.0:8000下公开它,然后使用子网运行docker并运行容器,如下所示:

docker network create --subnet=172.35.0.0/16 --gateway 172.35.0.1 SUBNET35
docker run -d -p 4444:4444 --net SUBNET35 <container-you-want-run-place-here>

因此,现在您可以通过http://172.35.0.1:8000

试试看:

version: '3.5'
services:
  yourservice-here:
    container_name: container_name
    ports:
      - "4000:4000"
    extra_hosts: # <---- here
      - localhost:192.168.1.202
      - or-vitualhost.local:192.168.1.202

要获取192.168.1.202,请使用ifconfig

这对我有用。希望能帮上忙!