• 作者:老汪软件技巧
  • 发表时间:2024-08-17 15:35
  • 浏览量:

解决 Docker 容器远程访问问题:从问题排查到彻底解决

在日常开发和部署过程中,我们时常会遇到 Docker 容器无法被外部访问的问题。最近,我在使用 Apache Tika 服务时,就遇到了这样的挑战。这篇博客将详细记录我从发现问题到解决问题的整个过程,希望能为遇到类似问题的开发者提供帮助。

问题背景

我部署了一个 Apache Tika 服务用于解析 PDF 文件,使用 Docker 容器运行该服务。虽然容器启动后,服务在本地可以正常访问,但从外部网络却无法访问到该服务。

访问报错内容:

无法解析PDF文件: Put ":9998/tika": write tcp 192.168.18.62:52244->116.198.207.159:9998: wsasend: An existing connection was forcibly closed by the remote host.

第一步:初步排查

我首先尝试从主机内部访问该服务,确认服务确实在运行,并且可以响应请求。

curl http://127.0.0.1:9998

请求成功,说明服务在本地是可以正常工作的。

第二步:清理旧的 Docker 容器和资源

在进一步排查问题前,我决定先清理掉一些旧的容器和资源,以避免可能的冲突或资源占用。

停止并删除所有容器

首先,停止所有正在运行的容器:

docker stop $(docker ps -aq)

然后,删除所有容器:

docker rm $(docker ps -aq)

删除未使用的镜像、网络和挂载的卷

为了彻底清理系统中的垃圾资源,我使用了以下命令来删除未使用的镜像、网络以及挂载的卷:

docker system prune -a --volumes

清理远程垃圾__清理容器

这个命令会删除所有未使用的镜像、停止的容器、未使用的网络,以及挂载的卷,确保 Docker 环境干净无遗留。

第三步:重新启动容器并正确配置端口映射

清理完 Docker 环境后,我重新启动了 Apache Tika 容器。这次,我将端口 9998 映射到了主机的所有接口 (0.0.0.0),以便允许外部访问。

docker run -d -p 9998:9998 apache/tika

这个命令确保容器的 9998 端口可以通过主机的任何网络接口进行访问。

后来发现确实还是网络不稳定,我尝试了一下

docker run -d \
  -p 9998:9998 \
  -e JAVA_OPTS="-Djetty.http.idleTimeout=600000" \
  apache/tika

这中途我不小心配了个本地的docker,以下是 Docker 容器的基本信息:

CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS              PORTS                      NAMES
3ff6bbbb4bca   apache/tika   "/bin/sh -c 'exec ja…"   About a minute ago   Up About a minute   127.0.0.1:9998->9998/tcp   nostalgic_stonebraker

如上所示,我将容器的 9998 端口映射到了主机的 127.0.0.1:9998,但这意味着该服务只能通过主机本身访问,而无法从外部网络访问。这导致我需要从头再来,哈哈。

第四步:验证外部访问

重新启动容器后,我从另一台机器尝试访问主机的 9998 端口,以确保服务可以被外部网络访问。

curl http://<主机的IP地址>:9998

这次请求成功,Tika 服务可以从外部访问了。

最终结论

通过这次问题排查和解决,我总结了以下几点:

端口映射要正确配置:在 Docker 中运行服务时,如果希望服务可以被外部访问,确保将端口映射到 0.0.0.0 而不仅仅是 127.0.0.1。

定期清理 Docker 资源:随着时间推移,Docker 容器、镜像和卷会累积,定期清理这些资源有助于避免意外冲突和资源占用。

网络与防火墙配置:确保主机的防火墙规则允许外部访问相应的端口,特别是在多台机器或不同网络环境中测试时。

这次的经历不仅帮助我解决了当前的问题,也让我更深刻地理解了 Docker 网络配置的重要性。如果你也遇到类似的问题,希望这篇博客能为你提供一些有用的解决思路。