Как справиться с миграцией базы данных с помощью Kubernetes и Skaffold

Проблема:

Локально я использую Skaffold (Kubernetes) для горячей перезагрузки как клиентской, так и серверной части моего кода. Когда я выключаю его, он удаляет мой серверный модуль, включая папку /migrations/, и, таким образом, не синхронизируется с моей базой данных alembic_version. На производстве я не удаляю свой серверный модуль, но перестраиваю образ докера при развертывании, что приводит к замене моей папки /migrations/.

Вопрос

Как мне справиться с этими миграциями, чтобы моя база данных не синхронизировалась?


настройка приложения

Flask/Python API и используйте Flask Migrate. Для тех, кто не знает, что он делает, это создает папку миграции с файлами версий, такими как 5a7b1a44a69a_.py, Внутри этого файла def upgrade() а также downgrade() манипулировать БД. Он также записывает ссылки на revision и down_revision для таблицы alembic_version в моем модуле postgres.

Настройка Kubernetes и Docker

У меня есть серверный модуль и модуль postgres. Я вхожу в оболочку модуля сервера для запуска команд переноса. Он создает файлы версий внутри контейнера Docker и обновляет базу данных.

Чтобы показать пошаговый пример проблемы:

  1. Зайдите в модуль развертывания сервера и запустите db init.
  2. Папка Migrations создана.
  3. выполнить миграцию на сервере-развертывании, который создает файл миграции и обновляет базу данных.
  4. postgres pod db получает вход alembic_version и обновление.
  5. используйте skaffold delete или ctrl-c skaffold.
  6. Модуль развертывания сервера удаляется, а postgres - нет. Папка миграций уходит.
  7. Запустите резервную копию skaffold и sh в модуль развертывания сервера и попробуйте запустить db migrate. Просит вас сделать DB инициации.
  8. Если вы попытаетесь понизить рейтинг отсюда, это ничего не даст. Теперь серверный модуль и модуль postgres не синхронизированы с точки зрения alembic_version.

Заключительные заметки

То, что я использовал для pre-docker/kubernetes, было запускать его локально, и я передал этот файл версии миграции в мое хранилище. Он был синхронизирован во всех средах, поэтому репо каждого было на одной и той же версии alembic. Я рассмотрел создание отдельного, всегда включенного модуля "миграция-развертывание", который является еще одним экземпляром фляги, чтобы он никогда не терял папку /migrations/. Однако это кажется очень плохим решением.


Надеемся на лучшие практики или идеи!

1 ответ

Решение

Я нашел способ справиться с этим. Я не собираюсь устанавливать его как правильный ответ, пока кто-то еще не подтвердит, если это хороший подход.

По сути, я создал постоянную заявку на объем. В развертывании сервера я подключаю миграцию / папку к этому постоянному тому. Таким образом, всякий раз, когда модуль удаляется, папка миграций / остается и сохраняется после перезапуска модуля.

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

      containers:
      ..........
        volumeMounts:
          - name: migrationstuff
            mountPath: 'MyServerApplicationDirectory/migrations'
      volumes:
        - name: migrationstuff
          persistentVolumeClaim:
            claimName: migrate-pvc

ПВХ будет выглядеть так:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: migrate-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Для тех, кто решает использовать этот подход с миграцией колб, есть сложная проблема "курица или яйцо". Когда вы запускаете flask db init, он создает папку migrations / с некоторыми элементами в ней. Тем не менее, если существует PVC, создающий пустую миграцию / папку, миграция фляги уже думает, что папка существует. Вы также не можете удалить папку с помощью rmdir, потому что на ней есть рабочий процесс. Тем не менее, вам нужно получить содержимое команды инициализации флакона migrate в пустую папку migrations /.....

Уловка, которую я нашел, была:

python flask db init --directory migration
mv migration/* migrations/

Это запустило все нужные файлы в новую папку "миграции". Затем вы копируете все это в папку migrations /, чтобы затем сохранить ее. Flask migrate автоматически ищет эту папку, если вы пропустите флаг --directory.

Затем удалите папку миграции rmdir migration(или просто подождите, пока ваш модуль перезапустится, и в любом случае он исчезнет).

Теперь у вас есть правильная папка миграций / со всем в ней. Когда вы закрываете свою колбу и перезагружаетесь, PVC вводит заполненную миграцию / папку обратно в коробку. Теперь я могу обновить / понизить. Просто нужно быть осторожным, чтобы не удалить ПВХ!

Другие вопросы по тегам