简体   繁体   English

什么是 Compose 文件中的 --add-host=host.docker.internal:host-gateway 的等价物

[英]What is the equivalent of --add-host=host.docker.internal:host-gateway in a Compose file

Starting from Docker version 20.10 ( https://github.com/moby/moby/pull/40007 ), there is a new special string host-gateway that one can use within the --add-host run flag to allow a direct connection from inside a docker container to the local machine on Linux based systems.从 Docker 版本20.10 ( https://github.com/moby/moby/pull/40007 ) 开始,有一个新的特殊字符串host-gateway可以在--add-host运行标志中使用以允许直接连接从 docker 容器内部到基于 Linux 的系统上的本地计算机。 And this is very nice.这是非常好的。

But what is the equivalent of --add-host=host.docker.internal:host-gateway in a Compose file?但是 Compose 文件中的--add-host=host.docker.internal:host-gateway的等价物是什么?

eg in:例如在:

$ docker run \
  --rm \
  --name postgres \
  -p "5433:5432" \
  -e POSTGRES_PASSWORD=**** \
  --add-host=host.docker.internal:host-gateway \
  -d postgres:14.1-bullseye

How would the same --add-host flag fit in this Docker Compose equivalent template:相同的--add-host标志如何适合此 Docker Compose 等效模板:

version: '3.9'

services:
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: ****
    ports:
      - "5433:5432"

It's for sure not: network_mode: host at the service level (see #Doc ).肯定不是: network_mode: host (请参阅#Doc )。

The actual Docker Compose equivalent is achieved by appending the same string to the extra_hosts parameters ( #Doc ) as:实际的 Docker Compose 等效项是通过将相同的字符串附加到extra_hosts参数 ( #Doc ) 来实现的:

version: '3.9'

services:
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: ****
    ports:
      - "5433:5432"
    extra_hosts:
      - "host.docker.internal:host-gateway"

You can see it has been successfully mapped to the IP of the docker0 interface, here 172.17.0.1 , from inside your container, eg:你可以看到它已经从你的容器内部成功映射到docker0接口的 IP ,这里是172.17.0.1 ,例如:

$ docker-compose up -d
$ docker-compose exec postgres bash

then, from inside the container:然后,从容器内部:

root@5864db7d7fba:/# apt update && apt -y install netcat
root@5864db7d7fba:/# nc -vz host.docker.internal 80
Connection to host.docker.internal (172.17.0.1) 80 port [tcp/http] succeeded!

(assuming port 80 is not closed or constrained to the IP of the docker0 interface by a firewall on the host machine). (假设 80 端口没有被主机上的防火墙关闭或限制为docker0接口的 IP)。

More on this can be found here:更多信息可以在这里找到:
https://medium.com/@TimvanBaarsen/how-to-connect-to-the-docker-host-from-inside-a-docker-container-112b4c71bc66 https://medium.com/@TimvanBaarsen/how-to-connect-to-the-docker-host-from-inside-a-docker-container-112b4c71bc66

But... beware...但是……小心……

Warning ⚠️警告⚠️

This will normally always match the 172.17.0.1 IP of the docker0 interface on the host machine.这通常将始终与主机上docker0接口的172.17.0.1 IP 匹配。 Hence, if you spin-up a container using a Compose file (so, not by using docker run ), chances are infinitely high that this container will rely on the network created during the build of the Compose services.因此,如果您使用 Compose 文件启动容器(因此,不是使用docker run ),该容器将依赖于在构建 Compose 服务期间创建的网络的可能性非常高。 And this network will use a random Gateway address of the form 172.xxx.0.1 which will for sure be different than the 172.17.0.1 default docker Gateway, this can for example be 172.22.0.1 .并且该网络将使用172.xxx.0.1形式的随机网关地址,这肯定不同于172.17.0.1默认的 docker 网关,例如可以是172.22.0.1

This can cause you some troubles if for example you only explicitly authorized connections from 172.17.0.1 to a port of a local service on the host machine.如果您仅明确授权从172.17.0.1到主机上本地服务的端口的连接,这可能会给您带来一些麻烦。 Indeed, it will not be possible to ping the port of that service from inside the container, precisely because of this differently assigned Gateway address ( 172.22.0.1 ).实际上,无法从容器内部 ping 该服务的端口,正是因为这个不同分配的网关地址( 172.22.0.1 )。

Therefore, and because you cannot know in advance which Gateway address the Compose network will have, I highly recommend that you wisely build a custom network definition in the Compose file, eg:因此,由于您无法提前知道 Compose 网络将拥有哪个网关地址,我强烈建议您明智地在 Compose 文件中构建自定义network定义,例如:

version: '3.9'

networks:
  network1:
    name: my-network
    attachable: true
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/16
          ip_range: 172.18.5.0/24
          gateway: 172.18.0.1

services:
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: ****
    ports:
      - "5433:5432"
    networks:
      - network1

If needed, I also recommend using some IP range calculator tool, such ashttp://jodies.de/ipcalc?host=172.18.5.0&mask1=24&mask2= to help yourself in that task, especially when defining ranges using the CIDR notation.如果需要,我还建议使用一些 IP 范围计算器工具,例如http://jodies.de/ipcalc?host=172.18.5.0&mask1=24&mask2=来帮助自己完成该任务,尤其是在使用CIDR表示法定义范围时。

Finally, spin up your container.最后,启动你的容器。 And verify that the newly specified Gateway address 172.18.0.1 has been correctly used:并验证新指定的网关地址172.18.0.1是否已正确使用:

$ docker inspect tmp_postgres_1  -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'
172.18.0.1

Attach to it, install netcat and verify:附加到它,安装netcat并验证:

root@9fe8de220d44:/# nc -vz 172.18.0.1 80
Connection to 172.18.0.1 80 port [tcp/http] succeeded!

(you may also need to adapt your firewall rules accordingly and/or the allowed IPs for your local service, eg a database) (您可能还需要相应地调整防火墙规则和/或本地服务允许的 IP,例如数据库)

Another solution另一种解决方案

is to connect to the existing default bridge network using docker network .是使用docker network连接到现有的默认bridge网络。 In order to do so, after having spin up the container, run this command:为此,在启动容器后,运行以下命令:

$ docker network connect bridge tmp_postgres_1

Now, an inspect should give you two IPs;现在,检查应该给你两个 IP; the one you set up (if any) or the one auto-magically set up by docker during the container creation, and the bridge IP:您设置的那个(如果有的话)或 docker 在容器创建期间自动设置的那个,以及bridge IP:

$ docker inspect tmp_postgres_1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}' 
172.17.0.1 172.18.0.1

Or或者

you can skip the manual network creation and directy tell, in your Compose service definition, to join the bridge network using the networks_mode: flag as follow:您可以跳过手动网络创建,并在 Compose 服务定义中直接告诉使用networks_mode:标志加入bridge网络,如下所示:

version: '3.9'

services:
  postgres:
    image: postgres:14.1-bullseye
    environment:
      POSTGRES_PASSWORD: ****
    ports:
      - "5433:5432"
    # removed networks: and add this:
    networks_mode: bridge
    extra_hosts:
      - "host.docker.internal:host-gateway"

Now, whether you used the docker network connect... method or the network_mode: flag in your Compose file, you normally succesfully joined the default bridge network with the Gateway 172.17.0.1 , this will allow you to use that Gateway IP to connect to your host, either by typing its numerical value, or if set, the variable host.docker.internal :现在,无论您是使用docker network connect...方法还是您的 Compose 文件中的network_mode:标志,您通常都会成功地使用网关172.17.0.1加入默认bridge网络,这将允许您使用该网关 IP 连接到您的主机,可以通过输入其数值,或者如果设置了变量host.docker.internal

root@9fe8de220d44:/# nc -vz 172.18.0.1 80
Connection to 172.18.0.1 80 port [tcp/http] succeeded!
root@9fe8de220d44:/# nc -vz 172.17.0.1 80
Connection to 172.18.0.1 80 port [tcp/http] succeeded!
root@9fe8de220d44:/# nc -vz host.docker.internal 80
Connection to host.docker.internal (172.17.0.1) 80 port [tcp/http] succeeded!

⚠️ But by joining the bridge network, you also makes it possible for your container to communicate with all other containers on that network (if they have published ports), and vice-versa. ⚠️ 但是通过加入bridge网络,您还可以让您的容器与该网络上的所有其他容器进行通信(如果它们已发布端口),反之亦然。 So if you need to clearly keep it apart from these other containers, you preferably don't want to do that and stick with its own custom network!因此,如果您需要清楚地将其与这些其他容器分开,您最好不要这样做并坚持使用它自己的自定义网络!

What if something goes wrong?如果事情不顺利怎么办?

In case you messed up your docker network after some trials, you may face such error message:如果您在经过一些试验后弄乱了您的 docker 网络,您可能会遇到这样的错误消息:

Creating tmp_postgres_1 ... error

ERROR: for tmp_postgres_1  Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist

ERROR: for postgress  Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist
ERROR: Encountered errors while bringing up the project.

even so the 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 bridge network does actually exist, you have to clean all that either by restarting your computer or in the luckiest case, the docker service with:即便如此895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486网桥网络确实存在,您必须通过重新启动计算机或在最幸运的情况下使用 docker 服务来清除所有这些:

$ sudo service docker restart

(a docker networkd prune -f may not be sufficient). docker networkd prune -f可能不够用)。


More in the documentation:文档中的更多内容:
https://docs.docker.com/compose/networking/ https://docs.docker.com/compose/networking/
https://docs.docker.com/compose/compose-file/compose-file-v3/.networks https://docs.docker.com/compose/compose-file/compose-file-v3/.networks
https://github.com/compose-spec/compose-spec/blob/master/spec.md.networks-top-level-element https://github.com/compose-spec/compose-spec/blob/master/spec.md.networks-top-level-element


Tested on a host machine having the following specs:在具有以下规格的主机上测试:
Ubuntu: 18.04.6 LTS Ubuntu:18.04.6 LTS
Kernel: 5.4.0-94-generic Kernel:5.4.0-94-通用
Docker: 20.10.12, build e91ed57 Docker:20.10.12,构建 e91ed57
Docker Compose: 1.27.4, build 40524192 Docker 组成:1.27.4,构建 40524192

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS ElasticBeanstalk 上的 Docker:“host.docker.internal:host-gateway”:连接被拒绝。 iptables 的问题? - Docker on AWS ElasticBeanstalk: "host.docker.internal: host-gateway": Connection refused. Iptables issue? Linux 上的 docker-compose `host-gateway` 无法连接到 RPC (v20.10.1) - docker-compose `host-gateway` on Linux cannot connect to RPC (v20.10.1) --add-host在播放应用程序泊坞窗容器中失败 - --add-host failed within play application docker container 写入主机操作系统的目录 - 通过 docker-compose 文件传递指令 - Writing to the directory of Host OS - Passing the instruction with docker-compose file Linux网络-Docker容器通过网关到远程主机而不使用路由添加? - Linux Networking - Docker Container to Remote Host via Gateway without using route add? 如何使用 docker-compose 使用主机网络配置 - how to use host network config using docker-compose 限制Docker组合中可用的主机资源而无群 - Limit useable host resources in Docker compose without swarm 从 docker 容器创建/触摸主机上的文件 - Create/Touch a file on host from docker container Docker-compose 单个主机上的多个实例 - Docker-compose multiple instances on a single host machine 无法将文件从Docker容器复制到主机 - Not able to copy file from docker container to host
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM