我在基于 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 转发
- 配置 Linux 内核以允许 IP 转发。 - sysctl net.ipv4.conf.all.forwarding=1
- 将 iptables FORWARD 策略从 DROP 更改为 ACCEPT - iptables -P FORWARD ACCEPT
此后,我可以从我的笔记本电脑以及其他服务器访问 api。