Вопрос или проблема
В автоматизированном резервном копировании базы данных базы данных экспортируются в Google Bucket с помощью команды:
gcloud sql export sql "$INSTANCE" "gs://db-backup-temp-storage/${INSTANCE_PREFIX}_${DB}_dump.gz" --database="${DB}"
Несколько дней назад эта команда начала часто давать сбой (~ 80 %). Когда она выполняется несколько раз после сбоя, она выполняется после нескольких попыток. Сообщение об ошибке:
$ gcloud --verbosity=debug sql export sql "$INSTANCE" "gs://db-backup-temp-storage/${INSTANCE_PREFIX}_${DB}_dump.gz" --database="${DB}"
DEBUG: Запуск [gcloud.sql.export.sql] с аргументами: [--database: "['staging_tool_tool']", --verbosity: "debug", INSTANCE: "prd-pg", URI: "gs://db-backup-temp-storage/pg_staging_tool_tool_dump.gz"]
DEBUG: Начинаю новое HTTPS соединение (1): sqladmin.googleapis.com:443
DEBUG: https://sqladmin.googleapis.com:443 "POST /sql/v1beta4/projects/<PROJECT_NAME>/instances/prd-pg/export?alt=json HTTP/1.1" 403 None
DEBUG: (gcloud.sql.export.sql) HTTPError 403: У учетной записи сервиса нет необходимых разрешений для корзины. Эта команда аутентифицирована как prod-rundeck-kubectl@<PROJECT_NAME>.iam.gserviceaccount.com, который является активной учетной записью, указанной в свойстве [core/account].
Трассировка (последний вызов последним):
Файл "/usr/bin/../lib/google-cloud-sdk/lib/googlecloudsdk/calliope/cli.py", строка 998, в Execute
ресурсы = calliope_command.Run(cli=self, args=args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/googlecloudsdk/calliope/backend.py", строка 842, в Run
ресурсы = command_instance.Run(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/surface/sql/export/sql.py", строка 75, в Run
return export_util.RunSqlExportCommand(args, client)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/googlecloudsdk/command_lib/sql/export_util.py", строка 146, в RunSqlExportCommand
return RunExportCommand(args, client, sql_export_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/googlecloudsdk/command_lib/sql/export_util.py", строка 91, в RunExportCommand
result_operation = sql_client.instances.Export(export_request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/googlecloudsdk/generated_clients/apis/sqladmin/v1beta4/sqladmin_v1beta4_client.py", строка 832, в Export
return self._RunMethod(
^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/third_party/apitools/base/py/base_api.py", строка 747, в _RunMethod
return self.ProcessHttpResponse(method_config, http_response, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/third_party/apitools/base/py/base_api.py", строка 753, в ProcessHttpResponse
self.__ProcessHttpResponse(method_config, http_response, request))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Файл "/usr/bin/../lib/google-cloud-sdk/lib/third_party/apitools/base/py/base_api.py", строка 612, в __ProcessHttpResponse
raise exceptions.HttpError.FromResponse(
apitools.base.py.exceptions.HttpForbiddenError: HttpError при доступе к <https://sqladmin.googleapis.com/sql/v1beta4/projects/<PROJECT_NAME>/instances/prd-pg/export?alt=json>: ответ: <{'vary': 'Origin, X-Origin, Referer', 'content-type': 'application/json; charset=UTF-8', 'content-encoding': 'gzip', 'date': 'Wed, 09 Oct 2024 14:16:56 GMT', 'server': 'ESF', 'cache-control': 'private', 'x-xss-protection': '0', 'x-frame-options': 'SAMEORIGIN', 'x-content-type-options': 'nosniff', 'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000', 'transfer-encoding': 'chunked', 'status': 403}>, контент <{
"error": {
"code": 403,
"message": "У учетной записи сервиса нет необходимых разрешений для корзины.",
"errors": [
{
"message": "У учетной записи сервиса нет необходимых разрешений для корзины.",
"domain": "global",
"reason": "notAuthorized"
}
]
}
}
>
ERROR: (gcloud.sql.export.sql) HTTPError 403: У учетной записи сервиса нет необходимых разрешений для корзины. Эта команда аутентифицирована как prod-rundeck-kubectl@<PROJECT_NAME>.iam.gserviceaccount.com, который является активной учетной записью, указанной в свойстве [core/account].
При анализе разрешений в облачной консоли (IAM & Admin → Учетные записи сервисов → prod-rundeck-kubectl@<PROJECT_NAME>.iam.gserviceaccount.com → Разрешения → Просмотреть доступ → Анализ) у учетной записи сервиса есть разрешения “Storage Object Admin” и “Cloud SQL Editor”, как упоминается в документации.
Странно то, что экспорт выполняется, когда команду повторяют, не изменяя ничего, что заставляет думать, что это не проблема разрешений.
Кто-нибудь знает, в чем может быть причина или как это диагностировать?
Ответ или решение
Причина, по которой экспорт баз данных в Google Cloud SQL иногда завершает работу с ошибкой разрешений (403), может быть связана с несколькими факторами, несмотря на то, что у вашего сервисного аккаунта есть необходимые права. Рассмотрим действие и возможные решения проблемы:
1. Проверка разрешений сервисного аккаунта
Хотя у вашего аккаунта должны быть разрешения "Storage Object Admin" и "Cloud SQL Editor", важно убедиться, что они действительно применимы к нужному проекту и ресурсу:
- Перейдите в консоль Google Cloud и убедитесь, что все разрешения корректны.
- Проверьте, что ваша учетная запись действительно имеет эти роли для проекта, в который вы делаете экспорт.
2. Потенциальные проблемы с кэшированием или задержкой
Вероятно, проблема может быть связана с временной недоступностью, например, при кэшировании или задержке обновления прав после их изменения:
- Если вы недавно изменяли разрешения, подождите некоторое время и попробуйте еще раз.
- Выполняйте экспорт с использованием
--verbosity=debug
, чтобы отслеживать дополнительные детали.
3. Перезапись хранения
Поскольку проблема наблюдается только иногда, возможно, что возникают конфликты при записи в Google Cloud Storage:
- Убедитесь, что вы не пытаетесь экспортировать в существующий файл. Попробуйте использовать уникальные имена для файлов экспорта, чтобы избежать конфликтов.
- Задайте более уникальное имя файла в вашем скрипте, добавляя временную метку, например:
gs://db-backup-temp-storage/${INSTANCE_PREFIX}_${DB}_dump_$(date +%Y%m%d_%H%M%S).gz
.
4. Мониторинг и журналирование
Обратите внимание на журналы ошибок:
- Используйте Google Cloud Logging для мониторинга и анализа проблем во время выполнения команды.
- Логи могут предоставить дополнительную информацию о том, почему происходит ошибка.
5. Настройки доступа к API
Убедитесь, что у вашего сервисного аккаунта есть разрешение на доступ к нужным API:
- Переходите в раздел IAM & Admin → Service Accounts, проверьте, активно ли API Cloud SQL Admin и Google Cloud Storage для вашего проекта.
- При необходимости проверьте настройки контроля доступа к API и самих API.
6. Программные ошибки
Если проблема продолжает возникать, возможно, имеются проблемы с самим инструментом gcloud
или его зависимостями:
- Убедитесь, что у вас установлена последняя версия SDK Google Cloud. Запустите команду
gcloud components update
.
Заключение
Если несмотря на все предложенные шаги проблема не решается, рекомендуется обратиться в службу поддержки Google Cloud для более глубокого анализа. Вам могут потребоваться предоставить логи и конфигурации, которые помогут определить источник проблемы.
Такой подход поможет вам не только устранить текущую ошибку, но также улучшить стабильность ваших автоматизированных процессов резервного копирования.