Стадия жизненного цикла модуля: General Availability

Toolbox

Включенные в Toolbox инструменты используются для обслуживания и выполнения административных задач над продуктом Code

Toolbox содержит множество полезных gitlab-инструментов, таких как rails-console, rake-tasks, backup-utillity и т.д. Они позволяют посмотреть совершать такие задачи, как просмотр статуса миграции в БД, профилирование rails-приложений, запуск rake-tasks в административых целях, взаимодействовать с rails-console или выполнять процедуру восстановления из бекапов

# locate the Toolbox pod
kubectl -n d8-code get pods -lapp.kubernetes.io/component=toolbox

# Launch a shell inside the pod
kubectl exec -it <Toolbox pod name> -- bash

# open Rails console
gitlab-rails console -e production

# execute a Rake task
gitlab-rake gitlab:env:info

Советы по Rails-консоли

Rails-console является одним из компонентов Toolbox.

Через Rails-консоль можно выполнить множество полезных и иногда экстренных задач. Доступ к консоли предоставляет административные права по умолчанию, поэтому настоятельно рекомендуется использовать её с осторожностью и только в случае крайней необходимости.


Как отключить пайплайны для всех проектов

Project.all.find_each { |project| project.update!(builds_enabled: false) }

Как включить стандартную аутентификацию по паролю

Gitlab::CurrentSettings.update!(password_authentication_enabled_for_web: true)

Registry V1

Очистка неиспользуемых данных

Чтобы запустить очистку, сначала нужно перевести registry в режим чтения. Добавьте следующее в CodeInstance:

...
spec:
  features:
    registry:
      maintenance:
        readOnly: true
...

Теперь registry работает в режиме только для чтения (r/o), теперь получим имя одного из Pod’ов registry:

kubectl get pods -n d8-code -l app.kubernetes.io/component=registry,app.kubernetes.io/name=code -o jsonpath='{.items[0].metadata.name}'

Запустите сам процесс очистки. Ознакомьтесь с документацией registry, если хотите точно понять необходимость параметра -m.

kubectl exec -n d8-code <registry-pod> -- /bin/registry garbage-collect -m /etc/docker/registry/config.yml

Registry V2

Миграция с V1

Внимание! Эта операция не может быть отменена после запуска. Внимательно прочтите документацию.

  1. Включите режим обслуживания для container registry, установив значение spec.features.registry.maintenance.readOnly в true:

    kubectl patch codeinstance code --type=json -p="[{\"op\": \"replace\", \"path\": \"/spec/features/registry/maintenance/readOnly/enabled\", \"value\": true}]"
    
  2. Добавьте аннотацию registry-migration-in-progress=true к ресурсу CodeInstance:

    kubectl annotate codeinstance/code registry-migration-in-progress=true
    
  3. (Точка невозврата) Укажите настройки базы данных в разделе spec.features.registry.database:

    spec:
      features:
        registry:
          postgres:
            mode: External
            external:
              database: registry-database # имя базы данных для метаданных registry
              host: postgres.postgres.svc # IP-адрес или DNS-имя сервера PostgreSQL
              password: postgres # пароль для подключения к базе данных PostgreSQL
              port: 5432 # TCP-порт для подключения к базе данных PostgreSQL
              username: postgres # имя пользователя для подключения к базе данных PostgreSQL
    

    Поля host, password, port и username можно не указывать — в этом случае они будут взяты из spec.storages.postgres.external. Обязательно требуется только поле database.

  4. Дождитесь завершения reconcile. Убедитесь, что все поды в d8-code namespace находятся в готовом состоянии:

    kubectl -n d8-code get pods
    
  5. Зайдите в registry контейнер:

    kubectl -n d8-code exec -it -c registry deploy/registry -- bash
    
  6. Перейти в директорию /tmp

    cd /tmp
    
  7. Выполните приведённую ниже команду и дождитесь её завершения(внутри registry контейнера):

    registry database migrate up /etc/docker/registry/config.yml
    
  8. (Точка невозврата) После успешного завершения миграции запустите импорт(внутри registry контейнера):

    registry database import /etc/docker/registry/config.yml
    
  9. Вы можете выйти из registry контейнера.

  10. Удалите аннотацию и отключите режим обслуживания:

    kubectl annotate codeinstance/code registry-migration-in-progress-
    kubectl patch codeinstance code --type=json -p="[{\"op\": \"replace\", \"path\": \"/spec/features/registry/maintenance/readOnly/enabled\", \"value\": false}]"
    

Теперь у вас установлен Реестр V2.


Бэкапы


Автоматическое создание бэкапов перед обновлениями модуля

При получении новой версии модуля Code происходит обновление только контроллера, а все остальные компоненты остаются нетронутыми и продолжают работать до момента создания бэкапа. Обновленный оператор ожидает успешного завершения задания по созданию бэкапа.

  • Если во время запуска задания по созданию бэкапа или в самом процессе создания бэкапа возникает ошибка, оператор будет периодически проверять статус существующих заданий. В случае обнаружения успешно завершенного задания, оператор начнет разворачивать остальные компоненты.

Обновление на уровне модуля завершится с ошибкой, если оно запущено в период, когда предыдущее обновление с опцией backup.backupBeforeUpdate завершилось неудачно, а версия оператора и его компонентов различаются

Для корректной работы данного функционала требуется версия Deckhouse Kubernetes Platform не ниже 1.69

Включение автоматического создания бэкапов

Для включения автоматического создания бэкапов необходимо в спецификации CodeInstance установить значения параметров backup.enabled и backup.backupBeforeUpdate в true. Также важно, чтобы параметр backup.restoreFromBackupMode был установлен в false. Пример конфигурации:

backup:
  backupBeforeUpdate: true
  backupStorageGb: 3
  cronSchedule: 0 0 1 * *
  enabled: true

При включении опции backup.backupBeforeUpdate: true и backup.restoreFromBackupMode: true обновление модуля завершится с ошибкой

Логика работы автоматического создания бэкапов перед обновлением

  • Оператор хранит свою версию в переменной окружения pod/deployment — GITLAB_VERSION.
  • Версия компонентов GitLab проверяется вызовом API.
  1. Проверяются значения параметров backup.enabled и backup.backupBeforeUpdate. Если хотя бы одно из них не равно true, оператор пропустит создание бэкапа и начнет обновление всех своих компонентов.
  2. Получается текущая версия оператора и компонентов GitLab. Если версии не различаются, создание бэкапа пропускается.
  3. Выполняется поиск Kubernetes Job по созданию бэкапа за последний час:
    • Если ни одна задача (job) не найдена, оператор создаст новую задачу и будет следить за её статусом, ожидая успешного завершения.
    • Если в течение последнего часа найдена хотя бы одна задача со статусом Failure, оператор не будет обновлять компоненты. В Prometheus будет отправлен алерт, сигнализирующий об ошибке обновления. Алерт будет активен до тех пор, пока не будет выключена опция backup.backupBeforeUpdate или не будет найдена задача со статусом Success.
    • Если найдена задача со статусом Success, оператор перейдет к обновлению остальных компонентов.

Решение проблем при ошибке создания бэкапов

  1. Необходимо прочитать логи задачи, завершившейся со статусом Failure, чтобы найти ошибку. (Примеры возможных проблем: недостаточно места в S3-бакете для хранения бэкапов, проблемы с сетью.). Пример команды для чтения логов:

    kubectl -n d8-code logs backup-before-update-1745879676-zdzz7
    

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

  2. Поскольку оператор создает задачу для создания бэкапов только один раз, после устранения проблем с созданием бэкапов необходимо вручную пересоздать задачу, чтобы восстановить корректную работу оператора. Оператор автоматически найдет успешно завершенную задачу и продолжит работу. Пример команды:

    kubectl -n d8-code create job --from=cronjob/full-backup backup-before-update-manual-created
    

    Где:

    • backup-before-update-manual-created — имя новой задачи, которая будет запущена.

Бекапы и восстановление

Скрипт резервного копирования создает архивный файл для сохранения ваших данных.

Для создания архивного файла скрипт резервного копирования выполняет следующие действия:

  • Извлекает предыдущий архивный файл резервной копии, если вы выполняете инкрементное резервное копирование.
  • Обновляет или создает новый архивный файл резервной копии.
  • Выполняет все подзадачи резервного копирования:
    • Создает резервную копию базы данных.
    • Создает резервную копию Git-репозиториев.
    • Создает резервную копию файлов (включая S3-хранилища).
  • Архивирует подготовленную область резервного копирования в tar-файл.
  • Загружает новый архив резервной копии в объектное хранилище.
  • Очищает файлы подготовленной области резервного копирования, которые были заархивированы.

Бекапы по расписанию

В случае отсутствия поля backup.cronSchedule автоматические бекапы не будут работать. Поля является обязательным для работы автоматизированного создания бекапов

Убедитесь, что функционал бекапов включен в спецификации CodeInstance. Пример конфигурации секции описан в разделе «Настройка бекапов»

Бекапы реализованы с помощью kubernetes cronJobs (расписание cron-а также может быть настроена). Используется нативный инструмент Gitlab-а backup-utlity, а сам процесс подробно описан в официальной документации. Стоит отметить, что снятие бекапов производится с использованием ключа --repositories-server-side. что обеспечивает асинхронный бекап репозиториев непосредственно с реплик Gitaly, подробнее можно почитать в этом разделе официальной документации.

Особенности конфигурации диска

Размер диска вычисляется по формуле Gitaly node size + sum of all buckets size + database size

  • Убедитесь, что выделенного размера диска достаточно для хранения файла бекапа
  • Альтернативным вариантом будет отключение persistenceVolume для бекапов (backup.persistentVolumeClaim.enabled: false). В таком случае, следует убедиться, что на kubernetes Node, где будут запущены backup-cronjob и toolbox (для восстановления из бекапа) достаточно места на дисках

Для включения регулярных бекапов добавьте следующую секцию в CodeInstance:

backup:
  cronSchedule: 0 0 */7 * *
  enabled: true
  s3:
    bucketName: d8-code-test-backups
    external:
      provider: YCloud
      accessKey: __ACCESS_KEY__
      secretKey: __SECRET_KEY__
    mode: External
  persistentVolumeClaim:
    enabled: true # использовать ли persistentStorage при бекапе и восстановлении из бекапа
    storageClass: localpath

После правильной настройки CodeInstance нет необходимости в дополнительных шагах. Просто дождитесь, пока бекап выполнится по расписанию.

Ручные бекапы по требованию

  1. Убедитесь, что секция backup.s3.external задана иначе будут унаследованы значения из секции storages.s3.external в CodeInstance. Обязательно нужно задать поле backup.s3.bucketName
  2. Убедитесь, что значение backup.enabled равняется true
  3. Убедитесь, что необходимый компонент запущен и готов к работе
kubectl -n d8-code get pods -lapp.kubernetes.io/component=toolbox
  1. hostЗапустите утилиту бекапирования
kubectl exec -n d8-code deploy/toolbox -it -- backup-utility
  1. Бекап будет сохранен в бакете backup.s3.bucketName. Его имя будет соответствовать <timestamp>_gitlab_backup.tar формату.

Восстановление из бекапов

Для восстановления из бекапов следуйте нижеприведенной инструкции:

  1. Используйте toolbox-под и встроенную в него утиллиту backup-utlity для старта процесса восстановления: kubectl -n d8-code exec <Toolbox pod name> -it -- backup-utility --restore -t <timestamp|URL>
  • timestamp - дата из имени целевого архива бекапа
  • URL - публчиный адрес файла бекапа, удовлетворяющий file:///path формату
  1. Следуйте процессу интерактивного режима восстановления: отвечайте yes на все предложения утиллиты

Дополнительно у Вас есть возможность верифицировать целостьность выгружаемых данных из того же пода Toolbox, следуя официальной документации


Управление API-токенами

Оператор Code автоматически управляет внутренними API-токенами, используемыми для взаимодействия с GitLab API. Это включает автоматическую ротацию и мониторинг срока действия токенов.

Автоматическая ротация токенов

Оператор автоматически ротирует API-токены ежедневно. Срок действия токенов устанавливается на 37 дней, что гарантирует их обновление задолго до истечения.

Автоматически обновляются следующие токены:

Имя секрета Назначение
code-service-account Используется оператором для операций с GitLab API
code-mra-secret Используется компонентом MRA

В обычных условиях ручное вмешательство для ротации токенов не требуется.

Мониторинг

Оператор экспортирует Prometheus метрику для отслеживания срока действия токенов:

code_operator_api_token_expire_hours{token_name="code-operator-sa"}

Эта метрика показывает оставшееся количество часов до истечения срока действия токена Deckhouse SA.

Модуль включает встроенные алерты Prometheus, которые срабатывают при приближении срока истечения токена:

Алерт Условие Severity
D8CodeOperatorTokenExpireIn14Days Токен истекает менее чем через 14 дней 5
D8CodeOperatorTokenExpireIn7Days Токен истекает менее чем через 7 дней 3
D8CodeOperatorTokenExpireIn24Hours Токен истекает менее чем через 24 часа 2

Эти алерты указывают на то, что автоматическая ротация токенов может работать некорректно и требует проверки.

Устранение неполадок

При подозрении на проблемы с токенами:

  1. Проверьте логи оператора на предмет статуса ротации:

    kubectl -n d8-code logs deploy/code-operator | grep -i "token"
    
  2. Проверьте валидность токена:

    API_URL=$(kubectl -n d8-code get ingress webservice-default -o jsonpath='{.spec.rules[0].host}')
    TOKEN=$(kubectl -n d8-code get secret code-service-account -o jsonpath='{.data.api-token}' | base64 -d)
    curl -s -H "PRIVATE-TOKEN: $TOKEN" "https://$API_URL/api/v4/personal_access_tokens/self" | jq .expires_at
    
  3. Если токен просрочился, выполните следующие действия для создания нового:

    Откройте Rails-консоль с помощью Toolbox:

    kubectl -n d8-code exec -it deploy/toolbox -- gitlab-rails console -e production
    

    Создайте новый токен для сервисного аккаунта deckhouse_sa:

    user = User.find_by_username('deckhouse_sa')
    
    personal_access_token = PersonalAccessTokens::CreateService.new(
      current_user: user,
      target_user: user,
      organization_id: Organizations::Organization.default_organization.id,
      params: {
        name: 'Deckhouse service account',
        scopes: [:api, :admin_mode],
        expires_at: Time.now + 3.months
      },
    ).execute
    
    personal_access_token.payload[:personal_access_token].token
    

    Скопируйте полученный токен и обновите Kubernetes-секрет:

    token="$(echo -n "NEW_TOKEN" | base64 -w0)"
    kubectl -n d8-code patch secret code-service-account --type=json -p="[{\"op\": \"replace\", \"path\": \"/data/api-token\", \"value\": \"$token\"}]"
    

    Поскольку проверка срока действия токена выполняется раз в сутки, перезапустите оператор для немедленной проверки и сброса Prometheus-алерта:

    kubectl -n d8-code rollout restart deploy/code-operator
    

    Алерт погаснет примерно через 10 минут после запуска нового пода.