【问题标题】:How to use host network for docker compose?如何为 docker compose 使用主机网络?
【发布时间】:2019-06-13 14:11:30
【问题描述】:

我想在主机网络中使用 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 来缩放容器。但是来自documentation 的 docker compose 文件不起作用。 docker 容器不查询 REST API。

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

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

【问题讨论】:

  • 你在使用 docker swarm 吗?你是如何部署的? docker-compose up 还是 docker stack deploy?根据这一点,您当前的撰写文件可能有几个错误。
  • 目前我使用的是 swarm。但是当我使用 docker-compose up 时也会返回 services.web.build contains unsupported option: 'network'
  • Swarm 和 compose 部署非常不同,并且您的 yml 文件在两种模式下大多无效,因为您混合了两种模式的选项。请说明您打算使用哪种部署方法,以便获得正确的答案(并添加 docker-swarm 标签并删除 docker-compose 一个,具体取决于您想要的答案)
  • 感谢您的澄清。我想使用 compose 部署并将其添加到问题中

标签: docker docker-compose


【解决方案1】:

docker-compose v3 的等效配置是使用network_mode 键:https://docs.docker.com/compose/compose-file/compose-file-v3/#network_mode

您应该在您的docker-compose.yml 中将network_mode 设置为"host"

如果使用 docker swarm,请参阅codestation's answer

【讨论】:

  • 如何在 swarm 中为版本 3 使用此网络模式?或者我如何添加网络模式,因为我得到了一个不同于 3 的不受支持的撰写文件版本
  • network_mode 用于 v3 和 v2。 v1 称之为 net: docs.docker.com/compose/compose-file/compose-file-v1/#net
  • 我在撰写文件中添加了net,但 net 属性被忽略了
  • 使用更新问题中的撰写文件,您有version: "3",因此您应该使用network_mode
  • 两者都试过了,但network_mode 仍然被忽略
【解决方案2】:

您正在混合在 compose 和 swarm 部署中无效的选项。

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

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

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


(请随意忽略这部分答案,因为您澄清说您没有使用集群部署)。

如果你使用 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 对您的副本进行负载平衡。

【讨论】:

    【解决方案3】:

    我也遇到了同样的问题。我发现当network_mode 设置为host 时,端口映射不起作用,因为容器会寻找主机的端口。因此,删除端口映射对我有用,如下所示。

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

    【讨论】:

      【解决方案4】:

      我认为你应该像这样定义 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
      

      【讨论】:

      • 我收到错误消息name Additional property name is not allowed
      • 尝试使用docker-compose 3.7版本
      • 谢谢。救了我的命。
      【解决方案5】:

      您在哪个平台上? host 模式仅适用于 Linux AFAIK。如果network_mode 不起作用,试试network: host

      version: '3.4'
      serivces:
        some_service:
        build:
          network: host
      

      【讨论】:

      • 在arch linux上我收到错误消息`services.web.build Additional property network is not allowed`
      • 在 Ubuntu 上:services.build: 'network' 的配置选项不受支持
      【解决方案6】:

      network_mode: 集群模式下不允许主机。

      【讨论】:

        【解决方案7】:

        我自己在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 套接字,该套接字可以安装在容器中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-07-08
          • 2021-11-04
          • 2020-07-14
          • 2023-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多