【问题标题】:Problems with underscore in the domain name域名下划线问题
【发布时间】:2018-10-16 21:24:35
【问题描述】:

让我先描述一下我最初的问题和解决方案:

我有几个 docker-compose 文件,它们描述了我的应用程序的不同部分。这些部分是独立开发和部署的,因此不能将它们集成到单个 compose 文件中。但是这些组件需要相互通信,而我目前使用的解决方案是拥有一个所有服务都连接到的外部网络(网桥)。到目前为止一切顺利,只要我连接到自定义桥接网络,我确实可以连接到使用任何 docker compose 文件启动的服务:

$ docker run --network=mynet --rm --name ping_test -it xenial-networking bash

root@0319469f7951:/# ping -c 1 proj_web_1
PING proj_web_1 (172.30.0.3) 56(84) bytes of data.
64 bytes from 172.30.0.3: icmp_seq=1 ttl=64 time=0.071 ms

--- proj_web_1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.071/0.071/0.071/0.000 ms

为什么要使用proj_web_1?因为那是 docker compose 正在创建的 DNS 条目。

这很好用,没人关心下划线不是that great in domain names

没有人...除了django 似乎:

ERROR Invalid HTTP_HOST header: 'proj_web_1:8000'. The domain name provided is not valid according to RFC 1034/1035.
172.30.0.5 - admin [07/May/2018:05:41:53 +0000] "OPTIONS /api/v1/expansions/ HTTP/1.1" 400 58663 "-" "python-requests/2.18.4"

似乎 docker-compose does not support 使用连字符而不是下划线。

通过在我的 django 服务中启用 DEBUG 可能是 I can workaround this

有没有更简洁的方法来启用它,而不在 django 调试模式下运行? 有没有办法告诉 docker compose 停止使用下划线?

【问题讨论】:

  • 我无法重现这个。 requests.post('http://proj_web1:8000/api/v1/expansions/') 不会抱怨主机名,但会导致我的机器上出现预期的超时。请提供 MCVE!
  • 请注意,docker compose 还允许您使用服务名称(在您的情况下只是 web)在同一堆栈中的服务之间进行通信(这也是建议,因为它没有使它们依赖于用于部署堆栈的项目名称)
  • @KlausD。问题发生在接收方。你需要有一个基于 django-rest 的服务才能看到这个问题。
  • @thaJeztah 在使用不同的 docker compose 时不可能:您无法通过仅使用服务名称从另一个 docker compose 启动的容器访问一个 docker compose 声明的服务。

标签: python django docker dns docker-compose


【解决方案1】:

交叉编写网络连接

在运行 compose 项目时,可以通过服务的全名(包括项目名称前缀,例如 myproject_web_1)和服务名称(在 compose 文件中指定)访问服务,例如web。简称为network-scoped alias,表示任何连接到同一个网络的容器都可以通过这个名字访问容器。

默认情况下,docker-compose 为每个 compose 项目(projectname_default)创建一个网络,以便 compose 项目中的所有服务都可以通信。因为该网络是为每个项目单独创建的,所以两个 compose 项目不共享同一个网络,并且它们的服务与其他 compose 项目隔离。

但是,可以使 compose 项目(或 compose 项目中的单个服务)共享同一个网络。

示例 1 - 为整个项目使用共享网络

以下撰写文件为默认网络指定了一个自定义名称;两个 compose-files 都使用 sharednet 网络作为默认网络,这意味着两个 compose 项目的服务将连接到同一个网络:

编写文件 1 (compose1.yml):

version: '3.5'
services:
  compose1service:
    image: busybox
    tty: true

networks:
  default:
    name: sharednet

编写文件 2 (compose2.yml):

version: '3.5'
services:
  compose2service:
    image: busybox
    tty: true

networks:
  default:
    name: sharednet

为了说明这一点:

启动两个撰写文件:

docker-compose -f compose1.yml --project-name=compose1 up -d
docker-compose -f compose2.yml --project-name=compose2 up -d

使用短名称 (compose2service) 从 compose1service 容器中的服务内部 ping compose2service 有效;

docker exec compose1_compose1service_1 ping -c1 compose2service
PING compose2service (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.134 ms

--- compose2service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.134/0.134/0.134 ms

反之亦然:

docker exec compose2_compose2service_1 ping -c1 compose1service
PING compose1service (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.151 ms

--- compose1service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.151/0.151/0.151 ms

全名也是如此(包括项目前缀);

docker exec compose2_compose2service_1 ping -c1 compose1_compose1service_1
PING compose1_compose1service_1 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.151 ms

--- compose1_compose1service_1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.151/0.151/0.151 ms

示例 2 - 为项目中的某些服务使用共享网络

在此示例中,两个 compose 项目都有自己的(“默认”)网络,但此外,还添加了一个共享网络以允许某些服务连接到另一个 compose 项目中的服务。

编写文件 1 (compose3.yml):

version: '3.5'
services:
  compose3service:
    image: busybox
    tty: true
    networks:
      - default
      - sharednet

  compose3otherservice:
    image: busybox
    tty: true

networks:
  sharednet:
    name: mysharednetwork

注意:如果您指定服务应连接到哪些网络,则覆盖默认值,这意味着该服务不再自动连接到default 网络。在网络列表中包含 default 网络,以允许该服务与 compose 项目中的其他服务进行通信。

编写文件 2 (compose4.yml):

version: '3.5'
services:
  compose4service:
    image: busybox
    tty: true
    networks:
      - default
      - sharednet

  compose4otherservice:
    image: busybox
    tty: true

networks:
  sharednet:
    name: mysharednetwork

启动两个撰写文件:

docker-compose -f compose3.yml --project-name=compose3 up -d
docker-compose -f compose4.yml --project-name=compose4 up -d

再次,在其他 compose 项目中从 compose3service ping 到 compose4service 服务(通过简称或全名);

docker exec compose3_compose3service_1 ping -c1 compose4service
PING compose4service (172.22.0.3): 56 data bytes
64 bytes from 172.22.0.3: seq=0 ttl=64 time=0.110 ms

--- compose4service ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.110/0.110/0.110 ms


docker exec compose3_compose3service_1 ping -c1 compose4_compose4service_1
PING compose4_compose4service_1 (172.22.0.3): 56 data bytes
64 bytes from 172.22.0.3: seq=0 ttl=64 time=0.093 ms

--- compose4_compose4service_1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.093/0.093/0.093 ms

但是,尝试相同的方式连接到 compose4otherservice 会失败,因为该服务未连接到 mysharednetwork 网络:

docker exec compose3_compose3service_1 ping -c1 compose4otherservice
ping: bad address 'compose4otherservice'

docker exec compose3_compose3service_1 ping -c1 compose4_compose4otherservice_1
ping: bad address 'compose4_compose4otherservice_1'

注意

如果两个 compose 项目有一个同名的服务(例如,两者都有一个名为 web 的服务),则应小心。在这种情况下,web 可能会随机解析到任一项目中的web 服务。

【讨论】:

    【解决方案2】:

    我可以通过使用网络别名来解决这个问题,避免使用下划线:

      web:
        restart: always
        environment:
          - DJANGO_SECRET_KEY=local
          - DJANGO_CONFIGURATION=Develop
        build:
          context: ./
          args:
            - REGISTRY
        image: web
        command: ./run-gunicorn.sh
        volumes:
          - ./:/code
        depends_on:
          - postgres
        networks:
          spp:
            aliases:
              - projweb
    

    现在我可以到达它了:

    root@a9c0fde612a1:/# ping -c 1 projweb
    PING projweb (172.30.0.4) 56(84) bytes of data.
    64 bytes from svc_web_1.spp (172.30.0.4): icmp_seq=1 ttl=64 time=0.082 ms
    
    --- projweb ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.082/0.082/0.082/0.000 ms
    

    【讨论】:

      猜你喜欢
      • 2019-07-03
      • 2012-04-22
      • 2011-07-10
      • 2011-10-23
      • 1970-01-01
      • 2023-03-10
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多