GCP中的Metadata Server
GCP Metadata Server 是 Google Cloud 在运行环境(GCE VM、GKE、Cloud Run、App Engine 等)内部提供的一个本地 HTTP 服务,用来让程序获取:
当前实例信息(Instance Metadata)
当前项目(Project)信息
Service Account 信息
OAuth Access Token
Identity Token (OIDC JWT)
用户自定义 Metadata
它的作用类似 AWS 的 IMDS (Instance Metadata Service)。
下面通过GCE中的实例来理解Metadata Server的用法。
查看所有可用API
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/
instance/
oslogin/
project/获取项目Metadata
获取项目id
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/project/project-id
spheric-backup-427305-v3获取数字项目id
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/project/numeric-project-id
713826089555Instance Metadata
Instance Metadata存在http://metadata.google.internal/computeMetadata/v1/instance/目录下面,每个路径都是一个key,对应了一些metadata信息。
查询所有路径:
yuzhehappymax@instance-20260609-051755:~$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/
attributes/
cpu-platform
credentials/
description
disks/
gce-workload-certificates/
guest-attributes/
hostname
id
image
licenses/
machine-type
maintenance-event
name
network-interfaces/
partner-attributes/
preempted
remaining-cpu-time
scheduling/
service-accounts/
shutdown-details/
tags
upcoming-maintenance
virtual-clock/
zone查询instance id:
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/id
857298834629604914查询hostname:
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/hostname
instance-20260609-051755.us-central1-c.c.spheric-backup-427305-v3.internal查询zone:
yuzhehappymax@instance-20260609-051755:~$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/zone
projects/713826089555/zones/us-central1-cMachine type:
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/machine-type
projects/713826089555/machineTypes/e2-microNetwork Metadata
获取Internal IP
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip
10.128.0.32获取External IP
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip
34.58.251.156获取VPC Network
yuzhehappymax@instance-20260609-051755:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/network
projects/713826089555/networks/defaulCustom Metadata
如果创建VM时指定了metadata,可以这样读取。
gcloud compute instances create myvm \
--metadata org=king,team=zheuyuzhehappymax@instance-20260609-054925:~$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/team
zheuyuzhehappymax@instance-20260609-054925:~$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/org
kingService Account API
这是最为重要的一类API。
yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/
713826089555-compute@developer.gserviceaccount.com/
default/yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email
713826089555-compute@developer.gserviceaccount.com查看Scope:
yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes
https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring.write
https://www.googleapis.com/auth/service.management.readonly
https://www.googleapis.com/auth/servicecontrol
https://www.googleapis.com/auth/trace.append获取OAuth Access Token
这是 Metadata Server 最常用的接口。
yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
{"access_token":"ya29.c.xxx","expires_in":3336,"token_type":"Bearer"}用Token调用Google API:
TOKEN=$(curl \
-H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
| jq -r .access_token)yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Authorization: Bearer $TOKEN" \
https://cloudresourcemanager.googleapis.com/v1/projects
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "google.cloudresourcemanager.v1.Projects.ListProjects",
"service": "cloudresourcemanager.googleapis.com"
}
}
]
}
}
yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Authorization: Bearer $TOKEN" \
https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
{
"azp": "107662016686531267400",
"aud": "107662016686531267400",
"scope": "https://www.googleapis.com/auth/trace.append https://www.googleapis.com/auth/monitoring.write https://www.googleapis.com/auth/servicecontrol https://www.googleapis.com/auth/service.management.readonly https://www.googleapis.com/auth/logging.write https://www.googleapis.com/auth/devstorage.read_only",
"exp": "1780987867",
"expires_in": "3114",
"access_type": "online"
}用当前Token不能ListProject,这是因为该Token的scope太窄。ListProject需要https://www.googleapis.com/auth/cloud-platform scope,而GCE实例一旦创建就不能在运行时更改scope了。两种解决办法:一是重新创建VM并指定scope,二是用Cloud Run。Cloud Run是基于Service Account和IAM的。
重建VM并指定scope:
gcloud compute instances create INSTANCE_NAME \
--scopes=https://www.googleapis.com/auth/cloud-platform获取Identity Token (OIDC JWT)
yuzhehappymax@instance-20260609-054925:~$ curl \
-H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://my-service.run.app"
eyJhbGciOiJSUzI1N...用https://www.jwt.io/解码该JWT得到如下结果:
Header:
{
"alg": "RS256",
"kid": "7b021671ede90ee5a375c022a523d490181a2c9d",
"typ": "JWT"
}Payload:
{
"aud": "https://my-service.run.app",
"azp": "107662016686531267400",
"exp": 1780988695,
"iat": 1780985095,
"iss": "https://accounts.google.com",
"sub": "107662016686531267400"
}Recursive API
获取全部Metadata
curl \
-H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=json"Wait For Change API
Metadata Server 有长轮询能力。
例如监听 Metadata 变化:
curl \
-H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/attributes/my-config?wait_for_change=true"