Распределение развертываний Kubernetes и миграция баз данных

При обработке скользящего обновления с миграциями базы данных, как это делают кубернеты?

Для экземпляра - у меня есть приложение, которое обновляется с приложения-v1 до app-v2, которое включает в себя шаг перехода для изменения существующей таблицы. Таким образом, это означает, что мне требуется запустить что-то вроде db:migrate для приложения rails после его развертывания.

Когда развертывание развертки происходит на 3 набора реплик. Он будет развертываться с одного модуля на другой. Потенциально разрешая POD, у которых нет новой версии приложения для разрыва.

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

Ответ 1

Один из способов предотвратить взлома старой версии - это разделить миграцию на несколько этапов.

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

  • Добавьте миграцию db, которая вставляет новый столбец
  • Измените приложение, чтобы все записи переходили в старый и новый столбцы
  • Запустите задачу, которая копирует все значения из старого в новый столбец
  • Измените приложение, которое оно читает из нового столбца
  • Добавьте миграцию, которая удаляет старый столбец

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

Ответ 2

Kubernetes НЕ изначально обрабатывает обновления с миграциями db. Это приложение специфично, поэтому разработчику приложения придется его обрабатывать. Возможно, вам придется делать то же самое, что и в настройке, отличной от k8s.

Во всяком случае, я бы это сделал:

  • Увеличьте свои реплики до 1.
  • Обновите изображение.
  • Увеличьте свои реплики до 3.

Это не безупречно, но не связано с изменением кода. Существует небольшое окно между шагом db: migrate и фактическим прослушиванием сервера, где запрос будет отправлен на более раннюю реплику (которая будет завершена, как только новая реплика будет готова). Этот запрос может или не может провалиться в зависимости от того, непосредственно ли код кода связан с изменением схемы.

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

Ответ 3

Я недавно решал этот вопрос, и вот мой путь:

  • Используйте аннотации развертывания для хранения команд, которые обычно нужно запускать до или после развертывания.
  • Создайте скрипт, который сможет прочитать ваше развертывание по имени и затем создать задание для запуска команд, указанных в аннотациях развертывания.
  • При нажатии изображения на реестр докеров добавьте веб-чек, который вызовет ваш скрипт, указанный в предыдущей точке.
  • Чтобы избежать проблем с несовместимой структурой БД:
    • Не изменяйте столбцы db несовместимым образом.
    • Не удаляйте неиспользуемые столбцы сразу же в своих миграциях. Вы можете сделать это в следующем выпуске. Таким образом, у вас будет только один сценарий миграции, который вы будете запускать до развертывания.

PS Чтобы иметь возможность работать с Kubernetes в вашем скрипте, вы можете ознакомиться с этими ссылками: API Kubernetes, Обзор API Kubernetes, Кластеры доступа с использованием API Kubernetes, Библиотеки клиентов.