Cloud Run Job通过Cloud Scheduler调度时出现未认证错误,手动执行正常
Cloud Run Job调度时出现UNAUTHENTICATED错误的问题排查
问题描述
我的Cloud Run Job手动执行正常,但通过Cloud Scheduler调度时持续失败,报错为UNAUTHENTICATED(未认证)。该Job是Python脚本,逻辑为从Mouseflow API拉取数据存入临时DataFrame,再导入BigQuery。此前在Cloud Functions中运行同一段代码时,曾因无响应导致调度失败,添加try-return和else语句后解决,但Cloud Run Job的调度问题仍存在。
代码示例
from io import StringIO import requests import json import pandas as pd from google.cloud import bigquery from requests.auth import HTTPBasicAuth def rec(request): r = requests.get("https://api-eu.mouseflow.com/websites/e768ed54-c09b-48dc-bf49-beda12697013/recordings", auth=HTTPBasicAuth("****************", "********************")) if r.status_code == 200: parsed = json.loads(r.text) print(json.dumps(parsed['recordings'], indent=4, sort_keys=True)) df = pd.DataFrame.from_records(parsed['recordings']) try: temp_csv_string = df.to_csv(sep=";", index=False) temp_csv_string_IO = StringIO(temp_csv_string) new_df = pd.read_csv(temp_csv_string_IO, sep=";") new_df.to_gbq('Mouseflow.Mouseflow_Recording', if_exists='replace', project_id='api-data-pod') return f'Successful' except Exception as err: return f'Upload to BigQuery failed: {err}' else: return f'API request error occurred: Status code {r.status_code}' rec(requests)
错误日志
{ "insertId": "1u1op9ffik0vad", "jsonPayload": { "jobName": "projects/api-data-pod/locations/us-central1/jobs/mouseruningjober", "status": "UNAUTHENTICATED", "url": "https://us-central1-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/api-data-pod/jobs/mouseruningjober:run", "@type": "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished", "targetType": "HTTP" }, "httpRequest": { "status": 401 }, "resource": { "type": "cloud_scheduler_job", "labels": { "location": "us-central1", "project_id": "api-data-pod", "job_id": "mouseruningjober" } }, "timestamp": "2022-08-09T08:26:20.781273719Z", "severity": "ERROR", "logName": "projects/api-data-pod/logs/cloudscheduler.googleapis.com%2Fexecutions", "receiveTimestamp": "2022-08-09T08:26:20.781273719Z" }
排查方向
- 检查Cloud Scheduler身份验证配置:
Cloud Scheduler调用Cloud Run Job需配置正确服务账号,确保该账号拥有run.jobs.run权限(对应roles/run.invoker角色)。确认调度器目标为HTTP时,已勾选"添加OIDC令牌",服务账号邮箱填写正确,受众(Audience)与Cloud Run Job的调用URL完全匹配(即日志中显示的URL)。 - 验证Cloud Run Job的IAM权限:
检查Cloud Run Job的IAM设置,确保调度器使用的服务账号被授予Cloud Run Invoker角色,拥有调用该Job的权限。 - 排查代码中的触发逻辑问题:
当前代码中rec(requests)的调用存在错误,rec函数期望接收request对象,但传入requests模块会导致参数异常,这可能是手动执行未暴露但调度时触发的潜在问题。 - 确认BigQuery权限配置:
Cloud Run Job运行时使用自身服务账号,需确保该账号拥有BigQuery的dataEditor或jobUser等必要权限,避免内部执行时的认证失败干扰调度排查。
解决建议
- 修正代码触发逻辑:
Cloud Run Job不需要接收request参数,重构代码为独立执行的主函数,确保错误能被正确抛出以便排查:from io import StringIO import requests import json import pandas as pd from google.cloud import bigquery from requests.auth import HTTPBasicAuth def main(): r = requests.get("https://api-eu.mouseflow.com/websites/e768ed54-c09b-48dc-bf49-beda12697013/recordings", auth=HTTPBasicAuth("****************", "********************")) if r.status_code == 200: parsed = json.loads(r.text) print(json.dumps(parsed['recordings'], indent=4, sort_keys=True)) df = pd.DataFrame.from_records(parsed['recordings']) try: temp_csv_string = df.to_csv(sep=";", index=False) temp_csv_string_IO = StringIO(temp_csv_string) new_df = pd.read_csv(temp_csv_string_IO, sep=";") new_df.to_gbq('Mouseflow.Mouseflow_Recording', if_exists='replace', project_id='api-data-pod') print('Successful') except Exception as err: print(f'Upload to BigQuery failed: {err}') raise err else: error_msg = f'API request error occurred: Status code {r.status_code}' print(error_msg) raise Exception(error_msg) if __name__ == "__main__": main() - 重新配置Cloud Scheduler:
- 进入Cloud Scheduler控制台,编辑目标Job。
- 目标类型选择HTTP,方法设为POST,URL填写Cloud Run Job的调用URL。
- 勾选"添加OIDC令牌",选择拥有
run.invoker权限的服务账号,受众填写与URL完全一致的地址。
- 配置Cloud Run Job的IAM权限:
在Cloud Run控制台的Job详情页,进入"权限"标签,给调度器使用的服务账号添加Cloud Run Invoker角色。 - 测试调度执行:
使用gcloud scheduler jobs run mouseruningjober --location us-central1命令手动触发调度,同时查看Cloud Run Job的日志,确认是否有新的错误信息。
内容的提问来源于stack exchange,提问作者user19589395
相关产品推荐
相关产品推荐

