当我尝试访问元数据服务器时出现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 网络中的内部流量仅限于icmp
和tcp: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]