为什么需要外部地址来建立 GCE 实例之间的内部连接?

为什么需要外部地址来建立 GCE 实例之间的内部连接?

我有一个 VPC (10.11.0.0/20),其中有 3 个虚拟机。VM2 和 VM3 是相同除了 VM2 具有外部 IP 地址(临时)而 VM3 没有。它们都运行 Docker 映像,并且 Web 服务器公开端口 80。

我有一个“允许所有内部”防火墙规则:

NAME            NETWORK   DIRECTION  PRIORITY  SRC_RANGES    ALLOW
dev-internal    dev       INGRESS    1000      10.11.0.0/20  icmp,tcp:0-65535,udp:0-65535

我可以进入 VM1,并且从它可以 ping VM2 和 VM3。

当我使用nmapVM2 时,我可以看到 998 个端口已关闭并且都已ssh打开http- 正如预期的那样。

当我nmap使用 VM3 时,我获得 999 个端口已过滤- 意味着防火墙屏蔽了它们? - 并且只ssh暴露了端口。

我可以curl从 VM2 执行此操作,但 VM3 超时了。

我希望能够跨内部网络进行通信,而无需分配外部 IP。我做错了什么?

(唯一的轻微复杂之处在于 VPC 是在 1 个项目中定义的,而 VPC-Shared 则定义在第二个项目中。防火墙规则和路由是在 VPC 主机项目中定义的。虚拟机位于第二个项目中,但在共享 VPC 上。)

netstat -antp编辑:来自VM2的结果:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1207/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      311/sshd            
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      299/systemd-resolve 
tcp        0      0 10.11.0.6:46458         169.254.169.254:80      ESTABLISHED 381/python2.7       
tcp        0    272 10.11.0.6:22            173.194.90.33:64360     ESTABLISHED 43364/sshd: jamie_h 
tcp        0      0 10.11.0.6:53880         169.254.169.254:80      ESTABLISHED 401/device_policy_m 
tcp        0      0 10.11.0.6:46454         169.254.169.254:80      CLOSE_WAIT  385/python2.7       
tcp        0      0 10.11.0.6:46460         169.254.169.254:80      ESTABLISHED 385/python2.7       
tcp        0      0 10.11.0.6:46456         169.254.169.254:80      ESTABLISHED 384/python2.7       
tcp6       0      0 :::5355                 :::*                    LISTEN      299/systemd-resolve 

VM3 是完全相同的- 两个容器操作系统都运行相同的 Docker 映像 - 并且由于我没有外部 IP,所以我无法进入它(不需要进行复杂的操作...)。

编辑:重现步骤:

  1. 创建 VPC
  2. 为子网的外部 SSH 和 HTTP 访问创建防火墙规则(我分别使用sshhttp标签)
  3. 为 VPC 上的内部流量创建防火墙规则(源 = 子网,目标 = 子网上的所有实例)
  4. source使用 Debian 创建在 VPC 上调用的 VM,带有ssh网络标签和外部 IP(以支持 SSH 连接)
  5. target1使用 COS 和nginxdemos/helloDocker 镜像(在端口 80 上公开的“hello world”)以及http网络标签和外部 IP在 VPC 上创建调用的 VM
  6. target2使用 COS 和nginxdemos/hello带有http网络标签的Docker 镜像在 VPC 上创建名为 VM 的虚拟机,以及外部 IP
  7. 通过 SSH 连接到source虚拟机并 ping 两者target1target2它们会响应
  8. curl target1然后它返回一个 hello world 页面
  9. curl target2并且超时
  10. nmap -Pn target1显示 ssh + http 打开,其他所有均关闭
  11. nmap -Pn target2显示 ssh 打开并且所有其他 ssh 被过滤

答案1

您不需要外部 IP 来连接您的 GCE 实例。您可以使用虚拟机的内部 IP 在 GCE 实例之间进行通信。确保您的防火墙配置正确,必要的端口已为您的目的打开,并且您有一个在端口 80 上监听的服务。

答案2

这比我预想的要简单得多……

如果没有外部 IP 地址,ContainerOS 实例无法连接互联网拉取 Docker 映像。如果您添加 Cloud NAT 实例(https://cloud.google.com/nat/docs/using-nat),实例拉取镜像,启动它,一切正常。

原因nmap是没有显示 http 并且其他所有内容都被“过滤”,一定是因为防火墙规则在实例启动并运行之前不会应用。

(为了找到这个,我必须在子网上切换“私人 Google 访问”标志。这允许仅限内部的 VM 将日志推送到 Stackdriver,这清楚地显示了 Docker 拉取超时。)

相关内容