Горизонтальное автомасштабирование Pod (HPA) с initContainer, для которого требуется задание.

avatar
Jordan Lewallen
9 августа 2021 в 04:42
260
1
4

У меня есть конкретный сценарий, в котором я хочу, чтобы развертывание контролировалось автоматическим масштабированием горизонтального модуля. Чтобы выполнить миграцию базы данных в модулях при отправке нового развертывания, я следовал отличному руководству Эндрю Лока здесь.

.

Короче говоря, вы должны определить initContainer, который waits для Kubernetes Job, чтобы завершить процесс (например, выполнить миграцию БД) до того, как новые модули смогут запуститься.

Это работает хорошо, однако я не знаю, как обращаться с HPA после первоначального развертывания, потому что, если система обнаружит необходимость добавить еще один Pod в мой узел, для initContainer, определенного в моем развертывании, потребуется Job для развертывания и запуска, но поскольку Jobs являются одноразовыми процессами, модуль не может инициализироваться и работать должным образом (атрибут ttlSecondsAfterFinished в любом случае удаляет Job).

Как мне определить initContainer для запуска при развертывании моего приложения, чтобы я мог выполнять миграцию моей базы данных в Job, а также разрешить HPA контролировать динамическое добавление Pod без необходимости initContainer?

Вот как выглядит мой deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: graphql-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: graphql-pod
  template:
    metadata:
      labels:
        app: graphql-pod
    spec:
      initContainers:
        - name: wait-for-graphql-migration-job
          image: groundnuty/k8s-wait-for:v1.4 # This is an image that waits for a process to complete
          args:
            - job
            - graphql-migration-job # this job is defined next
      containers:
        - name: graphql-container
          image: image(graphql):tag(graphql)

Также развернуто следующее Job

apiVersion: batch/v1
kind: Job
metadata:
  name: graphql-migration-job
spec:
  ttlSecondsAfterFinished: 30
  template:
    spec:
      containers:
      - name: graphql-migration-container
        image: image(graphql):tag(graphql)
        command: ["npm", "run", "migrate:reset"]
      restartPolicy: Never

Итак, в основном происходит следующее:

  • Я развертываю эти два ресурса на своем узле
  • Job инициализируется
  • initContainer на Pod ожидает завершения Job с использованием образа с именем groundnuty/k8s-wait-for:v1.4
  • Job завершает
  • initContainer завершает
  • Pod инициализирует
  • (через 30 секунд TTL) Job удаляется с узла

(МНОГО ДВИЖЕНИЯ)

  • HPA осознает потребность в другом модуле
  • initContainer для НОВОГО модуля запущен, но не может быть запущен, поскольку Job не существует
  • ...crashLoopBackOff

Было бы интересно узнать, как правильно справиться с этим сценарием!

Источник
papanito
9 августа 2021 в 05:16
0

Требуется ли запускать задание для каждого нового модуля или это только одна вещь?

Jordan Lewallen
9 августа 2021 в 05:28
0

@papanito хороший вопрос, важно запустить задание только при первоначальном развертывании. Кроме этого, нет, задание просто запускает мой сценарий миграции БД, который не нужно запускать при горизонтальном автомасштабировании. Полезная функция initContainer и wait-for заключается в том, что он не запускает ни один из новых модулей до тех пор, пока задание не будет завершено, а затем масштабирует новые модули и удаляет старые, чтобы не было времени простоя.

Ответы (1)

avatar
Lukas Eichler
11 августа 2021 в 08:28
4

К сожалению, простой функции Kubernetes для решения вашей проблемы не существует.

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

Для этого существует множество способов:

  • Сначала создайте сценарий bash и т. д. для выполнения задания, подождите, а затем обновите развертывание
  • Используйте более сложные инструменты развертывания, такие как Helm, которые позволяют вам добавить 'предварительную установку' к вашему заданию, чтобы выполнять их при развертывании вашего приложения
Jordan Lewallen
11 августа 2021 в 17:38
0

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