s.k*_*s.k 49 linux docker docker-compose docker-network
从 Docker 版本20.10(https://github.com/moby/moby/pull/40007)开始,有一个新的特殊字符串host-gateway,可以在--add-host运行标志中使用,以允许从 docker 容器内部直接连接到本地计算机在基于 Linux 的系统上。这非常好。
--add-host=host.docker.internal:host-gateway但是Compose 文件中的等价物是什么?
例如在:
$ docker run \
--rm \
--name postgres \
-p "5433:5432" \
-e POSTGRES_PASSWORD=**** \
--add-host=host.docker.internal:host-gateway \
-d postgres:14.1-bullseye
Run Code Online (Sandbox Code Playgroud)
相同的标志如何--add-host适合这个 Docker Compose 等效模板:
version: '3.9'
services:
postgres:
image: postgres:14.1-bullseye
environment:
POSTGRES_PASSWORD: ****
ports:
- "5433:5432"
Run Code Online (Sandbox Code Playgroud)
肯定不是:network_mode: host在服务级别(参见#Doc)。
s.k*_*s.k 83
实际的 Docker Compose 等效项是通过将相同的字符串附加到参数来实现的extra_hosts(#Doc ) 来实现的,如下所示:
version: \'3.9\'\n\nservices:\n postgres:\n image: postgres:14.1-bullseye\n environment:\n POSTGRES_PASSWORD: ****\n ports:\n - "5433:5432"\n extra_hosts:\n - "host.docker.internal:host-gateway"\nRun Code Online (Sandbox Code Playgroud)\n您可以看到它已成功映射到容器内部的docker0接口IP,例如:172.17.0.1
$ docker-compose up -d\n$ docker-compose exec postgres bash\nRun Code Online (Sandbox Code Playgroud)\n然后,从容器内部:
\nroot@5864db7d7fba:/# apt update && apt -y install netcat\nroot@5864db7d7fba:/# nc -vz host.docker.internal 80\nConnection to host.docker.internal (172.17.0.1) 80 port [tcp/http] succeeded!\nRun Code Online (Sandbox Code Playgroud)\n(假设端口 80 没有docker0被主机上的防火墙关闭或限制为接口的 IP)。
有关更多信息,请访问:
\n https://medium.com/@TimvanBaarsen/how-to-connect-to-the-docker-host-from-inside-a-docker-container-112b4c71bc66
但是...请注意...\n
这通常总是与主机上接口172.17.0.1的 IP匹配。docker0因此,如果您使用 Compose 文件启动容器(因此,而不是使用docker run),则该容器将依赖于 Compose 服务构建期间创建的网络的可能性无限高。这个网络将使用一个随机的网关地址,172.xxx.0.1其形式肯定与172.17.0.1默认的 docker 网关不同,例如可以是172.22.0.1.
例如,如果您仅显式授权连接到172.17.0.1主机上本地服务的端口,这可能会给您带来一些麻烦。\n事实上,无法从容器内部 ping 该服务的端口,正是因为这个不同分配的网关地址 ( 172.22.0.1)。
因此,由于您无法提前知道 Compose 网络将具有哪个网关地址,因此我强烈建议您明智地network在 Compose 文件中构建自定义定义,例如:
version: \'3.9\'\n\nnetworks:\n network1:\n name: my-network\n attachable: true\n ipam:\n driver: default\n config:\n - subnet: 172.18.0.0/16\n ip_range: 172.18.5.0/24\n gateway: 172.18.0.1\n\nservices:\n postgres:\n image: postgres:14.1-bullseye\n environment:\n POSTGRES_PASSWORD: ****\n ports:\n - "5433:5432"\n networks:\n - network1\nRun Code Online (Sandbox Code Playgroud)\n如果需要,我还建议使用一些 IP 范围计算器工具,例如http://jodies.de/ipcalc?host=172.18.5.0&mask1=24&mask2=来帮助您完成该任务,特别是在使用CIDR表示法定义范围时。
\n最后,旋转你的容器。并验证新指定的网关地址172.18.0.1是否已正确使用:
$ docker inspect tmp_postgres_1 -f \'{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}\'\n172.18.0.1\nRun Code Online (Sandbox Code Playgroud)\n附加到它,安装netcat并验证:
root@9fe8de220d44:/# nc -vz 172.18.0.1 80\nConnection to 172.18.0.1 80 port [tcp/http] succeeded!\nRun Code Online (Sandbox Code Playgroud)\n(您可能还需要相应地调整防火墙规则和/或本地服务允许的 IP,例如数据库)
\nbridge是使用连接到现有的默认网络docker network。为此,在启动容器后,运行以下命令:
$ docker network connect bridge tmp_postgres_1\nRun Code Online (Sandbox Code Playgroud)\n现在,检查应该给你两个 IP;您设置的一个(如果有)或在容器创建期间由 docker 自动设置的一个,以及bridge:
$ docker inspect tmp_postgres_1 -f \'{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}\' \n172.17.0.1 172.18.0.1\nRun Code Online (Sandbox Code Playgroud)\n您可以跳过手动网络创建,并在 Compose 服务定义中直接告诉您bridge使用network_mode:以下标志加入网络:
version: \'3.9\'\n\nservices:\n postgres:\n image: postgres:14.1-bullseye\n environment:\n POSTGRES_PASSWORD: ****\n ports:\n - "5433:5432"\n # removed networks: and add this:\n network_mode: bridge\n extra_hosts:\n - "host.docker.internal:host-gateway"\nRun Code Online (Sandbox Code Playgroud)\n现在,无论您使用Compose 文件中的docker network connect...方法还是标志,您通常都会成功地通过 Gatewaynetwork_mode:加入默认网络,这将允许您使用该网关 IP 连接到您的主机,可以通过键入其数值,或者如果设置,变量:bridge172.17.0.1host.docker.internal
root@9fe8de220d44:/# nc -vz 172.18.0.1 80\nConnection to 172.18.0.1 80 port [tcp/http] succeeded!\nroot@9fe8de220d44:/# nc -vz 172.17.0.1 80\nConnection to 172.18.0.1 80 port [tcp/http] succeeded!\nroot@9fe8de220d44:/# nc -vz host.docker.internal 80\nConnection to host.docker.internal (172.17.0.1) 80 port [tcp/http] succeeded!\nRun Code Online (Sandbox Code Playgroud)\n\xe2\x9a\xa0\xef\xb8\x8f 但是通过加入网络bridge,您还可以使容器与该网络上的所有其他容器(如果它们已发布端口)进行通信,反之亦然。因此,如果您需要明确地将其与其他容器分开,您最好不想这样做并坚持使用自己的自定义网络!
如果你在经过一些尝试后弄乱了你的 docker 网络,你可能会遇到这样的错误消息:
\nCreating tmp_postgres_1 ... error\n\nERROR: for tmp_postgres_1 Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist\n\nERROR: for postgress Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist\nERROR: Encountered errors while bringing up the project.\nRun Code Online (Sandbox Code Playgroud)\n即使895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486桥接网络确实存在,您也必须通过重新启动计算机或在最幸运的情况下通过 docker 服务来清理所有这些:
Creating tmp_postgres_1 ... error\n\nERROR: for tmp_postgres_1 Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist\n\nERROR: for postgress Cannot start service postgres: failed to create endpoint tmp_postgres_1 on network bridge: network 895de42e2a0bdaab5423a6356a079fae55aae41ae268ee887ed214bd6fd88486 does not exist\nERROR: Encountered errors while bringing up the project.\nRun Code Online (Sandbox Code Playgroud)\n(adocker networkd prune -f可能还不够)。
文档中的更多内容:
\n https://docs.docker.com/compose/networking/
\n https://docs.docker.com/compose/compose-file/compose-file-v3/#networks
\n https ://github.com/compose-spec/compose-spec/blob/master/spec.md#networks-top-level-element
在具有以下规格的主机上进行了测试:
\nUbuntu:18.04.6 LTS
\n内核:5.4.0-94-generic
\nDocker:20.10.12,内部版本 e91ed57
\nDocker Compose:1.27.4,内部版本 40524192
| 归档时间: |
|
| 查看次数: |
78330 次 |
| 最近记录: |