![Docker 容器无法响应来自主机的 HTTP 请求](https://linux22.com/image/1200829/Docker%20%E5%AE%B9%E5%99%A8%E6%97%A0%E6%B3%95%E5%93%8D%E5%BA%94%E6%9D%A5%E8%87%AA%E4%B8%BB%E6%9C%BA%E7%9A%84%20HTTP%20%E8%AF%B7%E6%B1%82.png)
我想使用 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 网络文档以供参考。