即使使用 iptables 命令打开端口,docker 暴露的端口也无法从外部访问

即使使用 iptables 命令打开端口,docker 暴露的端口也无法从外部访问

我在基于 Linux 的服务器中有一个示例 docker tar 映像,并通过 docker run 命令运行该映像,如下所示,其中 9521f101839f 是映像 ID。

docker run -p 0.0.0.0:9895:9898 -td 9521f101839f

现在 docker 容器已经存在,并且该项目(rest api)在我的服务器内工作正常。

docker ps 命令输出看起来也正确:

a97904cb07d1 localhost/elk-spring-boot.jar:latest 22 minutes ago Up 22 minutes ago 0.0.0.0:9895->9898/tcp compassionate_goldberg

如您所见,它向外界暴露了9895。

 iptables -I INPUT -p tcp -m tcp --dport 9895 -j ACCEPT

使用上面的 iptables 命令,我确保打开 9895 端口。

[root@pxgrid-163 localdisk]# iptables -nvL | grep 9895
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:9895
1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9895
1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9895
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:9895
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9895

但是,当我尝试从另一个基于 Linux 的服务器(或从我的笔记本电脑 CLI)卷曲到此 docker 容器服务器时,它无法访问。从我保存 docker 容器的服务器内部,我可以正确访问所有内容。但是,当我尝试从单独的服务器(或我的笔记本电脑)执行curl 来访问api(docker run api)时,它无法访问。

这是预期的行为吗?难道它不应该从外部访问吗,因为端口暴露于外部世界?我在这里错过了什么吗?

以下是我执行 ifconfig 时的网络接口列表

我们在这里讨论的是哪个interface_ip?是eth0吗?当我执行 ifconfig 时,我看到了很多接口

ifconfig
cni-podman0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 10.88.0.1  netmask 255.255.0.0  broadcast 10.88.255.255

cni-podman1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.2.1  netmask 255.255.255.0  broadcast 169.254.2.255

cni-podman2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.4.1  netmask 255.255.255.0  broadcast 169.254.4.255

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.23.166.163  netmask 255.255.255.0  broadcast 172.23.166.255

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0        

veth506e78cf: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500 

veth6c80d69f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        
vethe32079e7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

答案1

Doker 在你的机器中有自己的网络 172.16.0.0/12。

尝试

-p your_interface_ip:9895:9898

还要检查 ip 转发是否启用

sysctl -w net.ipv4.ip_forward=1

https://docs.docker.com/config/containers/container-networking/

https://www.docker.com/blog/understanding-docker-networking-drivers-use-cases/

答案2

我必须按照以下 2 个步骤在我的服务器中启用 IP 转发

  1. 配置 Linux 内核以允许 IP 转发。 - sysctl net.ipv4.conf.all.forwarding=1
  2. 将 iptables FORWARD 策略从 DROP 更改为 ACCEPT - iptables -P FORWARD ACCEPT

此后,我可以从我的笔记本电脑以及其他服务器访问 api。

相关内容