Как справиться с миграцией базы данных с помощью 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 и обновляет базу данных.
Чтобы показать пошаговый пример проблемы:
- Зайдите в модуль развертывания сервера и запустите db init.
- Папка Migrations создана.
- выполнить миграцию на сервере-развертывании, который создает файл миграции и обновляет базу данных.
- postgres pod db получает вход alembic_version и обновление.
- используйте skaffold delete или ctrl-c skaffold.
- Модуль развертывания сервера удаляется, а postgres - нет. Папка миграций уходит.
- Запустите резервную копию skaffold и sh в модуль развертывания сервера и попробуйте запустить db migrate. Просит вас сделать DB инициации.
- Если вы попытаетесь понизить рейтинг отсюда, это ничего не даст. Теперь серверный модуль и модуль 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 вводит заполненную миграцию / папку обратно в коробку. Теперь я могу обновить / понизить. Просто нужно быть осторожным, чтобы не удалить ПВХ!