Застарілі 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, що передує цій поточній версії".
  2. Якщо ви знайшли будь-яку версію API, яка була видалена у версії Kubernetes, то:

    • Якщо ви використовуєте версію Kubernetes, де ці версії API все ще доступні (наприклад, ви використовуєте Kubernetes 1.15 і виявили, що використовуєте API, які будуть видалені у Kubernetes 1.16):
      • Дотримуйтесь процедури, описаної у пункті 1.
    • Інакше (наприклад, ви вже використовуєте версію Kubernetes, де деякі версії API, зазначені у helm get manifest, більше не доступні):
      • Вам потрібно відредагувати маніфест релізу, який зберігається в кластері, щоб оновити версії API до підтримуваних. Див. Оновлення версій API маніфесту релізу для отримання додаткової інформації.

Примітка: У всіх випадках оновлення релізу 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 не вдається виконати оновлення в такому випадку, оскільки він намагається створити патч відмінностей між поточним розгорнутим релізом (який містить версії API Kubernetes, що були видалені в цій версії Kubernetes) та чартом, який ви передаєте з оновленими/підтримуваними версіями API. Основна причина невдачі полягає в тому, що коли Kubernetes видаляє версію API, клієнтська бібліотека Go для Kubernetes більше не може аналізувати застарілі обʼєкти, і тому Helm зазнає невдачі при виклику бібліотеки. На жаль, Helm не в змозі відновитися з такої ситуації та більше не може керувати таким релізом. Див. Оновлення версій API маніфесту релізу для отримання додаткової інформації про те, як відновитися з такої ситуації.

Оновлення версій API маніфесту релізу

Маніфест є властивістю обʼєкта релізу Helm, який зберігається в полі data в Secret (стандартно) або ConfigMap у кластері. Поле data містить обʼєкт у стиснутому вигляді, закодований у base64 (існує додаткове кодування base64 для Secret). Для кожної версії/ревізії релізу існує свій 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, що передує цій поточній версії".