为什么我无法访问 GCP 实例的元数据服务器?

为什么我无法访问 GCP 实例的元数据服务器?

当我尝试访问元数据服务器时出现Could not resolve host metadata.google.internal错误。Could not resolve host metadata

虽然我使用自己的 VPC 和自定义防火墙,但我不认为这是防火墙的问题,因为根据 Google 元数据服务器,流量从未离开实例。此外,我的主机文件中有一个条目可以证明这一点:

# Google Compute Engine metadata server 169.254.169.254 metadata.google.internal metadata

我尝试 ping 169.254.169.254,但它返回General Failure(但这并不能证明什么......我不确定元数据服务器是否允许 ICMP)。

我的 Stackdriver Logging Agents 也因此失败。以下是其日志中的一行:

Failed to access metadata service: error_class=Errno::ENETUNREACH error="Failed to open TCP connection to 169.254.169.254:80 (A socket operation was attempted to an unreachable network. - connect(2) for \"169.254.169.254\" port 80)"

如果重要的话,我的 VPC 网络中的内部流量仅限于icmptcp:22(ssh)。

发生了什么事以及如何解决这个问题?

答案1

虽然我使用带有自定义防火墙的 VPC,但我不认为这是防火墙的问题,因为根据 Google 元数据服务器,流量从未离开实例。

GCP 元数据流量永远不会离开物理主机运行实例。此类请求从客户机的接口发出,但从未被转发。

实例中的主机级防火墙可以阻止流量到达元数据服务器。因为它会在数据包离开客户机之前将其丢弃在实例的网络堆栈中。

通常,元数据服务会响应 http、DNS 和 ICMP echo,但它们都无法为您工作。距离只有一跳,因此不太可能路由错误。听起来确实像防火墙。

答案2

这可能是由于禁用实例的服务帐户造成的。您需要获得授权才能访问元数据。

在 Google Cloud 控制台中:

  • 转到 Compute Engine -> VM 实例。
  • 停止实例。
  • 单击编辑并向下滚动到“服务帐户”。
  • 选择正确的服务帐号,通常是“Compute Engine 默认服务帐号”。
  • 在访问范围下,选择所需的配置。

我建议“允许默认访问”或“允许完全访问所有云 API”。真正的访问控制由分配给服务帐户的角色决定。“访问范围”选项只能限制这些角色,而不能增加它们。

接下来,删除主机文件中元数据的自定义条目。

答案3

您需要在 curl 标头中设置元数据风格,

curl -v -w "\n" -H "Metadata-Flavor: Google" \ 
  http://169.254.169.254/computeMetadata/v1/instance/machine-type

答案4

如果你是:

  • 在 Compute Engine 实例中工作
  • 使用来自另一个项目的服务帐户作为 CE 实例。

然后您需要添加roles/iam.serviceAccountTokenCreator到 Compute Engine 服务代理(服务代理是 GCP 管理的服务帐户)

Compute Engine 的服务代理是:serviceAccount:[email protected]

相关内容