Docker 容器端口无法从外部访问
### 文章目录
- [Docker 容器端口无法从外部访问](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
- [@[TOC](文章目录)](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
- [服务器信息](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
- [问题描述](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
- [排查思路](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
- [解决方案](#文章目录 Docker 容器端口无法从外部访问 @TOC 服务器信息 问题描述 排查思路 解决方案)
服务器信息
openEuler 22.03
问题描述
事情的起因是要在服务器部署Open webUI的web服务,我是使用docker进行部署的,本来是觉得很简单的一件事,但是当我部署完成后,我用笔记本直连服务器,本地笔记本浏览器访问的时候发现不通https://192.168.137.102:8000,服务器ip是192.168.137.102,本地笔记本ip配的是192.168.137.100,ip是通的,但是8000端口不通。
排查思路
-
首先怀疑是服务器防火墙给拦截了,然后查看防火墙状态发现是关闭的,所以这个就可以忽略掉了。
shell# 查看防火墙状态 systemctl status firewalld -
因为我是用自己的笔记本直连服务器的,然后又排查了本地的防火墙是否开启,然后又把本地的防火墙都关闭后,发现还是不行。
-
然后又检查服务器的NAT规则是否存在,发现Docker已正确写入DNAT规则,也没问题。
shell# 查看NAT规则 iptables -t nat -L -n -v -
然后因为服务器是多网卡,由此联想到是不是多网卡的问题,所以检查了路由表
shell# 查看路由表 ip route 结果: default via 10.193.200.1 dev enp67s0f1npl 192.168.137.0/24 dev enp189s0f1 proto kernel scope link src 192.168.137.102 - 默认网关走 `10.193.200.1`(网卡 `enp67s0f1npl`) - `192.168.137.0/24` 直连网卡 `enp189s0f1`,IP 为 `192.168.137.102` → 路由正常,`192.168.137.102` 是容器端口对外暴露的正确 IP。 -
对比 SSH 和 8000 端口的链路差异(关键发现)
shell# 查看 FORWARD 链状态 iptables -L FORWARD -n -v端口 来源 走的链路 依赖 SSH 22 外部 → 服务器 INPUT→ sshd不依赖 IP 转发 Docker 443 外部 → 容器 PREROUTING(DNAT) →FORWARD→POSTROUTING→ 容器依赖 IP 转发 → 这一步定位到:Docker 端口映射必须走
FORWARD链,而FORWARD链依赖 Linux IP 转发功能开启。 -
检查 IP 转发状态(找到根因)
shellcat /proc/sys/net/ipv4/ip_forward 结果: 0 IP 转发关闭(值为 0),这就是导致外部流量无法转发到 Docker 容器的唯一原因。
解决方案
-
开启转发
shell# 立即生效(临时) sysctl -w net.ipv4.ip_forward=1 # 永久生效 # 追加到 sysctl.confecho "net.ipv4.ip_forward=1" >> /etc/sysctl.conf# 使配置立即生效sysctl -p