【问题标题】:Resolve container name in extra_hosts option in docker-compose在 docker-compose 的 extra_hosts 选项中解析容器名称
【发布时间】:2018-05-14 14:53:27
【问题描述】:

我需要从另一个容器中卷曲我的 API。 容器 1 被称为nginx 容器 2 被称为fpm

我需要能够 bash 进入我的 fpm 容器并卷曲 nginx 容器。

配置:

#docker-compose.yaml
services:
 
  nginx:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    volumes:
      - ./docker/nginx/conf/dev/api.conf:/etc/nginx/conf.d/default.conf
    ports:
      - 8080:80
    links:
      - fpm
    
    
  fpm:
    build:
      context: .
      dockerfile: ./docker/fpm/Dockerfile
    volumes:
      - .:/var/www/html
      - ./docker/fpm/conf/dev/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
      - ./docker/fpm/conf/dev/api.ini:/usr/local/etc/php/conf.d/api.ini
    env_file:
      - ./docker/mysql/mysql.env
      - ./docker/fpm/conf/dev/fpm.env
    links:
      - mysql
    shm_size: 256M
    extra_hosts:
      - myapi.docker:nginx

我最初的想法是在extra_hosts 选项中添加它,例如:

extra_hosts:
  - myapi.docker:nginx

但是 docker-compose up 失败了:

错误:对于 apiwip_fpm_1 无法为服务 fpm 创建容器:添加主机中的 IP 地址无效:“nginx”

我见过一些人使用 docker 的网络配置的例子,但似乎只是解析一个地址。

如何解析/评估容器的 IP 地址,而不是直接传递它?

【问题讨论】:

  • 你做过这个工作吗?
  • 不,我最终只是传递了 IP 地址,或者只是设置和 extra_host 以匹配我的虚拟服务器(或本地主机)
  • 请注意 - 错误消息来自 extra_hosts 参数使用不正确这一事实 - 值的格式应为 <host>:<ip_address> - 请参阅 docs.docker.com/compose/compose-file/#extra_hosts 。因此,nginx 被视为 IP 地址。
  • @piit79 评论中的链接已更改,现在为 docs.docker.com/compose/compose-file/compose-file-v3/…(适用于 v3)
  • @Gorgsenegger 新年后第一份工作回来玩 docker 网络?我不羡慕你。大声笑感谢您的链接更新。

标签: docker dns docker-compose


【解决方案1】:

在默认网络中添加网络别名

version: "3.7"
services:

  nginx:
    # ...
    networks:
      default:
        aliases:
          - example.local

  browser-sync:
    # ...
    depends_on:
      - nginx
    command: "browser-sync start --proxy http://example.local"

【讨论】:

    【解决方案2】:
    services:
      nginx:
        build:
        context: .
        dockerfile: ./docker/nginx/Dockerfile
        volumes:
          - ./docker/nginx/conf/dev/api.conf:/etc/nginx/conf.d/default.conf
        ports:
          - 8080:80
        networks:
          my_network:
            aliases:
              - myapi.docker
              - docker_my_network
      fpm:
        build:
        context: .
        dockerfile: ./docker/fpm/Dockerfile
        volumes:
          - .:/var/www/html
          - ./docker/fpm/conf/dev/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
          - ./docker/fpm/conf/dev/api.ini:/usr/local/etc/php/conf.d/api.ini
        env_file:
          - ./docker/mysql/mysql.env
          - ./docker/fpm/conf/dev/fpm.env
        links:
          - mysql
        shm_size: 256M
        networks:
          - my_network
    
      networks:
        my_network:
          driver: bridge
    
    • 添加自定义网络并将容器添加到该网络
    • 默认情况下,如果你从 fpm 卷曲 nginx 容器,你会卷曲 localhost,所以我们需要在 nginx 配置中添加与你的服务器名相同的别名
    • 使用此解决方案,您可以从 fpm 容器中 curl myapi.docker

    @edward 让我知道此解决方案是否适合您

    编辑: Jack_Hu 是对的,我删除了 extra_hosts。网络别名就够了。

    【讨论】:

    • 不错。这看起来可以工作。下次我在这个项目上工作时,我会告诉你朋友,谢谢。
    • 似乎不起作用。还是得到原来的错误:ERROR: for apiwip_fpm_1 Cannot create container for service fpm: invalid IP address in add-host: "nginx"
    • 已解决...解决方案是从上面完全删除 extra_hosts: - myapi.docker:nginx 位。网络别名正在有效地替换它,而不是在 /etc/hosts 文件中解析 DNS,而是在虚拟网络适配器本身上解析它......基本上,因为在给定网络上为服务赋予了别名,也在该网络上的所有其他服务都能够将给定的别名解析为它所连接的服务。
    【解决方案3】:

    我通过使用links 而不是extra_hosts 解决了此类问题。

    在这种情况下,只需设置link alias 即可。

    服务 fpm 设置
    links
      - nginx:myapi.docker
    

    参见docker-compose links documentation,别名可以是您代码中出现的域。

    【讨论】:

    • link 已经被弃用了一段时间。应该使用网络别名。有关详细信息,请参阅 Denis Kovacevic 的回答,以及我的 cmets。
    【解决方案4】:

    来自 docker 文档,

    https://docs.docker.com/compose/networking/

    您应该能够使用您的服务名称(在本例中为 nginx)作为 docker 网络中的主机名。因此,您可以 bash 进入我的 FPM 容器并调用 curl nginx,docker 将为您解决它。希望这会有所帮助。

    【讨论】:

    • 我真的需要/etc/hosts 的别名,但我想看看谢谢,伙计
    • 意味着您将使用诸如内部 SSL 终止等功能的附带细节使容器混乱,并使任何非 TLS 设置复杂化
    【解决方案5】:

    快速解决方法是将其指向 docker 生成的动态 IP。不过这可能会改变……是的。

    查找您的网络: docker network ls

    NETWORK ID          NAME                 DRIVER              SCOPE
    72fef1ce7a50        apiwip_default       bridge              local <-- here
    cdf9d5b885f6        bridge               bridge              local
    2f4f1e7038fa        host                 host                local
    a96919eea0f7        mgadmin_default      bridge              local
    30386c421b70        none                 null                local
    5457b953fadc        website2_default     bridge              local
    1450ebeb9856        anotherapi_default   bridge              local
    

    复制网络 ID

    docker network inspect 72fef1ce7a50

    "Containers": {
                "345026453e1390528b2bb7eac4c66160750081d78a77ac152a912f3de5fd912c": {
                    "Name": "apiwip_nginx_1",
                    "EndpointID": "6504a3e4714a6ba599ec882b21f956bfd1b1b7d19b8e04772abaa89c02b1a686",
                    "MacAddress": "02:42:ac:14:00:05",
                    "IPv4Address": "172.20.0.5/16", <-- CIDR block
                    "IPv6Address": ""
                },
                "ea89d3089193825209d0e23c8105312e3df7ad1bea6b915ec9f9325dfd11736c": {
                    "Name": "apiwip_fpm_1",
                    "EndpointID": "dc4ecc7f0706c0586cc39dbf8a05abc9cc70784f2d44c90de2e8dbdc9148a294",
                    "MacAddress": "02:42:ac:14:00:04",
                    "IPv4Address": "172.20.0.4/16",
                    "IPv6Address": ""
                }
            },
    

    将该 CIDR 块中的 IP 地址添加到 extra_hosts 选项:

    extra_hosts:
      - myapi.docker:172.20.0.5
    

    【讨论】:

    • 这不是解决方案。
    • 不会更喜欢这种“解决方案”,它非常脆弱,正如帖子的介绍性句子中已经描述的那样
    • 大家好,以防万一不清楚这不是解决方案(我也没有将其标记为这样)。如果您想要解决方案,请随时尝试其他答案并发表评论,谢谢。
    • 赞成,因为它为故障排除提供了一些视角并帮助找到未连接到网络的容器,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 2022-06-15
    • 2020-02-01
    • 2020-09-17
    • 1970-01-01
    • 2020-05-18
    相关资源
    最近更新 更多