Я ломал голову, пытаясь понять, что не так с этой установкой. Мне удалось добиться успеха, но думаю, что я просто упускаю эту последнюю часть.
У меня есть следующая установка:
Моя цель — запланировать запуск задания «задачи в очереди» раз в две недели. Это задание выполняет некоторые действия (не важные), а затем ставит некоторые задачи в очередь «элементов процесса».
Кажется, это работает нормально
Каждая задача должна вызывать задание «элемент процесса» с некоторыми переопределениями. Очередь должна управлять ограничением скорости выполнения каждой задачи.
Кажется, в этом проблема.
Настройка IAM:
Я создал специальную роль с разрешением run.jobs.runWithOverrides
, чтобы можно было передавать дополнительные переопределения заданию «элемент процесса» через аргументы в каждой задаче.
Отрывок из того, как я создаю/ставлю задачи в очередь (обратите внимание, все находится в регионе us-west1
):
// NOTE: This code is inside the "enqueue-tasks" job
import { CloudTasksClient } from "@google-cloud/tasks"
const client = new CloudTasksClient()
const project = "my-project-id"
const location = "us-west1"
const queueName = "process-items"
const taskId = "task-123" // example for item #123
const url = "https://run.googleapis.com/v2/projects/my-project-id/locations/us-west1/jobs/process-item:run"
await client.createTask({
parent: client.queuePath(project, location, queueName),
task: {
name: client.taskPath(project, location, queueName, taskId),
httpRequest: {
httpMethod: "POST",
url: url,
oidcToken: {
serviceAccountEmail: "[email protected]",
audience: url,
},
headers: {
"Content-Type": "application/json",
},
body: Buffer.from(JSON.stringify({ overrides: { containerOverrides: [{args: "--item-id=123"}]}})).toString("base64"),
},
},
})
Теперь, хоть я и новичок в GCP, я считаю, что все делаю правильно! Однако по какой-то причине, когда облачные задачи выполняются, они всегда терпят неудачу со статусом «НЕСАНКЦИОНИРОВАНО», и при просмотре панели мониторинга моих заданий облачного запуска я не вижу для них никакого вызова.
Чтобы проверить и убедиться в правильности SA моей облачной задачи, я создал токен доступа в качестве SA из CLI gcloud со следующим:
gcloud auth print-access-token --impersonate-service-account=cloud-task-service-account@my-project.iam.gserviceaccount.com
Затем использовал Bruno (приложение, похожее на почтальона/бессонницу), чтобы попытаться сделать вызов вручную в качестве облачной задачи SA.
> POST https://run.googleapis.com/v2/projects/my-project-id/locations/us-west1/jobs/process-item:run
> authorization: Bearer ya29.c.c0AY...XYZ
> content-type: application/json
> data {"overrides":{"containerOverrides":[{"args":["--item-id=123"]}]}}
Это прекрасно удается! Это заставляет меня думать, что что-то не так с тем, как я ставлю задачи в очередь. Документы невероятно запутаны, и даже копаясь в видеороликах на YouTube, я не могу найти в Интернете никаких ресурсов, таких как Cloud Run Job -> Cloud Tasks -> Cloud Run Job. Буду рад добавить более подробную информацию, если это необходимо, но очень любопытно, если я здесь что-то упускаю :/
Изучив эту похожую проблему , мне интересно, связана ли проблема с аудиторией OIDC. Я просмотрел документацию по конечной точке для запуска задания облачного запуска через REST и нашел это, но, возможно, есть еще одна недокументированная конечная точка, которую я предполагаю использовать с OIDC?
Безопасность Google Cloud не так сложна, но полна ловушек! И вы почувствовали себя в одном из них. Позволь мне объяснить.
Вы должны использовать OIDC (токен идентификации) при вызове ВАШЕГО API (развернутого в Cloud Run, App Engine (с IAP) или облачных функциях). Вы должны использовать OAuth (токен доступа) при вызове API Google.
Вы можете заметить, что используете print-access-token
с командой gcloud, а не print-identity-token
, и это сработало!
Поэтому используйте oauthToken
(и без аудитории) вместо oidcToken
в определении задачи.
Вау, это была проблема. Корю себя, что как-то это пропустил. Думаю, я слишком внимательно следил за примерами/видео. В любом случае, большое спасибо за помощь!