使用VS Code Cloud Code在Minikube中访问Metadata Service失败
Minikube Pod无法访问GCP Metadata Service获取SecretManager密钥的解决方法
问题描述
我是Cloud Run和K8s的新手,目前正在用Node.js开发Cloud Run应用,尝试通过SecretManager存储密钥,但始终无法成功——原因是Minikube Pod内对Metadata Service的请求失败。
错误信息:
Error: Could not refresh access token: request to http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform failed, reason: socket hang up at Gaxios._request (/Users/takamizawa/dev/functions/node_modules/gaxios/build/src/gaxios.js:148:19) at process.processTicksAndRejections (/Users/takamizawa/dev/functions/lib/internal/process/task_queues.js:95:5) at async metadataAccessor (/Users/takamizawa/dev/functions/node_modules/gcp-metadata/build/src/index.js:94:21) at async Compute.refreshTokenNoCache (/Users/takamizawa/dev/functions/node_modules/google-auth-library/build/src/auth/computeclient.js:57:20) at async Compute.getRequestMetadataAsync (/Users/takamizawa/dev/functions/node_modules/google-auth-library/build/src/auth/oauth2client.js:298:17) at async Compute.getRequestHeaders (/workspace/node_modules/google-auth-library/build/src/auth/oauth2client.js:261:26) {config: {…}, response: undefined, error: FetchError, code: 'ECONNRESET', note: 'Exception occurred in retry method that was not classified as transient', …}
该脚本在本地Shell执行时可正常从SecretManager获取密钥,推测问题出在Pod内对Metadata Service的请求上。
环境:Mac Ventura(13.6)系统下的VS Code Cloud Code
解决步骤
1. 明确问题根源
Minikube本地集群不存在GCP专属的Metadata Service(http://169.254.169.254),这个服务仅运行在GCP托管环境(如Compute Engine、Cloud Run)中。本地Shell能正常运行,是因为本地GCP SDK(gcloud)已完成身份认证,而Pod内没有对应的认证环境。
2. 给Minikube Pod注入GCP服务账号密钥
- 在GCP控制台创建服务账号,授予
Secret Manager Secret Accessor权限,下载JSON格式的密钥文件。 - 在Minikube中创建Kubernetes Secret存储该密钥:
kubectl create secret generic gcp-service-account --from-file=key.json=/path/to/your/service-account-key.json - 修改Deployment配置,挂载Secret到Pod,并设置环境变量让Google Auth库读取:
spec: containers: - name: your-app image: your-image env: - name: GOOGLE_APPLICATION_CREDENTIALS value: /secrets/gcp/key.json volumeMounts: - name: gcp-secret mountPath: /secrets/gcp readOnly: true volumes: - name: gcp-secret secret: secretName: gcp-service-account
3. 配置Cloud Code本地调试环境
在VS Code的launch.json中添加环境变量与挂载配置,确保调试时Pod能获取认证信息:
{ "configurations": [ { "type": "cloudcode.kubernetes", "name": "Run on Kubernetes", "request": "launch", "skaffoldConfig": "${workspaceFolder}/skaffold.yaml", "watch": true, "cleanUp": true, "portForward": true, "env": { "GOOGLE_APPLICATION_CREDENTIALS": "/secrets/gcp/key.json" }, "volumeMounts": [ { "name": "gcp-secret", "mountPath": "/secrets/gcp" } ] } ] }
4. 验证Pod内的认证配置
进入运行中的Pod,检查环境变量与密钥文件是否正确加载:
kubectl exec -it <pod-name> -- /bin/sh # 检查环境变量 echo $GOOGLE_APPLICATION_CREDENTIALS # 检查密钥文件 cat /secrets/gcp/key.json
也可在Pod内直接测试SecretManager访问:
# 若Pod无curl,先安装 apt-get update && apt-get install -y curl # 使用gcloud测试(需已安装SDK) gcloud secrets versions access latest --secret=your-secret-name
5. 本地模拟SecretManager(可选)
若不想依赖GCP远程服务,可使用本地模拟器:
- 启动模拟器:
gcloud beta emulators secret-manager start - 在Pod配置中添加环境变量指向模拟器:
注:Mac环境下Minikube需用env: - name: SECRET_MANAGER_EMULATOR_HOST value: "host.docker.internal:8080"host.docker.internal访问本地主机服务,可能需额外配置Minikube网络。
内容的提问来源于stack exchange,提问作者Daisuke Takamizawa
相关产品推荐
相关产品推荐

