Проверьте свои развертывания Helm!

by moiseevrus

Вот очень популярный пост о безопасном развертывании диаграмм Helm, содержащих развертывания Kubernetes с автоматическими откатами. Первоначально опубликованный в 2019 году, он актуален и сегодня — если вы столкнетесь с чем-то, что следует обновить, сообщите нам об этом!

Ресурс Deployment — это де-факто способ обработки развертываний приложений в Kubernetes, но существует множество инструментов для управления ими. Один из способов безопасного управления ими — напрямую использовать kubectl, как показано в  моей предыдущей статье .

Еще один популярный способ развертывания ресурсов в Kubernetes — использование  Helm, менеджера пакетов для Kubernetes . В этой статье я расскажу о том, как повторить шаблон развертывания, продемонстрированный в предыдущем посте, с помощью Helm. Для демонстрации мы будем использовать Helm версии 2.14.2.

Пример диаграммы Helm

В Helm ресурсы Kubernetes распределяются в виде  диаграмм : коллекции шаблонных ресурсов Kubernetes в формате YAML или JSON. Диаграммы можно развернуть из внешнего репозитория Helm, файла архива диаграмм или локального каталога диаграмм. Каждая диаграмма имеет собственный набор переменных, которые можно использовать для настройки развертывания. Давайте создадим диаграмму Helm для локального каталога, которую мы можем использовать для тестирования неудачных и успешных развертываний.

$ helm create demo

Это создает простую диаграмму в каталоге  demo/, которая содержит развертывание для веб-сервера. Шаблон в пути  demo/templates/deployment.yaml создает манифест развертывания. Давайте параметризируем проверку готовности, чтобы мы могли имитировать неудачное развертывание, изменив параметр диаграммы Helm.

readinessProbe:
  httpGet:
    path: {{ .Values.readinessPath | default “/” }}
    port: http

Непроверенное развертывание

Существует два способа установки чартов Helm с помощью интерфейса командной строки Helm:  helm install и  helm upgrade --install. Подкоманда install всегда устанавливает новую диаграмму, в то время как подкоманда upgrade может обновить существующую диаграмму и установить новую, если диаграмма не была установлена ​​ранее. Благодаря функции обновления мы можем использовать одну команду для установки и обновления, что удобно для автоматизации. Давайте используем его для установки демо-чарта Helm, который мы создали ранее.

$ helm upgrade --install demo demo/
Release "demo" does not exist. Installing it now.
NAME:   demo
LAST DEPLOYED: Fri Aug 16 13:48:06 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME  READY  UP-TO-DATE  AVAILABLE   AGE
demo  0/1    1           0           1s

==> v1/Pod(related)
NAME                     READY  STATUS               RESTARTS  AGE
demo-69c7467798-84nr9    0/1    ContainerCreating    0         1s

==> v1/Service
NAME  TYPE        CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
demo  ClusterIP   10.96.196.73  <none>       80/TCP   1s

Как мы видим из вывода, диаграмма Helm была установлена, но развертывание все еще продолжается. Helm не проверил успешность нашего развертывания.

Когда мы создаем неудачное развертывание, мы должны увидеть тот же результат. Давайте намеренно прервем развертывание, изменив путь проверки готовности на то, что, как мы знаем, не работает.

$ helm upgrade --install --set readinessPath=/fail demo demo/
Release "demo" does not exist. Installing it now.
NAME:   demo
LAST DEPLOYED: Fri Aug 16 13:53:26 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME  READY  UP-TO-DATE  AVAILABLE   AGE
demo  0/1    1           0           5m

==> v1/Pod(related)
NAME                   READY  STATUS               RESTARTS  AGE
demo-54df8f97bb-ffp4b  0/1    ContainerCreating    0          0s
demo-69c7467798-84nr9  1/1    Running              0          5m
==> v1/Service
NAME  TYPE        CLUSTER-IP    EXTERNAL-IP  PORT(S)  AGE
demo  ClusterIP   10.96.196.73  <none>       80/TCP   5m

Вывод показывает, что диаграмма была «развернута», но обновленный модуль не был успешно запущен. Мы можем убедиться, что развертывание не завершилось успешно, просмотрев состояние развертывания развертывания.

$ kubectl rollout status deployment demo
Waiting for deployment "demo" rollout to finish: 1 old replicas are pending 
termination...

Однако  история развертывания диаграммы  покажет, что первое развертывание было заменено вторым.

$ helm history demo
REVISION  STATUS      DESCRIPTION
1         SUPERSEDED  Install complete
2         DEPLOYED    Upgrade complete

Давайте удалим диаграмму и начнем заново.

$ helm delete --purge demo

Подождите и тайм-аут

Кажется, что развертывание Helm chart работает аналогично тому, как  kubectl apply это работает: ресурсы создаются, но фактическое развертывание не проверяется. С kubectl мы можем использовать  kubectl rollout status его для дальнейшей проверки состояния развертывания. Так что же будет эквивалентно Helm в этом случае?

Команды установки и обновления Helm включают два параметра интерфейса командной строки, которые помогают проверять развертывания:  --wait и --timeout. При использовании  --waitHelm будет ждать, пока будет запущено минимальное ожидаемое количество модулей в развертывании, прежде чем пометить выпуск как успешный. Helm будет ждать столько, сколько установлено с помощью  --timeout. По умолчанию время ожидания установлено на 300 секунд. Давайте попробуем!

$ helm upgrade --install --wait --timeout 20 demo demo/
Release "demo" does not exist. Installing it now.
NAME:   demo
LAST DEPLOYED: Fri Aug 16 15:47:10 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME  READY  UP-TO-DATE  AVAILABLE  AGE
demo  1/1    1           1          8s

==> v1/Pod(related)
NAME                   READY  STATUS   RESTARTS  AGE
demo-69c7467798-4tkqf  1/1    Running  0         8s

==> v1/Service
NAME  TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
demo  ClusterIP  10.102.127.162  <none>       80/TCP   8s

Развертывание завершилось успешно, как и ожидалось. Давайте посмотрим, что произойдет, когда мы попробуем это с неудачным развертыванием.

$ helm upgrade --install --wait --timeout 20 --set readinessPath=/fail demo demo/
UPGRADE FAILED
Error: timed out waiting for the condition
Error: UPGRADE FAILED: timed out waiting for the condition

Очень хорошо! Наконец-то мы получили отзыв о неудачном развертывании. Мы также можем видеть это в истории диаграммы Helm.

$ helm history demo
REVISION  STATUS     DESCRIPTION
1         DEPLOYED   Install complete
2         FAILED     Upgrade "demo" failed: timed out waiting for the condition

Ручной откат

Теперь, когда у нас есть неудачное обновление, вы можете подумать, что можете просто развернуть предыдущую версию диаграммы и покончить с этим. К сожалению, это не вернет вас к рабочей версии.

$ helm upgrade --install --wait --timeout 20 demo demo/
UPGRADE FAILED
Error: timed out waiting for the condition
Error: UPGRADE FAILED: timed out waiting for the condition
$ helm history demo
REVISION  STATUS     DESCRIPTION
1         DEPLOYED   Install complete
2         FAILED     Upgrade "demo" failed: timed out waiting for the condition
3         FAILED     Upgrade "demo" failed: timed out waiting for the condition

Я не уверен, почему это так, но становится  еще хуже ! Если вы попытаетесь выпустить еще одно обновление для своей диаграммы, это также не удастся.

$ helm upgrade --install --wait --timeout 20 --set replicaCount=2 demo demo/
UPGRADE FAILED
Error: timed out waiting for the condition
Error: UPGRADE FAILED: timed out waiting for the condition

Единственный способ выйти из этой ситуации, который я могу придумать, — это полностью удалить развертывание диаграммы и начать все заново.

$ helm delete --purge demo

Вместо того, чтобы пытаться использовать команду обновления, мы можем использовать  helm rollback. Он специально разработан для развертывания версии диаграммы, которую вы развернули ранее. Чтобы использовать подкоманду отката, нам нужно предоставить ей ревизию для отката. Он также принимает те же параметры ожидания и тайм-аута, что и установка и обновление, которые мы можем использовать для проверки успешного отката. Обратите внимание, что откат нельзя использовать для выхода из описанной выше ситуации. Откатываемся на первую ревизию.

$ helm upgrade --install --wait --timeout 20 demo demo/
$ helm upgrade --install --wait --timeout 20 --set readinessPath=/fail demo demo/
$ helm rollback --wait --timeout 20 demo 1
Rollback was a success.

Потрясающий! Опять же, это должно быть видно и в истории диаграммы Helm.

$ helm history demo
REVISION  STATUS       DESCRIPTION
1         SUPERSEDED   Install complete
2         SUPERSEDED   Upgrade "demo" failed: timed out waiting for the condition
3         DEPLOYED     Rollback to 1

Автоматические откаты с атомарными

Автоматизация развертывания и отката таким образом немного громоздка, потому что вам нужно выяснить, как проанализировать последнюю успешную ревизию из истории Helm, чтобы вы могли выполнить откат. Используя  -o json опцию с командой history, вы можете получить историю в формате JSON, что должно помочь. Однако есть способ избежать всего этого.

Команды установки и обновления Helm включают  --atomic параметр CLI, который автоматически откатывает развертывание диаграммы в случае сбоя. Включение атомарной опции автоматически активирует ожидание. Давай попробуем!

$ helm upgrade --install --atomic --timeout 20 --set readinessPath=/fail demo demo/
UPGRADE FAILED
Error: timed out waiting for the condition
ROLLING BACKRollback was a success.
Error: UPGRADE FAILED: timed out waiting for the condition
$ helm history demo
REVISION  STATUS       DESCRIPTION
1         SUPERSEDED   Install complete
2         SUPERSEDED   Upgrade "demo" failed: timed out waiting for the condition
3         SUPERSEDED   Rollback to 1
4         SUPERSEDED   Upgrade "demo" failed: timed out waiting for the condition
5         DEPLOYED     Rollback to 3

Идеальный! Это также сработает, если не удастся установить диаграмму в первый раз. Если нет ревизии, к которой можно было бы вернуться, развертывание диаграммы будет удалено.

$ helm delete --purge demo
release "demo" deleted
$ helm upgrade --install --atomic --timeout 20 --set readinessPath=/fail demo demo/
Release "demo" does not exist. Installing it now.
INSTALL FAILED
PURGING CHART
Error: release demo failed: timed out waiting for the condition
Successfully purged a chart!
Error: release demo failed: timed out waiting for the condition
$ helm history demo
Error: release: "demo" not found

Неловкость в руле

Тот факт, что Helm поддерживает проверку развертываний и автоматический откат из коробки, — это здорово, но у него есть пара предостережений по сравнению с традиционными развертываниями на основе kubectl.

Во-первых, нет официальной команды для ожидания завершения развертывания, отдельной от процедуры установки и обновления, аналогичной  kubectl rollout status. Эту функцию было бы полезно иметь в ситуациях, когда вы подозреваете, что развертывание на той же диаграмме Helm может быть продолжающимся: вы можете дождаться завершения существующего развертывания, прежде чем пытаться применить ваши изменения. Однако можно обойти это предостережение, создав сценарий, который постоянно опрашивает состояние развертывания диаграммы с помощью  helm status подкоманды.

Во-вторых, время ожидания развертывания является глобальным для всех ресурсов на диаграмме. Сравните это с  функцией progressDeadlineSeconds в Deployment , которая позволяет оценить время ожидания для каждого пода. В Helm вам нужно учитывать все модули внутри развертывания за один тайм-аут. Это значительно усложняет оценку правильного времени ожидания для развертывания диаграммы. Если вы оцените его слишком низко, вы получите слишком раннее развертывание, которое завершится сбоем, даже если оно еще может развиваться. Если вы оцените его слишком высоко, развертыванию диаграммы придется долго ждать, чтобы заметить, что развертывание никуда не движется.

Вывод

В этой статье я продемонстрировал, как безопасно развертывать диаграммы Helm, содержащие развертывания Kubernetes, с автоматическим откатом. Я также говорил о неотъемлемых предостережениях в подходе Helm к мониторингу работоспособности развертывания. Одна область, которую я не рассмотрел, — это то, как безопасные развертывания обрабатываются с помощью диаграмм Helm, которые содержат ресурсы, основанные не только на ресурсе развертывания Kubernetes.

Спасибо за чтение!

You may also like

Leave a Comment