容器A无法通过外网访问容器B

时间:2021-02-03 18:06:51

标签: docker nginx docker-compose docker-networking

像这样的问题很多,但他们的解决方案大多是“使用服务名称而不是127.0.0.1”或类似的。

我有两个 docker-compose.yml 文件(我需要将它们分开):packageindexserver/docker-compose.ymlapi/docker-compose.ymlpackageindexserver/docker-compose.yml 包含一个 pypiserver 服务和一个 pypi-nginx-server 服务。因为 pypiserver 按预期工作,所以这里是 pypi-nginx-server

services:
  pypiserver: ...

  pypi-nginx-server:
    container_name: pypi-nginx-server
    image: pypi-nginx-server
    build:
      context: ./
      dockerfile: dockerfiles/NginxDockerfile
    restart: on-failure
    ports:
      - "0.0.0.0:7000:80"
    volumes:
      - ./packages:/data/packages
      - ./certificates:/etc/nginx/certificates:ro  # Not used; required by default configuration and will not start without it
    depends_on:
      - pypiserver
    networks:
      pypi-net:  # Presumably not relevant to question
      staticip:
        ipv4_address: 172.123.0.100  # Hoping to reach pypi-nginx-server on this IP, or by name

networks:
  pypi-net:  # Presumably not relevant to question
  staticip:
    driver: bridge
    name: staticip
    ipam:
      config:
      - subnet: 172.123.0.0/24

这是api (api/docker-compose.yml):

services:
  api-postgres-db:
    networks:
      - network-a  # Presumably not relevant to question
    ...

  api:
    ...
    networks:
      network-a:  # Presumably not relevant to question
      staticip:
        ipv4_address: 172.123.0.101  # Hoping to give this a static IP (presumably not relevant to question)

  api-nginx-server:
    networks:
      - network-a  # Presumably not relevant to question
      - network-b  # Presumably not relevant to question

  certbot: ...

networks:
  network-a: ...
  network-b: ...
  staticip:
    external: true

api 启动时,会运行一个脚本 (install-my-package.sh):

#!/bin/bash

if [[ -z "${PYPI_OVERRIDE_HOST}" ]]; then
  PYPI_HOST=[some default host]
else
  PYPI_HOST="${PYPI_OVERRIDE_HOST}"
fi

if [[ -z "${PYPI_OVERRIDE_INDEX_URL}" ]]; then
  INDEX_URL=[some default host]
else
  INDEX_URL="${PYPI_OVERRIDE_INDEX_URL}"
fi

echo "Installing [my packge] from $INDEX_URL with trusted host $PYPI_HOST"
pip3 install --index-url $INDEX_URL --trusted-host $PYPI_HOST my-package -U --no-cache-dir

如果将 PYPI_OVERRIDE_HOSTPYPI_OVERRIDE_INDEX_URL 设置为 [public IP of host]http://[public IP of host]:7000/simple/,则有效:api 可以到达 pypi-nginx-server 并安装 {{1 }}。但是,由于某些原因,这对我不起作用。

我只希望 [my package] 能够从 api(通过 pypiserver)查看和安装软件包。因此,在 pypi-nginx-server 的配置文件中,我可以使用 pypi-nginx-serverlisten [api IP address]:80;

我尝试将 allow [api IP address]; deny all; 设置为 api IP address,但是在将主机的公共 IP 地址用作 172.123.0.101 时这不起作用。如果我使用 PYPI_OVERRIDE_HOST,我会得到:

listen 172.123.0.101:80(连接被拒绝)

如果我使用 WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPConnection object at 0x7fa1c2854c90>: Failed to establish a new connection: [Errno 111] Connection refused')': /simple/my-package/,我会得到:

allow 172.123.0.101; deny all;

当我删除配置文件中的任何限制(不侦听特定 IP 或允许 IP/拒绝全部)并使用 ERROR: Could not find a version that satisfies the requirement my-package ERROR: No matching distribution found for my-package 作为 172.123.0.100 时,我得到:

PYPI_OVERRIDE_HOST(超时)

当我删除配置文件中的任何限制(不侦听特定 IP 或允许 IP/拒绝全部)并使用 WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.HTTPConnection object at 0x7ff8fe0f8ed0>, 'Connection to 172.123.0.100 timed out. (connect timeout=15)')': /simple/my-package/ 作为 pypi-nginx-server 时,我得到:

PYPI_OVERRIDE_HOST(名称或服务未知)

据我所知,WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPConnection object at 0x7f2e48865e50>: Failed to establish a new connection: [Errno -2] Name or service not known')': /simple/my-package/ 应该能够通过使用其名称 (pypi-nginx-server) 或 IP (172.123.0.100) 来访问 api,但事实并非如此,即使他们在同一个网络上。 pypi-nginx-server 只能通过主机的公共 IP 访问,我无法只允许 pypi-nginx-server 容器连接。

最后,如果我使用主机的公共 IP 并使用 api,我仍然得到 listen [public IP of host]:80;。此外,主机的公共IP预计会经常变化。涉及使用主机域名(仍然不可用)的解决方案是可以接受的,但不是最佳的。

使用 docker-compose 3.5 版。

有什么想法吗?

0 个答案:

没有答案