运维时,你可能会遇到这样的问题,那就是Docker 容器已经运行的情况下,我希望宿主机外的程序,比如数据库客户端,能够连接容器内部的端口,如数据库端口。
一旦 Docker 容器已经运行起来后,原则上是不能直接修改容器配置来新增端口的。Docker 容器的端口映射是在启动容器时通过 -p 或者 --publish 参数来设置的,一旦设置好并且容器运行起来后,这些设置就固定下来了。
不过,如果你需要在已经运行的容器对外暴露新的端口,有一些间接的方法可以尝试:
这里分享下方法 2 的具体做法:如何在宿主机上使用 iptables 设置端口转发规则可以将外部请求转发到 Docker 容器的端口上。
基本的步骤:
1、确保 IP 转发已开启:要让 iptables 能够进行端口转发,你需要确认宿主机已经开启了 IP 转发功能。可以通过以下命令查看和开启:
查看 IP 转发是否开启:
sysctl net.ipv4.ip_forward
如果结果为 0,说明 IP 转发功能没有开启,你可以通过以下命令临时开启 IP 转发:
sudo sysctl -w net.ipv4.ip_forward=1
要永久开启 IP 转发,在 /etc/sysctl.conf 文件中设置 net.ipv4.ip_forward=1,然后重新加载配置:
sudo sysctl -p /etc/sysctl.conf
2、设置 NAT 转发规则:使用 iptables 命令设置 NAT 转发规则,将宿主机上的端口转发到容器的端口上。以下是一个 iptables 命令的示例:
sudo iptables -t nat -A PREROUTING -p tcp --dport < 宿主机端口 > -j DNAT --to-destination < 容器 IP>:< 容器端口 >
例如,如果你想将宿主机的 8080 端口转发到容器的 80 端口,且容器的 IP 是 172.17.0.2,可以使用以下命令:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
3、设置过滤规则:为了确保转发的数据包能够被正确处理,你可能还需要添加一条规则来允许经过宿主机的转发流量:
sudo iptables -A FORWARD -p tcp -d < 容器 IP> --dport < 容器端口 > -j ACCEPT
使用上面的例子,命令将会是:
sudo iptables -A FORWARD -p tcp -d 172.17.0.2 --dport 80 -j ACCEPT
4、保存规则:在某些 Linux 发行版中,iptables 规则在重启后不会自动保存。你可以使用 iptables-save 和 iptables-restore 命令来保存和重载规则。对于 Debian/Ubuntu 系统,可以安装 iptables-persistent 包来保存规则。
在执行这些命令时,请特别小心,因为 iptables 的配置错误可能会导致网络服务中断。如果你不熟悉 iptables,建议在测试环境中先进行实验。
如果不嫌麻烦,你还可以在 GitHub 下载一个 gost 来进行端口转发,这个工具我认为是最强转发工具,没有之一。
上述方法并不是直接通过修改现有运行容器来实现的,而是通过一些外部操作或容器重建来实现端口暴露的目的。如果你希望对外暴露端口,建议在设计 Docker 容器时提前规划好端口映射。
最后,好久没更新了,如果本文有帮助,欢迎收藏、关注、转发。