Вот очень популярный пост о безопасном развертывании диаграмм Helm, содержащих развертывания Kubernetes с автоматическими откатами. Первоначально опубликованный в 2019 году, он актуален и сегодня — если вы столкнетесь с чем-то, что следует обновить, сообщите нам об этом!
—
Ресурс Deployment — это де-факто способ обработки развертываний приложений в Kubernetes, но существует множество инструментов для управления ими. Один из способов безопасного управления ими — напрямую использовать kubectl, как показано в моей предыдущей статье .
Еще один популярный способ развертывания ресурсов в Kubernetes — использование Helm, менеджера пакетов для Kubernetes . В этой статье я расскажу о том, как повторить шаблон развертывания, продемонстрированный в предыдущем посте, с помощью Helm. Для демонстрации мы будем использовать Helm версии 2.14.2.
Contents
Пример диаграммы 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
. При использовании --wait
Helm будет ждать, пока будет запущено минимальное ожидаемое количество модулей в развертывании, прежде чем пометить выпуск как успешный. 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.
Спасибо за чтение!