如何在Docker Compose中使用主机网络?

156

我希望使用Docker Compose与主机网络一起使用。

我有一个访问本地REST API的Docker容器。通常我运行

docker run --net=host -p 18080:8080 -t -i containera

您可以访问运行在http://127.0.0.1:8080的主机REST api。由于我想要扩展容器containera,因此我使用了Docker Compose来扩展容器。但是从文档中获取的Docker Compose文件无法正常工作。Docker容器无法查询REST API。

我尝试了以下Compose文件,但属性

version: "3"
services:
  web:
    image: conatinera:latest
    network_mode: "host"
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.5"
          memory: 4G 
      restart_policy:
        condition: on-failure
    ports:
      - "18080:8080"

但是属性network_mode被忽略/不允许。并显示以下信息:
Ignoring unsupported options: network_mode

1
你正在使用Docker Swarm吗?你是如何部署的?是使用docker-compose up还是docker stack deploy?根据这个,你当前的compose文件可能会有几个错误。 - codestation
目前我正在使用Swarm。但是当我运行docker-compose up时,也会返回services.web.build contains unsupported option: 'network' - A.Dumas
1
Swarm和Compose的部署方式有很大的不同,而且你的yml文件在这两种模式下大多数都是无效的,因为你混合了来自两种模式的选项。请说明你想要使用哪种部署方法,这样你才能得到一个适当的答案(根据你的回答添加docker-swarm标签或删除docker-compose标签)。 - codestation
感谢您的澄清。我想使用Compose deployment,并将其添加到问题中。 - A.Dumas
8个回答

140

我如何在Swarm中使用版本3的网络模式?或者说,如果我的compose文件版本不支持3,我该怎么添加网络模式? - A.Dumas
2
network_mode 在 v3 和 v2 中使用。v1 称其为 net: https://docs.docker.com/compose/compose-file/compose-file-v1/#net - ford
我在Compose文件中添加了net,但是该属性被忽略了。 - A.Dumas
1
在您更新的问题中,使用了compose文件version: "3",因此您应该使用network_mode - ford
1
尝试了两种方法,但network_mode仍然被忽略。 - A.Dumas
当您设置 network_modehost 时,应该摆脱 networks。https://dev59.com/xL3pa4cB1Zd3GeqPYCDc - user3379167

64

您正在混合使用不适用于compose和swarm部署的选项。

如果您要使用docker-compose up进行部署,则您的compose文件应该是这样的:

version: "3"
services:
  web:
    image: conatinera:latest
    network_mode: "host"        
    restart: on-failure

在Compose模式下,选项deploy被忽略,而使用主机模式网络时,端口选项也被忽略。我建议不要使用主机模式网络,而是使用另一个容器中的反向代理来平衡您的扩展容器。


(如果您没有使用Swarm部署,则可以忽略本答案的此部分)。

如果您正在使用Swarm部署,则您的Compose文件应该像这样:

version: "3.4"
services:
  web:
    image: conatinera:latest
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.5"
          memory: 4G 
      restart_policy:
        condition: on-failure
    networks:
      - host

networks:
  host:
    name: host
    external: true

再次强调,发表的端口和主机模式网络不兼容。此外,您的扩展可能会失败,因为所有容器都将尝试绑定到同一端口。 我建议不要使用主机模式网络,让Docker负载均衡您的副本。


我收到了这个错误:networks.host 不允许使用附加属性名称 - shgnInc
我遇到了这个错误:守护进程的错误响应:仅支持用户定义网络中的容器的网络范围别名 - sorosh_sabz

22

我曾经面临同样的问题。我发现当network_mode设置为host时,端口映射不起作用,因为容器会查找主机的端口。所以,像下面这样删除端口映射对我有帮助:

services:
  web-abc:
    build: ./abc
    # ports:
    #   - "7000:7000"
    volumes:
      - .:/code
    network_mode: host

13

1
如果主机REST API考虑客户端的请求URL,它将类似于http(s)://host.docker.internal/restservice在您的情况下,因此如果需要获取某些特定的URL,请随意使用任何别名代替host.docker.internal,例如:specific-url.local:host-gateway - Maksym Kosenko
在MacOS上的容器内,您可能需要使用docker.for.mac.host.internal而不是host.docker.internal。 - Eugene

7
你所使用的平台是什么?据我所知,“host”模式只在Linux上有效。如果“network_mode”无法工作,可以尝试使用“network: host”吗?
version: '3.4'
serivces:
  some_service:
  build:
    network: host

在 Arch Linux 上,我收到了错误信息 services.web.build,附加属性 network 不被允许。 - A.Dumas
1
在Ubuntu上:services.build的配置选项'network'不受支持。 - Bob

7
我认为你应该这样定义docker-compose文件: 这只是一个示例,请阅读文档: https://docs.docker.com/compose/compose-file/#network-configuration-reference
version: "3"
services:
  web:
    image: conatinera:latest
    networks:
      mynetwork: {}
    deploy:
      replicas: 1
      resources:
        limits:
          cpus: "0.5"
          memory: 4G 
      restart_policy:
        condition: on-failure
    ports:
      - "18080:8080"
networks:
  mynetwork:
    external: true
    name: host

2
我收到了错误信息 名称 Additional property name 不允许 - A.Dumas
请尝试使用docker-compose的3.7版本。 - Gianmarco Carrieri
3
我遇到了这个错误:守护进程的错误响应:仅支持用户定义网络中的容器的网络范围别名 - sorosh_sabz

2
我个人在使用 networksnetwork_mode 时并没有成功,但如果您想要访问主机上的网络服务,您可以让主机服务监听 docker0 网络接口,容器可以通过相同的 IP 地址(根据您的网络模式)访问该接口。以下是一个概念验证示例:
在主机上:
$ ip -4 a | grep docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

$ echo hello world | nc -l -p 8888 -s 172.17.0.1

在容器中:

$ docker run --rm -it alpine nc -w1 172.17.0.1 8888
hello world

另一种使主机服务可以被docker容器访问的方法是监听Unix套接字,并将其挂载到容器中。

2

在Swarm模式下,不允许使用network_mode:host。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接