Зміни з часів Helm 2

Зміни з часів Helm 2

Ось вичерпний список усіх основних змін, введених у Helm 3.

Видалення Tiller

Під час циклу розробки Helm 2 ми впровадили Tiller. Tiller відігравав важливу роль для команд, що працюють на спільному кластері — він дозволяв кільком різним операторам взаємодіяти з одним і тим же набором релізів.

З увімкненим контролем доступу на основі ролей (RBAC) у Kubernetes 1.6, контроль доступу до Tiller у випадках операційної діяльності став важчим у керуванні. Через велику кількість можливих політик безпеки наше ставлення полягало в тому, щоб забезпечити стандартну дозвільну конфігурацію. Це дозволяло новачкам почати експериментувати з Helm і Kubernetes без необхідності заглиблюватися в керування безпекою. На жаль, ця дозвільна конфігурація могла надавати користувачеві широкий спектр дозволів, які йому не були надані. DevOps і SRE доводилося вивчати додаткові оперативні кроки при встановленні Tiller в мультиорендний кластер.

Після того як ми дізналися, як члени спільноти використовують Helm у певних сценаріях, ми виявили, що система управління релізами Tiller не має покладатися на оператора в кластері для підтримки стану або дії як центральний центр інформації про релізи Helm. Натомість ми могли просто отримувати інформацію з сервера API Kubernetes, рендерити чарти на стороні клієнта і зберігати запис про установку в Kubernetes.

Основна мета Tiller могла бути досягнута без Tiller, тому одне з перших рішень, яке ми прийняли щодо Helm 3, полягало в повному видаленні Tiller.

З відсутністю Tiller модель безпеки Helm радикально спростилася. Helm 3 тепер підтримує всі сучасні функції безпеки, ідентифікації та авторизації сучасного Kubernetes. Дозволи Helm оцінюються за допомогою вашого файлу kubeconfig. Адміністратори кластерів можуть обмежити дозволи користувачів на будь-якому рівні деталізації, який вони вважають за потрібний. Релізи все ще записуються в кластері, а решта функціональності Helm залишається.

Поліпшена стратегія оновлення: 3-сторонні стратегічні зливання патчів

Helm 2 використовував двостороннє стратегічне злиття патчів. Під час оновлення він порівнював маніфест останньої версії чарту з маніфестом запропонованого чарту (той, що надається під час helm upgrade). Він порівнював різницю між цими двома чартами, щоб визначити, які зміни потрібно застосувати до ресурсів у Kubernetes. Якщо зміни були внесені до кластера поза планом (наприклад, під час kubectl edit), ці зміни не враховувалися. Це призводило до того, що ресурси не могли повернутися до попереднього стану: оскільки Helm розглядав тільки останній застосований маніфест чарту як поточний стан, якщо у стані чарту не було змін, поточний стан залишався незмінним.

У Helm 3 тепер використовується тристороннє стратегічне злиття патчів. Helm враховує старий маніфест, його поточний стан і новий маніфест при генерації патчу.

Приклади

Розглянемо кілька поширених прикладів того, на що впливають ці зміни.

Повернення до попереднього стану, де поточний стан змінився

Ваша команда щойно розгорнула свій застосунок для операційної діяльності на Kubernetes за допомогою Helm. Чарт містить обʼєкт Deployment, де кількість реплік встановлено на три:

$ helm install myapp ./myapp

Новий розробник приєднується до команди. В перший день, спостерігаючи за операційним кластером, трапляється жахлива аварія, коли кава проливається на клавіатуру, в наслідок чого kubectl scale згортає deployment з трьох реплік до нуля.

$ kubectl scale --replicas=0 deployment/myapp

Ще один розробник у вашій команді помічає, що операційний сайт не працює, і вирішує повернути реліз до попереднього стану:

$ helm rollback myapp

Що відбувається?

У Helm 2 буде згенеровано патч, порівнюючи старий маніфест з новим маніфестом. Оскільки це повернення, це той самий маніфест. Helm визначає, що немає нічого для зміни, оскільки немає різниці між старим і новим маніфестом. Кількість реплік продовжує залишатися на нулі. Паніка зростає.

У Helm 3 патч генерується з використанням старого маніфесту, поточного стану і нового маніфесту. Helm визнає, що старий стан був на трьох, поточний стан — на нулі, а новий маніфест хоче змінити його назад на три, тому він генерує патч, щоб змінити стан назад на три екземпляри.

Оновлення, де поточний стан змінився

Багато сервісних мереж та інших застосунків на основі контролерів вбудовують дані в обʼєкти Kubernetes. Це може бути щось на кшталт sidecar, міток або іншої інформації. Раніше, якщо у вас був даний маніфест, створений з чарту:

containers:
- name: server
  image: nginx:2.0.0

А поточний стан був змінений іншим застосунком на

containers:
- name: server
  image: nginx:2.0.0
- name: my-injected-sidecar
  image: my-cool-mesh:1.0.0

Тепер ви хочете оновити теґ образу nginx до 2.1.0. Отже, ви оновлюєте чарт до маніфесту:

containers:
- name: server
  image: nginx:2.1.0

Що відбувається?

У Helm 2 Helm генерує патч обʼєкта containers між старим маніфестом і новим маніфестом. Поточний стан кластера не враховується під час генерації патчу.

Поточний стан кластера модифікується, щоб виглядати наступним чином:

containers:
- name: server
  image: nginx:2.1.0
- name: my-injected-sidecar
  image: my-cool-mesh:1.0.0

Виникає більше паніки.

У Helm 3 Helm генерує патч обʼєкта containers між старим маніфестом, поточним станом і новим маніфестом. Він помічає, що новий маніфест змінює теґ образу на 2.1.0, але поточний стан містить контейнер sidecar.

Поточний стан кластера модифікується, щоб виглядати наступним чином:

containers:
- name: server
  image: nginx:2.1.0
- name: my-injected-sidecar
  image: my-cool-mesh:1.0.0

Імена релізів тепер обмежені простором імен

З видаленням Tiller інформація про кожен реліз повинна була десь зберігатися. У Helm 2 вона зберігалась в тому ж просторі імен, що й Tiller. Це означало, що після використання імені для одного релізу жоден інший реліз не міг використовувати те ж саме імʼя, навіть якщо він був розгорнутий в іншому просторі імен.

У Helm 3 інформація про конкретний реліз тепер зберігається в тому ж просторі імен, що і сам реліз. Це означає, що користувачі тепер можуть робити helm install wordpress stable/wordpress у двох окремих просторах імен, і кожен з них можна буде переглядати за допомогою helm list, змінивши контекст простору імен (наприклад, helm list --namespace foo).

З цим більшим узгодженням з нативними просторами імен кластера команда helm list більше не стандартно виводить перелік всіх релізів. Натомість вона буде виводити лише релізи в просторі імен вашого поточного контексту Kubernetes (тобто простір імен, що відображається, коли ви виконуєте kubectl config view --minify). Це також означає, що ви повинні вказати прапорець --all-namespaces для helm list, щоб отримати поведінку, подібну до Helm 2.

Secrets як стандартний драйвер зберігання

У Helm 3 Secrets тепер використовуються як стандартний драйвер зберігання. Helm 2 стандартно використовував ConfigMaps для зберігання інформації про релізи. У Helm 2.7.0 було впроваджено новий бекенд зберігання, що використовує Secrets для зберігання інформації про релізи, і тепер це є стандартним починаючи з Helm 3.

Перехід на Secrets як стандарт для Helm 3 забезпечує додаткову безпеку у захисті чарту разом з випуском шифрування Secrets у Kubernetes.

Шифрування секретів в спокої стало доступним як альфа функція в Kubernetes 1.7 і стало стабільним починаючи з Kubernetes 1.13. Це дозволяє користувачам шифрувати метадані релізів Helm в спокої, і це є хорошою відправною точкою, яку можна пізніше розширити на використання чогось на кшталт Vault.

Зміни в шляху Go import

У Helm 3 шлях імпорту Go був змінений з k8s.io/helm на helm.sh/helm/v3. Якщо ви плануєте оновити бібліотеки клієнтів Go для Helm 3, переконайтеся, що змінюєте свої шляхи імпорту.

Можливості

Вбудований обʼєкт .Capabilities, доступний під час етапу рендерингу, був спрощений.

Вбудовані Обʼєкти

Перевірка значень чарту з JSONSchema

Тепер можна накласти JSON Schema на значення чарту. Це забезпечує, що значення, надані користувачем, відповідають схемі, визначеній автором чарту, що забезпечує кращу звітність про помилки, коли користувач надає неправильний набір значень для чарту.

Перевірка відбувається при виконанні будь-якої з наступних команд:

  • helm install
  • helm upgrade
  • helm template
  • helm lint

Дивіться документацію про Файли схем для додаткової інформації.

Консолідація requirements.yaml в Chart.yaml

Система управління залежностями чартів перейшла з requirements.yaml та requirements.lock у Chart.yaml та Chart.lock. Рекомендується, щоб нові чарти для Helm 3 використовували новий формат. Тим не менш, Helm 3 все ще розуміє API версію 1 (v1) і буде завантажувати наявні файли requirements.yaml.

У Helm 2 файл requirements.yaml виглядав так:

dependencies:
- name: mariadb
  version: 5.x.x
  repository: https://charts.helm.sh/stable
  condition: mariadb.enabled
  tags:
    - database

У Helm 3 залежність виражена так само, але тепер у вашому Chart.yaml:

dependencies:
- name: mariadb
  version: 5.x.x
  repository: https://charts.helm.sh/stable
  condition: mariadb.enabled
  tags:
    - database

Чарти все ще завантажуються і розміщуються в теці charts/, тому субчарти, які знаходяться в теці charts/, будуть продовжувати працювати без змін.

Імʼя (або --generate-name) тепер необхідне при встановленні

У Helm 2, якщо імʼя не було надане, імʼя автоматично генерувалося. В операційній експлуатації це виявилося більше проблемою, ніж корисною функцією. У Helm 3 Helm видасть помилку, якщо імʼя не буде надано при helm install.

Для тих, хто все ще бажає автоматичне генерування імені, можна використовувати прапорець --generate-name, щоб створити його.

Публікація чартів в OCI реєстрах

Це експериментальна функція, введена в Helm 3. Щоб використовувати, встановіть змінну середовища HELM_EXPERIMENTAL_OCI=1.

На високому рівні, репозиторій чартів — це місце, де чарти можуть зберігатися та ними можна обмінюватися. Клієнт Helm пакує і відправляє чарт в репозиторій чартів. Простими словами, репозиторій чартів — це базовий HTTP сервер, який містить файл index.yaml і деякі упаковані чарти.

Хоча є кілька переваг в API репозиторію чартів, що відповідає найосновнішим вимогам зберігання, деякі недоліки почали виявлятися:

  • Репозиторії чартів мають великі труднощі з абстрагуванням більшості реалізацій безпеки, необхідних у виробничому середовищі. Наявність стандартного API для автентифікації та авторизації є дуже важливим в операційних сценаріях.
  • Інструменти перевірки походження чартів Helm, що використовуються для підписання та перевірки цілісності та походження чарту, є необовʼязковою частиною процесу публікації чарту.
  • У багатокористувацьких сценаріях один і той же чарт може бути завантажений іншим користувачем, що призводить до двократних витрат на зберігання того ж контенту. Розумніші репозиторії чартів були спроєктовані для обробки цього, але це не є частиною офіційної специфікації.
  • Використання одного індексного файлу для пошуку, інформації про метадані та отримання чартів ускладнило проєктування у безпечних багатокористувацьких реалізаціях.

Проєкт Docker Distribution (також відомий як Docker Registry v2) є спадкоємцем проєкту Docker Registry. Багато великих хмарних постачальників мають промислову пропозицію проєкту Distribution, і з такою кількістю постачальників, які пропонують один і той же продукт, проєкт Distribution отримав багато років удосконалення, кращих практик безпеки та випробувань у бою.

Будь ласка, ознайомтеся з helm help chart та helm help registry для отримання додаткової інформації про те, як упакувати чарт і опублікувати його в Docker реєстрі.

Більше інформації можна знайти на цій сторінці.

Видалення helm serve

helm serve запускав локальний репозиторій чартів на вашій машині для цілей розробки. Проте, він не отримав великого визнання як інструмент для розробки та мав численні проблеми з його дизайном. Зрештою, ми вирішили видалити його та винести у втулок.

Для досвіду подібного до helm serve, подивіться на локальний файловий системний варіант у ChartMuseum та втулок servecm.

Підтримка бібліотечних чартів

Helm 3 підтримує клас чартів, що називається “бібліотечний чарт”. Це чарт, який використовується іншими чартами, але не створює жодних артефактів релізів самостійно. Шаблони бібліотечного чарту можуть лише оголошувати елементи define. Глобально скопійовані не-define вмісти просто ігноруються. Це дозволяє користувачам повторно використовувати та ділитися фрагментами коду, які можна використовувати в багатьох чартах, уникати повторюваності та зберігати чарт DRY.

Бібліотечні чарти оголошуються в директиві залежностей у Chart.yaml, і їх можна встановлювати та керувати як будь-яким іншим чартом.

dependencies:
  - name: mylib
    version: 1.x.x
    repository: quay.io

Ми дуже раді бачити сценарії використання цієї функції для розробників чартів, а також будь-які найкращі практики, які виникають від споживання бібліотечних чартів.

Зміна apiVersion Chart.yaml

З впровадженням підтримки бібліотечних чартів та консолідацією requirements.yaml в Chart.yaml, клієнти, які розуміли формат пакетів Helm 2, не зможуть зрозуміти ці нові функції. Тому, ми підняли версію apiVersion у Chart.yaml з v1 на v2.

helm create тепер створює чарт з використанням цього нового формату, тому стандартний apiVersion був піднятий там також.

Клієнти, які бажають підтримувати обидві версії чартів Helm, повинні перевіряти поле apiVersion у Chart.yaml, щоб зрозуміти, як розібрати формат пакету.

Підтримка XDG Base Directory

Специфікація XDG Base Directory є портативним стандартом, що визначає, де слід зберігати конфігурації, дані та кешовані файли у файловій системі.

У Helm 2 Helm зберігав всю цю інформацію в ~/.helm (відомій як helm home), що можна було змінити, встановивши змінну середовища $HELM_HOME, або використовуючи глобальний прапорець --home.

У Helm 3 тепер Helm поважає наступні змінні середовища відповідно до специфікації XDG Base Directory:

  • $XDG_CACHE_HOME
  • $XDG_CONFIG_HOME
  • $XDG_DATA_HOME

Втулки Helm все ще отримують $HELM_HOME як псевдонім до $XDG_DATA_HOME для зворотної сумісності з втулками, які використовують $HELM_HOME як середовище для тимчасових даних.

Також кілька нових змінних середовища передаються в середовище втулка для врахування цієї зміни:

  • $HELM_PATH_CACHE для кешованого шляху
  • $HELM_PATH_CONFIG для конфігураційного шляху
  • $HELM_PATH_DATA для шляхів даних

Втулки Helm, які прагнуть підтримувати Helm 3, повинні розглянути можливість використання цих нових змінних середовища замість старих.

Перейменування команд CLI

Щоб краще узгодити термінологію з іншими менеджерами пакетів, helm delete було перейменовано на helm uninstall. helm delete все ще зберігається як псевдонім до helm uninstall, тож можна використовувати будь-яку форму.

У Helm 2, щоб очистити лог релізів, потрібно було вказати прапорець --purge. Ця функціональність тепер є стандартно увімкненою. Щоб зберегти попередню поведінку, використовуйте helm uninstall --keep-history.

Крім того, кілька інших команд були перейменовані для узгодження з тією ж термінологією:

  • helm inspect -> helm show
  • helm fetch -> helm pull

Ці команди також зберегли старі дієслова як псевдоніми, тому ви можете продовжувати використовувати їх у будь-якому вигляді.

Автоматичне створення просторів імен

При створенні релізу в просторі імен, який не існує, Helm 2 створював простір імен. Helm 3 дотримується поведінки іншого інструменту Kubernetes і повертає помилку, якщо простір імен не існує. Helm 3 створить простір імен, якщо ви явно вкажете прапорець --create-namespace.

Що сталося з .Chart.ApiVersion?

Helm дотримується звичайної домовленості CamelCasing, яка передбачає використання великої літери для абревіатури. Ми зробили це і в іншому коді, наприклад, у .Capabilities.APIVersions.Has. У Helm v3 ми виправили .Chart.ApiVersion, перейменувавши його на .Chart.APIVersion.