要通过 iptables
将容器中的特定端口请求转发到特定服务器,你需要设置 DNAT
(目标地址转换)规则。以下是详细步骤:
假设场景
- 容器端口:
8080
(容器内服务监听的端口) - 目标服务器:
192.168.1.100
(请求需要转发到的服务器) - 目标服务器端口:
80
(转发到目标服务器的端口) - 宿主机IP:
192.168.1.1
(运行容器的宿主机IP) - 容器网络模式: 假设为
bridge
模式(常见默认模式)
步骤 1:启用 IP 转发
确保 Linux 内核启用了 IP 转发:
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
永久生效需修改 /etc/sysctl.conf
:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
步骤 2:添加 iptables 规则
1. DNAT 规则(修改目标地址和端口)
将宿主机 8080
端口的请求转发到目标服务器 192.168.1.100:80
:
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
2. 允许流量通过 FORWARD 链
确保转发流量不被默认策略拒绝:
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT
3. MASQUERADE 规则(可选,解决回包问题)
如果目标服务器需要将响应包返回给容器,需启用源地址伪装(适用于桥接网络或 NAT 环境):
iptables -t nat -A POSTROUTING -j MASQUERADE
步骤 3:保存规则(根据系统选择)
-
Debian/Ubuntu:
iptables-save > /etc/iptables/rules.v4
-
RHEL/CentOS:
service iptables save
验证规则
-
查看 NAT 表规则:
iptables -t nat -L -n -v
-
测试端口转发:
curl http://宿主机IP:8080
应返回目标服务器
192.168.1.100:80
的内容。
注意事项
- 容器网络模式:
- 如果容器使用
host
网络模式,宿主机端口直接暴露给容器,无需额外转发。 - 如果容器使用自定义网络,需确保
iptables
规则匹配容器的网络接口(如docker0
)。
- 如果容器使用
- 防火墙冲突:
- 如果宿主机启用了
firewalld
或ufw
,需放行相关端口或停用冲突服务。
- 如果宿主机启用了
- 目标服务器路由:
- 确保目标服务器的默认网关能正确返回数据包到宿主机(或启用 MASQUERADE)。
完整示例
将所有访问宿主机 8080
端口的请求转发到 192.168.1.100:80
:
# 启用转发
sysctl -w net.ipv4.ip_forward=1
# 添加 DNAT 规则
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
# 允许转发流量
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT
# 启用源地址伪装
iptables -t nat -A POSTROUTING -j MASQUERADE
# 保存规则(Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4
通过以上步骤,容器内或外部访问宿主机 8080
端口的请求将被透明转发到 192.168.1.100:80
。
配置之后的代码显示
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:13206 to:38.59.178.104:13206
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
KUBE-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes postrouting rules */
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0
Chain KUBE-KUBELET-CANARY (0 references)
target prot opt source destination
Chain KUBE-MARK-DROP (0 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000
Chain KUBE-MARK-MASQ (0 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000
Chain KUBE-POSTROUTING (1 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0 mark match ! 0x4000/0x4000
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK xor 0x4000
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ random-fully