K8s CronJob中绑定GCP服务账号后gcloud无需手动配置的问题
我在GKE上部署了一个CronJob,它通过Kubernetes服务账号(ServiceAccount)关联了GCP IAM服务账号进行身份认证,但直接在CronJob中执行gcloud命令时会报错。
对应的K8s ServiceAccount配置:
apiVersion: v1 kind: ServiceAccount metadata: annotations: iam.gke.io/gcp-service-account: gke-my-service-account@$(GCP_PROJECT_ID).iam.gserviceaccount.com name: my-service-account
CronJob的命令配置:
command: - "/bin/sh" - "-c" - | gcloud storage cp $FILE gs://my-gcs-bucket/$FILE
执行时出现以下错误:
ERROR: (gcloud.storage.cp) You do not currently have an active account selected. Please run: $ gcloud auth login to obtain new credentials. If you have already logged in with a different account, run: $ gcloud config set account ACCOUNT to select an already authenticated account to use.
手动添加gcloud config set account $GCP_SERVICE_ACCOUNT_EMAIL命令后可以正常运行,但我希望像AWS CLI那样,无需手动配置账号就能让gcloud自动使用绑定的服务账号完成认证。
GKE的Workload Identity确实会将K8s SA关联的GCP IAM SA凭据注入到容器中(挂载在/var/run/secrets/google.com/serviceaccount/路径下),也就是应用默认凭据(ADC)。但gcloud CLI的默认行为是优先读取本地配置文件中的账号信息,当容器内没有预先配置的gcloud账号时,它不会自动切换到使用ADC,因此会提示没有激活的账号。
而手动设置账号后,gcloud会将该账号标记为活跃账号,进而使用对应的凭据(这里实际上就是Workload Identity注入的ADC)完成认证。
有两种简洁的方式实现无需手动配置账号即可运行gcloud CLI:
方法1:通过环境变量指定使用默认凭据
在CronJob的环境变量中添加CLOUDSDK_CORE_ACCOUNT=_default,让gcloud直接使用应用默认凭据:
command: - "/bin/sh" - "-c" - | gcloud storage cp $FILE gs://my-gcs-bucket/$FILE env: - name: CLOUDSDK_CORE_ACCOUNT value: "_default"
_default是gcloud的特殊值,代表使用应用默认凭据,也就是Workload Identity注入的GCP SA身份。
方法2:在命令中显式指定使用默认凭据
在gcloud命令后添加--account=_default参数,强制使用应用默认凭据:
command: - "/bin/sh" - "-c" - | gcloud storage cp $FILE gs://my-gcs-bucket/$FILE --account=_default
额外说明
如果你的镜像中gcloud版本较旧,可能需要先激活服务账号(但这种方式不如上面两种简洁):
command: - "/bin/sh" - "-c" - | gcloud auth activate-service-account --key-file=/var/run/secrets/google.com/serviceaccount/credentials.json gcloud storage cp $FILE gs://my-gcs-bucket/$FILE
不过推荐优先使用前两种方法,它们更符合无配置化的需求。
内容的提问来源于stack exchange,提问作者cosmos-1905-14

