Невозможно вызвать облачную функцию Google из планировщика GCP - PullRequest
2 голосов
/ 04 февраля 2020

Я пытался вызвать функцию GCP (--runtime nodejs8 --trigger-http) из планировщика GCP, оба расположены в одном проекте. Я могу заставить его работать, только если я предоставлю доступ без аутентификации, добавив член allUsers к разрешениям функций с примененной к нему ролью Cloud Functions-Invoker. Однако, когда я использую только служебную учетную запись планировщика в качестве Cloud Functions-Invoker, я получаю ошибку PERMISSION DENIED.

Я создал пример Hello World, чтобы подробно показать, как выглядит моя установка.

  1. Я настроил служебную учетную запись:

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'

Ответы [ 2 ]

3 голосов
/ 07 февраля 2020

Вот шаги, которые я выполнил, чтобы Cloud Scheduler запускал запускаемую по HTTP облачную функцию, которая не допускает неаутентифицированные вызовы:

  1. Создайте учетную запись службы , которая будет иметь следующая форма [SA-NAME] @ [PROJECT-ID] .iam.gserviceaccount.com.
  2. Добавление учетной записи службы [SA-NAME] @ [PROJECT-ID] .iam.gserviceaccount.com как участник проекта и добавил следующие роли в учетную запись службы: Облачные функции Invoker и Администратор облачного планировщика .
  3. Развертывание HTTP запущенная облачная функция , которая не разрешает доступ publi c (не прошедший проверку подлинности) (если вы используете пользовательский интерфейс, просто снимите флажок «Разрешить неаутентифицированные вызовы») и использует недавно созданную учетную запись службы [SA-NAME] @ [ PROJECT-ID] .iam.gserviceaccount.com в поле «Учетная запись службы» (щелкните больше и найдите поле «Учетная запись службы», по умолчанию для нее должна быть установлена ​​учетная запись службы App Engine по умолчанию) и выберите Уведомление об URL-адресе облачной функции.
  4. Создайте задание Cloud Scheduler с проверкой подлинности , введя следующую команду из облачной оболочки: 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 по умолчанию для своих облачных функций. Измените его на учетную запись службы, которую вы создали, как указано на предыдущих шагах.

0 голосов
/ 23 апреля 2020

@ Marko Я прошел через ту же проблему, она, кажется, снова включила (отключила / включила) API планировщика. Вот почему создание нового проекта имеет смысл, потому что вы, вероятно, получили учетную запись службы планировщика. Поэтому, если в вашем проекте нет учетной записи службы планировщика, созданной в Google, этот трюк даст вам такую ​​возможность. И хотя вам не нужно назначать эту указанную c учетную запись службы для какой-либо из ваших задач, она должна быть доступна. Вы можете увидеть мою работу здесь: Как вызвать Cloud Function из Cloud Scheduler с аутентификацией

...