Запланировать задание, используя тот же PVC, что и 1 другой модуль в StatefulSet

В кластере Kubernetes я хотел бы иметь возможность запланировать задание (с помощью CronJob), которое будет монтировать те же тома, что и 1 Pod данного StatefulSet. Решение о том, какой именно модуль будет выполняться, зависит от меток, установленных на модуле во время планирования задания.

Думаю, многие люди задаются вопросом, почему, поэтому описание того, что мы делаем и пытаемся сделать:

Текущая настройка

У нас есть StatefulSet, который обслуживает базу данных PostgreSQL. (одна основная, несколько реплик) Мы хотим иметь возможность создавать резервную копию из одного из модулей StatefulSet.

Для PostgreSQL мы уже можем делать резервные копии по сети с pg_basebackup, однако мы используем базы данных PostgreSQL с несколькими ТБ, что означает, что полное потоковое резервное копирование (с pg_basebackup) невозможно.

В настоящее время мы используем pgBackRest для резервного копирования баз данных, что позволяет создавать инкрементные резервные копии.

Поскольку для инкрементного резервного копирования pgBackRest требуется доступ к тому данных и тому WAL, нам нужно запустить контейнер резервного копирования на том же узле Kubernetes, что и экземпляр PostgreSQL, в настоящее время мы даже запускаем его внутри того же модуля в отдельном контейнере.

Внутри контейнера небольшой api оборачивается вокруг pgBackRest и может быть запущен путем отправки POST запросов к api, этот запуск в настоящее время выполняется с помощью CronJobs.

Минусы

  • Каждый экземпляр PostgreSQL имеет несколько контейнеров в модуле: 1 для обслуживания Postgres, 1 для обслуживания крошечной оболочки вокруг pgBackRest
  • Журналы заданий показывают только успешные триггеры резервного копирования, фактические журналы резервного копирования являются частью контейнера резервного копирования.
  • Pod, который будет запускать резервное копирование, может работать в относительно старой конфигурации, изменение конфигурации резервного копирования требует перепланирования Pod, что может означать отказоустойчивость основного PostgreSQL.

Предлагаемая установка

Сделайте CronJob графиком для модуля, имеющего тот же том, что и у 1 из модулей StatefulSet. Это позволит резервной копии использовать эти тома.

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

В настоящее время это невозможно, так как в спецификации CronJob я не могу найти способ использовать информацию из k8s api.

Что работает, но не очень приятно:

  • Используйте CronJob, который планирует задание
  • Это задание запрашивает API k8s и планирует другое задание

Например, вот что мы можем сделать, чтобы задание создавало другое задание, используя эту информацию времени выполнения:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: schedule-backup
spec:
  schedule: "13 03 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup-trigger
            image: bitnami/kubectl
            command:
            - sh
            - -c
            - |
              PRIMARYPOD=$(kubectl get pods -l cluster-name=<NAME>,role=master -o custom-columns=":metadata.name" --no-headers)
              kubectl apply -f - <<__JOB__
                apiVersion: batch/v1
                kind: Job
                metadata:
                  name: test
                spec:
                  volumes:
                    name: storage-volume
                    persistentVolumeClaim:
                      claimName:
                        data-volume-${PRIMARYPOD}
                  [...]
              __JOB__

Вышеупомянутое может быть лучше всего обслужено оператором, а не просто CronJob, но мне интересно, есть ли у кого-нибудь решение для вышеперечисленного.

Минусы

  • В журналах заданий отображаются только успешные триггеры резервного копирования, фактические журналы резервного копирования являются частью другого задания.
  • Для задания требуются разрешения для планирования работы Pod, что требует еще одной роли / привязки ролей.
  • Использование heredocs в Bash затрудняет чтение / синтаксический анализ / понимание

Резюме

Долгая история, но мы хотим удовлетворить следующие ограничения:

  • Запустить резервную копию базы данных PostgreSQL
  • Это базы данных на несколько ТБ
  • Следовательно, требуется инкрементное резервное копирование.
  • Следовательно, нам нужно смонтировать тот же PV уже запущенного Pod'а.
  • Следовательно, нам нужно запустить Pod (или контейнер) на том же узле K8s, что и PV.
  • Мы хотим иметь возможность выразить это в спецификации CronJob, вместо того, чтобы выполнять вызовы api kubernetes во время выполнения.

person Feike Steenbergen    schedule 02.01.2020    source источник


Ответы (1)


Ну, простой и короткий ответ будет: как правило, нельзя.

Но давайте пока проявим изобретательность :)

Очень ограниченное количество бэкэндов хранилища поддерживает доступ RWX (чтение и запись много), и в большинстве случаев это более медленные, которых вы хотите избежать при использовании для базы данных. Это означает, что до тех пор, пока вы не запустите свою резервную оболочку в качестве сопутствующего элемента (что вы делаете сейчас), вы не сможете получить доступ к PV в другом POD, точка.

Я бы, вероятно, придерживался вашего исходного подхода с некоторыми настройками (например, убедитесь, что вы никогда не отключите основной из-за изменения резервной копии / конфигурации).

На обновленном кластере K8S и поддерживаемом провайдере инфраструктуры вы, вероятно, могли бы изучить VolumeSnapshots для резервного копирования на основе моментальных снимков и потенциального использования моментального снимка в качестве источника для запуска задания инкрементного резервного копирования. Хотя звучит немного запутанно.

Вы также можете запустить выделенный модуль реплик postgres для резервного копирования с ограниченными ресурсами (без реального трафика) и встроить логику резервного копирования только в этот модуль.

person Radek 'Goblin' Pieczonka    schedule 02.01.2020
comment
Спасибо, я надеюсь, что VolumeSnapshots станет очень полезным в будущем. Ваше предложение об отдельном модуле только для резервного копирования также кажется очень ценным! - person Feike Steenbergen; 06.01.2020