如何在Docker容器中进行端口转发?

7
我希望你能在Docker容器中使用iptables将8080端口转发到80端口。在构建过程中,我遇到了错误消息,如下所示。
以下是Dockerfile:
FROM fedora
RUN whoami && \
 iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

这是输出结果:

[~]# docker build -t temp /home/edfromhadria/Documents/Docker/temp/.
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM fedora
 ---> 834629358fe2
Step 1 : RUN whoami &&  iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
 ---> Running in 95046cf959bf
root
iptables v1.4.21: can't initialize iptables table `nat': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
INFO[0001] The command [/bin/sh -c whoami &&  iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080] returned a non-zero code: 3 

谢谢您提前提供的任何帮助。

1个回答

13

首先,在docker build过程中运行iptables命令是毫无意义的;即使它能工作,iptables命令只会修改内核的运行时配置。这些更改不会保留在Docker镜像上,并且在启动容器时将无法使用。

其次,即使您在启动容器后运行iptables容器(而不是在构建容器时),它仍将失败,因为默认情况下Docker容器没有必要的特权来修改iptables配置(或修改网络等)。 您可以使用--privileged标志启动容器,但这可能不是您想要做的(因为它会授予容器许多其他不必要的特权,从安全角度考虑,只授予绝对必要的特权是个好主意)。

通常,您可以使用Docker的-p选项将主机上的端口连接到容器中的端口,例如:

docker run -p 80:8080 temp

这将把您主机的端口80链接到容器的端口8080。

如果这不是您想要的,更简单的解决方案就是配置容器中的应用程序以在所需的端口上运行。


亲爱的larsks!感谢您的解释,我明白了并记下了。-p选项正好符合我的需求! - los.adrian
“只修改运行时配置”是什么意思?有时我需要比端口转发更复杂的规则。 - Liao Zhuodi
1
在构建过程中运行iptables没有意义,因为iptables命令修改本地网络命名空间的配置,该命名空间是短暂的,并且将在处理Dockerfile中特定的RUN命令后被丢弃。当您docker run一个镜像时,您正在创建一个具有自己一组iptables规则的新网络命名空间。通常,在Docker容器内修改iptables配置是错误的做法。如果您有其他问题,请在StackOverflow上开启一个新的问题。 - larsks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接