Я пытался вызвать функцию GCP (--runtime nodejs8 --trigger-http) из планировщика GCP, оба расположены в одном проекте. Я могу заставить его работать, только если я предоставлю доступ без аутентификации, добавив член allUsers к разрешениям функций с примененной к нему ролью Cloud Functions-Invoker. Однако, когда я использую только служебную учетную запись планировщика в качестве Cloud Functions-Invoker, я получаю ошибку PERMISSION DENIED.
--runtime nodejs8 --trigger-http
allUsers
Cloud Functions-Invoker
Я создал пример Hello World, чтобы подробно показать, как выглядит моя установка.
gcloud iam service-accounts create scheduler --display-name="Task Schedule Runner"
svc_policy.json: { "bindings": [ { "members": [ "serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com" ], "role": "roles/cloudscheduler.serviceAgent" } ] } gcloud iam service-accounts set-iam-policy scheduler@mwsdata-1544225920485.iam.gserviceaccount.com svc_policy.json -q
gcloud functions deploy helloworld --runtime nodejs8 --trigger-http --entry-point=helloWorld
gcloud functions add-iam-policy-binding helloworld --member serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com --role roles/cloudfunctions.invoker
gcloud beta scheduler jobs create http test-job --schedule "5 * * * *" --http-method=GET --uri=https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld --oidc-service-account-email=scheduler@mwsdata-1544225920485.iam.gserviceaccount.com --oidc-token-audience=https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld
Журнал: РАЗРЕШЕНИЕ НА РАЗРЕШЕНИЕ
{ httpRequest: { } insertId: "1ny5xuxf69w0ck" jsonPayload: { @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished" jobName: "projects/mwsdata-1544225920485/locations/europe-west1/jobs/test-job" status: "PERMISSION_DENIED" targetType: "HTTP" url: "https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld" } logName: "projects/mwsdata-1544225920485/logs/cloudscheduler.googleapis.com%2Fexecutions" receiveTimestamp: "2020-02-04T22:05:05.248707989Z" resource: { labels: { job_id: "test-job" location: "europe-west1" project_id: "mwsdata-1544225920485" } type: "cloud_scheduler_job" } severity: "ERROR" timestamp: "2020-02-04T22:05:05.248707989Z" }
Вот соответствующие настройки.
Учетная запись службы планировщика
gcloud iam service-accounts get-iam-policy scheduler@mwsdata-1544225920485.iam.gserviceaccount.com bindings: - members: - serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com role: roles/cloudscheduler.serviceAgent etag: BwWdxuiGNv4= version: 1
Политика IAM функции:
gcloud functions get-iam-policy helloworld bindings: - members: - serviceAccount:scheduler@mwsdata-1544225920485.iam.gserviceaccount.com role: roles/cloudfunctions.invoker etag: BwWdxyDGOAY= version: 1
Описание функции
gcloud functions describe helloworld availableMemoryMb: 256 entryPoint: helloWorld httpsTrigger: url: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld ingressSettings: ALLOW_ALL labels: deployment-tool: cli-gcloud name: projects/mwsdata-1544225920485/locations/us-central1/functions/helloworld runtime: nodejs8 serviceAccountEmail: mwsdata-1544225920485@appspot.gserviceaccount.com sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-671641e6-3f1b-41a1-9ac1-558224a1638a/b4a0e407-69b9-4f3d-a00d-7543ac33e013.zip?GoogleAccessId=service-617967399269@gcf-admin-robot.iam.gserviceaccount.com&Expires=1580854835&Signature=S605ODVtOpnU4LIoRT2MnU4OQN3PqhpR0u2CjgcpRcZZUXstQ5kC%2F1rT6Lv2SusvUpBrCcU34Og2hK1QZ3dOPluzhq9cXEvg5MX1MMDyC5Y%2F7KGTibnV4ztFwrVMlZNTj5N%2FzTQn8a65T%2FwPBNUJWK0KrIUue3GemOQZ4l4fCf9v4a9h6MMjetLPCTLQ1BkyFUHrVnO312YDjSC3Ck7Le8OiXb7a%2BwXjTDtbawR20NZWfgCCVvL6iM9mDZSaVAYDzZ6l07eXHXPZfrEGgkn7vXN2ovMF%2BNGvwHvTx7pmur1yQaLM4vRRprjsnErU%2F3p4JO3tlbbFEf%2B69Wd9dyIKVA%3D%3D status: ACTIVE timeout: 60s updateTime: '2020-02-04T21:51:15Z' versionId: '1'
Описание задания планировщика
gcloud scheduler jobs describe test-job attemptDeadline: 180s httpTarget: headers: User-Agent: Google-Cloud-Scheduler httpMethod: GET oidcToken: audience: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld serviceAccountEmail: scheduler@mwsdata-1544225920485.iam.gserviceaccount.com uri: https://us-central1-mwsdata-1544225920485.cloudfunctions.net/helloworld lastAttemptTime: '2020-02-05T09:05:00.054111Z' name: projects/mwsdata-1544225920485/locations/europe-west1/jobs/test-job retryConfig: maxBackoffDuration: 3600s maxDoublings: 16 maxRetryDuration: 0s minBackoffDuration: 5s schedule: 5 * * * * scheduleTime: '2020-02-05T10:05:00.085854Z' state: ENABLED status: code: 7 timeZone: Etc/UTC userUpdateTime: '2020-02-04T22:02:31Z'
Вот шаги, которые я выполнил, чтобы Cloud Scheduler запускал запускаемую по HTTP облачную функцию, которая не допускает неаутентифицированные вызовы:
gcloud scheduler jobs create http [JOB-NAME] --schedule="* * * * *" --uri=[CLOUD-FUNCTIONS-URL] --oidc-service-account-email=[SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com
In ваш конкретный c случай, когда вы оставляете учетную запись службы App Engine по умолчанию для своих облачных функций. Измените его на учетную запись службы, которую вы создали, как указано на предыдущих шагах.
@ Marko Я прошел через ту же проблему, она, кажется, снова включила (отключила / включила) API планировщика. Вот почему создание нового проекта имеет смысл, потому что вы, вероятно, получили учетную запись службы планировщика. Поэтому, если в вашем проекте нет учетной записи службы планировщика, созданной в Google, этот трюк даст вам такую возможность. И хотя вам не нужно назначать эту указанную c учетную запись службы для какой-либо из ваших задач, она должна быть доступна. Вы можете увидеть мою работу здесь: Как вызвать Cloud Function из Cloud Scheduler с аутентификацией