Docker 容器无法响应来自主机的 HTTP 请求

Docker 容器无法响应来自主机的 HTTP 请求

我想使用 Docker(容器:Ubuntu 22.04)在服务器(Ubuntu 18.04)上部署 API。我之前在另一台服务器上使用相同的配置部署了 API,没有任何问题。

容器虽然构建成功,日志正常,但是好像没有收到HTTP请求(容器名称:demowebsiteapi/ IP地址:172.17.0.2)。

curl 172.17.0.2:8001/test # => timeout response
curl 127.0.0.1:8001/test # => HTML output for 404 errors
docker exec -it demowebsiteapi /bin/bash
/home/demowebsite# wget -qO- localhost:8001/test
> {"response":"ok"}

机器本地主机上的所有端口(我尝试了很多)都输出相同的 404 错误 HTML。我找不到设置此响应的服务器配置文件;/etc/apache2/仅包含一个文件javascript-common.conf并且sudo find / -type d -name '.htaccess'不输出任何内容。

什么原因导致容器无法接收 HTTP 请求?是否有任何交互或配置影响容器的可访问性?关于如何进一步排除故障或调试此问题,您有什么建议吗?

以下是有关我的设置的更多信息:


Docker 配置

以下是 Dockerfile 的示例:

FROM ubuntu:22.04
ENV USER demowebsite

...

COPY /docker-confs/nginx.conf /etc/nginx/conf.d/demowebsite.conf

EXPOSE 8001

CMD export LC_ALL=C.UTF-8 && export LANG=C.UTF-8 && \
    source venv/bin/activate && \
    supervisord -c api/docker-confs/supervisord.conf

以下是构建容器的脚本示例:

docker build --rm -t demowebsiteapi . -f Dockerfile --build-arg USERID="$DEMO_UID";

docker rm demowebsiteapi

docker run -d --name demowebsiteapi \
   -v $DATA_FOLDER:/data/ -p 127.0.0.1:8001:8001 \
   --restart unless-stopped --ipc=host demowebsiteapi

网络设置示例(docker inspect demowebsiteapi):

"NetworkSettings": {
    ...
    "Ports": {
        "8001/tcp": [
            {
                "HostIp": "127.0.0.1",
                "HostPort": "8001"
            }
        ]
    },
    "Networks": {
        "bridge": {
            ...
            "Gateway": "172.17.0.1",
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "02:42:ac:11:00:02",
            "DriverOpts": null
        }
    }
}

奇怪的是,Docker 的重复进程似乎同时运行

$ ps aux | grep demowebsite
userme  10534  0.0  0.0  28140 21484 ?        S    13:53   0:00 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/gunicorn --bind unix:/tmp/website.sock app.main:app --worker-connections 1001 --workers 4
userme  10563  0.5  0.2 3890376 381392 ?      Sl   13:53   0:03 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/gunicorn --bind unix:/tmp/website.sock app.main:app --worker-connections 1001 --workers 4
userme  10567  0.5  0.2 3890220 381952 ?      Sl   13:53   0:03 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/gunicorn --bind unix:/tmp/website.sock app.main:app --worker-connections 1001 --workers 4
userme  10538  0.0  0.0 104748 24676 ?        Sl   13:53   0:00 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/dramatiq app.main -p 1 -t 1
userme  10566  0.6  0.2 4186140 379588 ?      Sl   13:53   0:04 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/dramatiq app.main -p 1 -t 1
userme  10800  0.0  0.0  31188 18580 ?        S    13:54   0:00 /home/demowebsite/venv/bin/python3 /home/demowebsite/venv/bin/dramatiq app.main -p 1 -t 1

网络设置

$ sudo ufw status
Status: inactive

$ sudo ufw app list
Available applications:
  CUPS
  OpenSSH

$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN   
...

$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.042 ms

非常感谢您的帮助,我已经在这个问题上苦苦挣扎了一个星期,关于这个问题的任何建议或见解都将非常有价值!

编辑:更多信息

输出docker ps

CONTAINER ID   IMAGE            COMMAND                  CREATED        STATUS          PORTS                    NAMES
430796e48525   demowebsiteapi   "/bin/bash -c 'expor…"   12 hours ago   Up 27 minutes   0.0.0.0:8001->8001/tcp   demowebsiteapi

我注意到iptables配置很奇怪,我尝试重置它,但重启后它又恢复到相同的设置

sudo iptables -L -v
Chain INPUT (policy ACCEPT 4173 packets, 508K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-USER  all  --  any    any     anywhere             anywhere            
    0     0 DOCKER-ISOLATION-STAGE-1  all  --  any    any     anywhere             anywhere            
    0     0 ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  any    docker0  anywhere             anywhere            
    0     0 ACCEPT     all  --  docker0 !docker0  anywhere             anywhere            
    0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT 753 packets, 111K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  !docker0 docker0  anywhere             172.17.0.2           tcp dpt:8001

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  anywhere             anywhere            
    0     0 RETURN     all  --  any    any     anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  any    docker0  anywhere             anywhere            
    0     0 RETURN     all  --  any    any     anywhere             anywhere            

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  any    any     anywhere             anywhere 

答案1

当您运行时,错误出现在构建容器的脚本中:

docker run -d --name demowebsiteapi \
   -v $DATA_FOLDER:/data/ -p 127.0.0.1:8001:8001 \
   --restart unless-stopped --ipc=host demowebsiteapi

netstat与您的输出相匹配:

$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN 

当您在端口前加上localhost地址前缀 ( -p 127.0.0.1:8001:8001) 时,发布的端口只能从127.0.0.1( localhost) 访问,这netstat也会显示。

相反,为任何 IP 地址配置端口,如下所示:

docker run -d --name demowebsiteapi \
   -v $DATA_FOLDER:/data/ -p 8001:8001 \
   --restart unless-stopped --ipc=host demowebsiteapi

在这种情况下,netstat还应适当显示:

$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN 

查看Docker 网络文档以供参考。

相关内容