Перейти к основному содержимому
Версия: 3.19.0

Устаревшие API Kubernetes

Kubernetes — это система, управляемая через API, и этот API развивается со временем, отражая всё более глубокое понимание предметной области. Это обычная практика для систем и их API. Важная часть развития API — это грамотная политика устаревания и процесс информирования пользователей об изменениях в API. Иными словами, пользователи вашего API должны заранее знать, в каком релизе API будет удалён или изменён. Это устраняет неожиданности и предотвращает критические изменения для пользователей.

Политика устаревания Kubernetes описывает, как Kubernetes обрабатывает изменения версий API. Политика определяет сроки поддержки версий API после объявления об их устаревании. Поэтому важно следить за объявлениями об устаревании и знать, когда версии API будут удалены, чтобы минимизировать последствия.

Вот пример объявления об удалении устаревших версий API в Kubernetes 1.16, которое было опубликовано за несколько месяцев до выхода релиза. Эти версии API были объявлены устаревшими ещё раньше. Это показывает, что существует грамотная политика информирования пользователей о поддержке версий API.

Шаблоны Helm указывают группу API Kubernetes при определении объекта Kubernetes, аналогично файлу манифеста Kubernetes. Группа указывается в поле apiVersion шаблона и идентифицирует версию API объекта Kubernetes. Это означает, что пользователи Helm и мейнтейнеры чартов должны знать, когда версии API Kubernetes устарели и в какой версии Kubernetes они будут удалены.

Мейнтейнеры чартов

Вам следует проверить свои чарты на наличие версий API Kubernetes, которые устарели или удалены в определённой версии Kubernetes. Найденные версии API, которые скоро перестанут поддерживаться или уже не поддерживаются, следует обновить до поддерживаемой версии и выпустить новую версию чарта. Версия API определяется полями kind и apiVersion. Например, вот удалённая версия API объекта Deployment в Kubernetes 1.16:

apiVersion: apps/v1beta1
kind: Deployment

Пользователи Helm

Вам следует проверить используемые чарты (аналогично мейнтейнерам чартов) и выявить те, где версии API устарели или удалены в определённой версии Kubernetes. Для выявленных чартов вам нужно найти последнюю версию чарта (с поддерживаемыми версиями API) или обновить чарт самостоятельно.

Кроме того, вам необходимо проверить все развёрнутые чарты (то есть релизы Helm), также проверяя наличие устаревших или удалённых версий API. Это можно сделать, получив информацию о релизе с помощью команды helm get manifest.

Способ обновления релиза Helm до поддерживаемых API зависит от результатов проверки:

  1. Если вы обнаружили только устаревшие версии API:
  • Выполните helm upgrade с версией чарта, содержащей поддерживаемые версии API Kubernetes
  • Добавьте описание при обновлении, примерно следующего содержания: не выполнять откат к версии Helm, предшествующей текущей
  1. Если вы обнаружили версии API, удалённые в определённой версии Kubernetes:
  • Если вы используете версию Kubernetes, где эти версии API ещё доступны (например, вы на Kubernetes 1.15 и обнаружили API, которые будут удалены в Kubernetes 1.16):
    • Следуйте процедуре из пункта 1
  • В противном случае (например, вы уже используете версию Kubernetes, где некоторые версии API, отображаемые helm get manifest, более недоступны):

Примечание: Во всех случаях обновления релиза Helm до поддерживаемых API никогда не выполняйте откат релиза к версии, предшествующей версии с поддерживаемыми API.

Рекомендация: Лучшая практика — обновлять релизы с устаревшими версиями API до поддерживаемых версий API до обновления кластера Kubernetes, в котором эти версии API будут удалены.

Если вы не обновите релиз, как было предложено выше, вы получите ошибку, похожую на следующую, при попытке обновить релиз в версии Kubernetes, где его версии API удалены:

Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s)
for this kubernetes version and it is therefore unable to build the kubernetes
objects for performing the diff. error from kubernetes: unable to recognize "":
no matches for kind "Deployment" in version "apps/v1beta1"

Helm завершается с ошибкой в этом сценарии, потому что пытается создать diff-патч между текущим развёрнутым релизом (содержащим версии API Kubernetes, удалённые в этой версии Kubernetes) и чартом, который вы передаёте с обновлёнными/поддерживаемыми версиями API. Основная причина ошибки в том, что когда Kubernetes удаляет версию API, клиентская библиотека Kubernetes Go больше не может разбирать устаревшие объекты, и Helm завершается с ошибкой при вызове библиотеки. К сожалению, Helm не может восстановиться после этой ситуации и больше не может управлять таким релизом. Подробнее о том, как восстановиться после этого сценария, см. Обновление версий API в манифесте релиза.

Обновление версий API в манифесте релиза

Манифест — это свойство объекта релиза Helm, которое хранится в поле data Secret (по умолчанию) или ConfigMap в кластере. Поле data содержит сжатый gzip объект, закодированный в base64 (для Secret применяется дополнительное кодирование base64). Для каждой версии/ревизии релиза существует отдельный Secret/ConfigMap в пространстве имён релиза.

Вы можете использовать плагин Helm mapkubeapis для обновления релиза до поддерживаемых API. Подробности см. в readme плагина.

Альтернативно вы можете выполнить следующие ручные шаги для обновления версий API в манифесте релиза. В зависимости от вашей конфигурации следуйте шагам для Secret или ConfigMap.

  • Получите имя Secret или ConfigMap, связанного с последним развёрнутым релизом:
    • Для Secret: kubectl get secret -l owner=helm,status=deployed,name=<release_name> --namespace <release_namespace> | awk '{print $1}' | grep -v NAME
    • Для ConfigMap: kubectl get configmap -l owner=helm,status=deployed,name=<release_name> --namespace <release_namespace> | awk '{print $1}' | grep -v NAME
  • Получите данные последнего развёрнутого релиза:
    • Для Secret: kubectl get secret <release_secret_name> -n <release_namespace> -o yaml > release.yaml
    • Для ConfigMap: kubectl get configmap <release_configmap_name> -n <release_namespace> -o yaml > release.yaml
  • Создайте резервную копию релиза на случай, если что-то пойдёт не так:
    • cp release.yaml release.bak
    • В случае проблем восстановите: kubectl apply -f release.bak -n <release_namespace>
  • Декодируйте объект релиза:
    • Для Secret: cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d | base64 -d | gzip -d > release.data.decoded
    • Для ConfigMap: cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d | gzip -d > release.data.decoded
  • Измените версии API в манифестах. Можно использовать любой инструмент (например, редактор) для внесения изменений. Это находится в поле manifest вашего декодированного объекта релиза (release.data.decoded)
  • Закодируйте объект релиза:
    • Для Secret: cat release.data.decoded | gzip | base64 | base64
    • Для ConfigMap: cat release.data.decoded | gzip | base64
  • Замените значение свойства data.release в файле развёрнутого релиза (release.yaml) на новый закодированный объект релиза
  • Примените файл к пространству имён: kubectl apply -f release.yaml -n <release_namespace>
  • Выполните helm upgrade с версией чарта, содержащей поддерживаемые версии API Kubernetes
  • Добавьте описание при обновлении, примерно следующего содержания: не выполнять откат к версии Helm, предшествующей текущей