从Docker 20.10 (https://github.com/moby/moby/pull/40007)开始,有一个新的特殊字符串host-gateway,它可以在--add-host run标志中使用,以便在基于Linux的系统上从停靠容器内部直接连接到本地机器。这很不错。
但是,在撰写文件中,--add-host=host.docker.internal:host-gateway的等效性是什么呢?
例如:
$ docker run \
--rm \
--name postgres \
-p "5433:5432" \
-e POSTGRES_PASSWORD=**** \
--add-host=host.docker.internal:host-gateway \
-d postgres:14.1-bullseye如何将相同的--add-host标志放入此Docker中,构成等效模板:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"当然不是:服务级别的network_mode: host (参见#Doc)。
发布于 2022-01-15 22:18:22
通过将相同的字符串附加到extra_hosts参数(#Doc)中,可以实现实际的Docker等效:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
extra_hosts:
- "host.docker.internal:host-gateway"您可以看到它已经成功地从容器中映射到docker0接口的IP (此处为172.17.0.1 ),例如:
$ docker-compose up -d
$ docker-compose exec postgres bash然后,从容器内部:
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!(假设端口80不被主机上的防火墙关闭或限制在docker0接口的IP上)。
关于这一点的更多信息可在这里找到:
但是..。小心..。
警告⚠️
这通常总是与主机上的172.17.0.1接口的docker0 IP相匹配。因此,如果使用复合文件(所以,而不是使用docker run)拆分容器,则该容器依赖于在构建组合服务期间创建的网络的可能性是无限大的。这个网络将使用表单172.xxx.0.1的随机网关地址,这肯定与172.17.0.1默认的停靠网关不同,例如,可以是172.22.0.1。
如果您只显式地授权从172.17.0.1到主机上的本地服务端口的连接,这可能会给您带来一些麻烦。实际上,不可能从容器内部平移该服务的端口,正是因为这个不同的分配网关地址(172.22.0.1)。
因此,由于您无法预先知道撰写网络将具有哪个网关地址,因此我强烈建议您明智地在撰写文件中构建自定义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如果需要的话,我还建议使用一些IP范围计算器工具,例如http://jodies.de/ipcalc?host=172.18.5.0&mask1=24&mask2=来帮助自己完成该任务,特别是在使用CIDR符号定义范围时。
最后,旋转你的容器。并验证新指定的网关地址172.18.0.1是否正确使用:
$ docker inspect tmp_postgres_1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'
172.18.0.1附加到它上,安装netcat并验证:
root@9fe8de220d44:/# nc -vz 172.18.0.1 80
Connection to 172.18.0.1 80 port [tcp/http] succeeded!(您还可能需要相应地调整防火墙规则和/或允许的IP用于本地服务,例如数据库)
另一种解决办法
是使用bridge连接到现有的默认docker network网络。为了做到这一点,在旋转容器之后,运行以下命令:
$ docker network connect bridge tmp_postgres_1现在,检查应该为您提供两个IP;一个是您在容器创建过程中设置的一个(如果有的话),另一个是由码头自动设置的bridge IP:
$ docker inspect tmp_postgres_1 -f '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'
172.17.0.1 172.18.0.1或
在撰写服务定义中,您可以跳过手动网络创建和直接告诉,使用bridge标志加入network_mode:网络,如下所示:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
# removed networks: and add this:
network_mode: bridge
extra_hosts:
- "host.docker.internal:host-gateway"现在,无论您在撰写文件中使用docker network connect...方法还是network_mode:标志,您通常都会成功地将默认的bridge网络与网关172.17.0.1连接起来,这将允许您使用网关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!但是,通过加入bridge网络,您的容器还可以与该网络上的所有其他容器通信(如果它们已经发布了端口),反之亦然。因此,如果您需要清楚地将它与这些其他容器分开,您最好不要这样做,只使用它自己的自定义网络!
万一出了什么事怎么办?
如果您在一些试验后破坏了码头网络,您可能会面临这样的错误信息:
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.即使如此,895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486桥网络确实存在,您必须通过重新启动计算机或在最幸运的情况下,通过以下方式清除所有这些:
$ sudo service docker restart( docker networkd prune -f可能不够)。
更多在文件中:
https://docs.docker.com/compose/networking/
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
在具有以下规范的主机上测试:
Ubuntu: 18.04.6 LTS
内核:5.4.0-94-泛型
Docker: 20.10.12,构建e91ed57
码头组成: 1.27.4,构建40524192
https://stackoverflow.com/questions/70725881
复制相似问题