如何从互联网直接连接GCE实例上运行的嵌套VM
我之前帮几个客户处理过类似的GCP嵌套VM公网访问问题,结合你已经配置了IP别名和iptables的基础,给你两个最可行的方案,一步步来:
这是最简易的方式,依托你已经在用的iptables,只需要补充几个配置:
启用主机的IP转发功能
嵌套VM的流量要通过主机转发,必须先开启主机的IP转发:# *临时生效*(重启后会丢失) echo 1 > /proc/sys/net/ipv4/ip_forward # *永久生效*(重启后保持配置) echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p配置iptables端口转发规则
假设你的嵌套VM内部IP是192.168.1.10,想要把主机的2222端口映射到嵌套VM的22端口(SSH),执行以下命令:# 将外部访问主机2222的流量转发到嵌套VM的22端口 iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.10:22 # 允许转发的流量通过主机 iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT别忘了保存iptables规则防止重启丢失:
- Debian/Ubuntu:
iptables-save > /etc/iptables/rules.v4 - RHEL/CentOS:
service iptables save
- Debian/Ubuntu:
配置GCP防火墙规则放行流量
在GCP控制台或用gcloud命令创建入站防火墙规则,允许互联网访问主机的目标端口:gcloud compute firewall-rules create allow-nested-vm-ssh --direction=INGRESS --priority=1000 --network=你的VPC名称 --action=ALLOW --rules=tcp:2222 --source-ranges=0.0.0.0/0 --target-tags=你的主机实例标签这里的
target-tags要和你主机实例的标签一致,确保规则只应用到这台主机。测试连接
用ssh -p 2222 你的主机外部IP测试,应该能直接连到嵌套VM的SSH服务。
如果需要映射多个端口、使用独立的外部IP,或者更符合GCP网络架构规范,推荐这种方式:
添加VPC静态路由
在GCP VPC中添加一条静态路由,告诉GCP网络:发往嵌套VM子网(比如192.168.1.0/24)的流量,要转发到你的主机实例内部IP。
用gcloud命令的话:gcloud compute routes create nested-vm-route --network=你的VPC名称 --destination-range=192.168.1.0/24 --next-hop-instance=你的主机实例名称 --next-hop-instance-zone=你的主机所在区域创建GCP外部转发规则
分配一个独立的外部IP(或者用现有IP),创建转发规则把外部IP的端口映射到嵌套VM的端口:# 先分配外部IP(如果没有的话) gcloud compute addresses create nested-vm-external-ip --region=你的区域 # 创建转发规则,把外部IP的22端口指向嵌套VM的22端口(流量先到主机,再转发) gcloud compute forwarding-rules create nested-vm-forwarder --address=nested-vm-external-ip --ports=22 --target-instance=你的主机实例名称 --target-instance-zone=你的主机所在区域完善主机的转发配置
同样要确保主机开启了IP转发,并且iptables允许转发流量到嵌套VM(和方案一的前两步一致)。配置防火墙规则
创建防火墙规则允许转发规则的端口流量(比如tcp:22)到主机实例,和方案一的防火墙配置逻辑一样,只是端口改成你映射的端口。
- 嵌套VM自身的防火墙要允许来自主机IP(或公网)的目标端口流量,比如嵌套VM的iptables要放行
tcp:22。 - 如果用了IP别名,确保主机实例的网卡已经关联了IP别名子网,嵌套VM的网络绑定到该子网。
- 主机实例的服务账号需要有
Compute Instance Admin或类似的权限,确保能处理路由转发(默认的Compute Engine服务账号一般足够)。
内容的提问来源于stack exchange,提问作者Aosoft

