如何在 GCE 上公开同一 IP 上的不同端口

How expose different ports on the same IP at GCE

我们正在尝试托管一项服务,该服务需要在 GCE 上的同一地址 上公开至少两个不同的端口。

在我们的例子中,这是 GitLab,它至少应该提供 SSH(端口 22)和 HTTPS(端口 443)访问。但实际上,这可能是需要同一域或 IP 地址上的两个或多个端口的任何服务。

该服务在 GCE VM 实例中 运行 很好,我正在寻找最明智的方式将其公开给全世界。当然,对于像这样的任何生产部署,HTTPS 是强制性的。出于方便和安全原因,我不想在实例上处理 TLS。

我们发现用于公开此服务的所有不同选项都不完美:

在实例上使用 public IP

这意味着直接暴露服务端口。在这种情况下,VM 上的服务需要绑定到众所周知的端口 (22、443)。在我们的例子中,这有点烦人,因为服务在 Docker 内 运行 并且端口 22 与主机上的 SSH 服务器冲突。所以我们必须为主机使用另一个 SSH 端口并自己处理 TLS 证书。不太好。

使用 L4 负载均衡器 (TCP)

基本上相同的限制适用,因为看起来 L4 LB 将流量转发到与接收流量相同的端口。此选项还为 LoadBalancer 配置增加了相当多的开销。我们仍然需要在实例上管理 HTTPS。

使用 L7 负载均衡器 (HTTPS)

这是一个相当灵活的方法,但我们将失去提供 SSH 的能力,这对我们来说是行不通的。

我的问题有没有更好的方法在 GCE 上公开这种服务?

在 AWS 上,您可以只拥有一个带有多个侦听器(HTTPS 和 TCP:22)的 ELB,指向单个实例上的任意端口。 ELB 也可以为您终止 HTTPS。我真的无法想象 GCE 不提供这样的功能。

如果我没理解错的话,您正在寻找的是端口重定向,例如,将端口 2443 公开给 public,但您的服务正在内部侦听 443。你可以这样做:

1) 在您的 VM 上为端口重定向配置 iptables:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport <public-port> -j REDIRECT --to-port <internal-port>

http://www.cyberciti.biz/faq/linux-port-redirection-with-iptables/

2) 创建 GCE 防火墙规则以允许 public 端口:

gcloud compute firewall-rules create <name> --allow tcp:<public-port> --network <network> --source-ranges "0.0.0.0/0"