Реліз werf 1.1: покращення у збирачі сьогодні та плани на майбутнє

Реліз werf 1.1: покращення у збирачі сьогодні та плани на майбутнє

werf — наша GitOps CLI-утиліта з відкритим кодом для збирання та доставки додатків у Kubernetes. Як і обіцяли, вихід версії v1.0 знаменував початок додавання до нових можливостей і перегляду звичних підходів. Тепер ми раді представити реліз v1.1, який є великим кроком у розвитку та доробку на майбутнє збирача werf. Версія доступна на даний момент у канал 1.1 ea.

Основа релізу – це нова архітектура сховища стадій та оптимізація роботи обох збирачів (для Stapel та Dockerfile). Нова архітектура сховища відкриває можливості до реалізації розподілених збірок з кількох хостів та паралельних складання на одному хості.

Оптимізація роботи включає позбавлення від зайвих обчислень на етапі розрахунку сигнатур стадій і зміни механізмів розрахунку контрольних сум файлів на більш ефективні. Ця оптимізація зменшує середній час збирання проекту за допомогою werf. І неодружені збірки, коли всі стадії існують у кеші stages-storage, тепер справді швидкі. У більшості випадків повторний запуск складання пройде швидше, ніж за секунду! Це також стосується процедур верифікації стадій у процесі роботи команд werf deploy и werf run.

Також у цьому релізі з'явилася стратегія тегування образів за вмістом. content-based tagging, яка тепер включена за замовчуванням і є єдиною рекомендованою.

Розглянемо докладніше ключові нововведення в werf v1.1, а заразом розповімо про плани на майбутнє.

Що змінилося у werf v1.1?

Новий формат іменування стадій та алгоритм підбору стадій з кешу

Нове правило створення імені стадії. Тепер кожне складання стадії генерує унікальне ім'я стадії, яке складається з 2-х частин: сигнатура (як було в v1.0) плюс унікальний часовий ідентифікатор.

Наприклад, повне ім'я образу стадії може виглядати так:

werf-stages-storage/myproject:d2c5ad3d2c9fcd9e57b50edd9cb26c32d156165eb355318cebc3412b-1582656767835

… або у загальному вигляді:

werf-stages-storage/PROJECT:SIGNATURE-TIMESTAMP_MILLISEC

тут:

  • SIGNATURE — це сигнатура стадії, яка представляє ідентифікатор вмісту стадії і залежить від історії правок Git, які призвели до цього вмісту;
  • TIMESTAMP_MILLISEC — це гарантовано унікальний ідентифікатор образу, що генерується у момент збирання нового образу.

Алгоритм підбору стадій з кешу заснований на перевірці спорідненості Git-коммітів:

  1. Werf розраховує сигнатуру певної стадії.
  2. В stages-storage може існувати кілька стадій з цієї сигнатури. Werf вибирає всі стадії, що підходять по сигнатурі.
  3. Якщо поточна стадія пов'язана з Git (git-archive), стадія користувача з Git-патчами: install, beforeSetup, setup; або git-latest-patch), то werf вибирає ті стадії, які пов'язані з коммітом, що є предком поточного комміту (для якого викликана збірка).
  4. З потрібних стадій вибирається одна — найстаріша за датою створення.

Стадія для різних Git-гілок може мати ту саму сигнатуру. Але werf запобігає використанню кеша, пов'язаного з різними гілками, між цими гілками, навіть якщо сигнатури збіглися.

→ Документація.

Новий алгоритм створення та збереження стадій у сховищі стадій

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

Зауважимо, що кілька процесів (на одному або декількох хостах) можуть почати складання однієї і тієї ж стадії приблизно один і той же час. Werf використовує алгоритм оптимістичного блокування stages-storage у момент збереження свіжозібраного образу в stages-storage. Таким чином, коли збирання нової стадії готова, werf блокує stages-storage і зберігає туди свіжозібраний образ лише у випадку, якщо там вже не існує відповідного образу (за сигнатурою та іншими параметрами - див. новий алгоритм підбору стадій з кешу).

Свіжозібраний образ гарантовано матиме унікальний ідентифікатор за TIMESTAMP_MILLISEC (Див. новий формат іменування стадій). У разі, якщо у stages-storage буде знайдено відповідний образ, werf відкине свіжозібраний образ і використовуватиме образ з кеша.

Іншими словами: перший процес, який закінчить збирати образ (найшвидший), отримає право зберегти його в stages-storage (і потім саме цей єдиний образ використовуватиметься для всіх збірок). Повільний процес складання ніколи не буде блокувати швидший процес від збереження результатів складання поточної стадії і переходу до складання наступної.

→ Документація.

Покращена продуктивність збирача Dockerfile

На даний момент конвеєр стадій для образу, що збирається з Dockerfile, складається з однієї стадії. dockerfile. При обчисленні сигнатури вважається контрольна сума файлів context, що будуть використовуватися при складанні. До цього покращення werf рекурсивно проходив по всіх файлах та отримував контрольну суму, просумувавши контекст та мод кожного файлу. Починаючи з версій v1.1, werf може використовувати розраховані контрольні суми, що зберігаються у Git-репозиторії.

В основі алгоритму - git ls-tree. Алгоритм враховує записи в .dockerignore і проходить рекурсивно по дереву файлів лише за необхідності. Таким чином, ми відв'язалися від читання файлової системи, а залежність алгоритму від розміру context не є суттєвою.

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

Покращено продуктивність при імпортуванні файлів

У версіях werf v1.1 використовується rsync-сервер при імпорті файлів з артефактів та образів. Раніше імпортування виконувалося за два кроки з використанням монтування директорії з хост-системи.

Продуктивність імпортів у macOS більше не обмежується Docker volumes, а імпорти виконуються за той самий час, що й у Linux та Windows.

Content-based tagging

Werf v1.1 підтримує так зване тегування за вмістом образу content-based tagging. Теги результуючих образів Docker залежать від вмісту цих образів.

Під час запуску команди werf publish --tags-by-stages-signature або werf ci-env --tagging-strategy=stages-signature будуть протеговані публіковані образи так званої сигнатурою стадій образу. Кожен образ тегується своєю власною сигнатурою стадій цього образу, яка розраховується за тими самими правилами, як і регулярна сигнатура кожної зі стадій окремо, але є узагальнюючим ідентифікатором образу.

Сигнатура стадій образу залежить від:

  1. вмісту цього образу;
  2. Історія виправлення в Git, які призвели до цього вмісту.

У Git-репозиторії завжди є неодружені комміти, які не змінюють вмісту файлів образу. Наприклад, коміти тільки з коментарями або merge-комміти, або комміти, що змінюють файли в Git, які не будуть імпортовані в образ.

При використанні content-based tagging вирішуються проблеми зайвих перезапусків pod'ів програми в Kubernetes через зміни імені образу, навіть якщо вміст образу не змінилося. До речі, це одна з причин, що заважають зберігати безліч мікросервісів однієї програми в єдиному Git-репозиторії.

Також content-based tagging є більш надійним методом тегування, ніж тегування за Git-гілками, тому що вміст результуючих образів не залежить від порядку виконання pipeline'ів у CI-системі для складання кількох коммітів однієї і тієї ж гілки.

Важливо: починаючи з поточного моменту stages-signature - це єдина рекомендована стратегія тегування. Саме вона використовуватиметься за замовчуванням у команді werf ci-env (Якщо явно не вказати іншу схему тегування).

→ Документація. Цій фічі буде також присвячена окрема публікація. ОНОВЛЕНО (3 квітня): Стаття з подробицями опубліковано.

Рівні логування

У користувача з'явилася можливість контролювати висновок, ставити рівень логування та працювати з налагоджувальною інформацією. Додані опції --log-quiet, --log-verbose, --log-debug.

За замовчуванням у висновку міститься мінімум інформації:

Реліз werf 1.1: покращення у збирачі сьогодні та плани на майбутнє

При використанні докладного висновку (--log-verbose) можна простежити, як працює werf:

Реліз werf 1.1: покращення у збирачі сьогодні та плани на майбутнє

Детальний висновок (--log-debug), крім налагоджувальної інформації werf, також містить логи використовуваних бібліотек. Наприклад, можна побачити, як відбувається взаємодія з Docker Registry, а також зафіксувати місця, в яких витрачається значна кількість часу:

Реліз werf 1.1: покращення у збирачі сьогодні та плани на майбутнє

подальші плани

Увага! Описані далі можливості з позначкою v1.1 стануть доступними вже в цій версії, багато з них — найближчим часом. Оновлення прийдуть через автоапдейти при використанні multiwerf. Ці можливості не торкаються стабільної частини функцій v1.1, їх поява не вимагатиме ручного втручання користувача у вже існуючі конфігурації.

Повна підтримка різних реалізацій Docker Registry (НОВЕ)

Мета – користувач повинен використовувати довільну реалізацію без обмежень під час використання werf.

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

  • Default (library/registry)*,
  • AWS ECR,
  • Azure*,
  • Docker Hub,
  • GCR*,
  • GitHub Packages,
  • GitLab Registry*,
  • Harbor*,
  • Quay.

Зірочкою відзначені рішення, які на даний момент вже повністю підтримуються werf. Для решти є підтримка, але з обмеженнями.

Можна виділити дві основні проблеми:

  • Деякі рішення не підтримують видалення тегів за допомогою Docker Registry API, що не дозволяє користувачам використовувати автоматичне очищення, реалізоване у werf. Це справедливо для AWS ECR, Docker Hub та GitHub Packages.
  • Частина рішень не підтримують так звані nested repositories (Docker Hub, GitHub Packages і Quay) або підтримують, але користувач повинен створювати їх вручну, використовуючи UI або API (AWS ECR).

Ці та інші проблеми ми маємо намір вирішувати з використанням нативних API у рішень. Це завдання також входить покриття тестами повного циклу роботи werf кожному з них.

Розподілене складання образів (↑)

  • Версія: v1.2 v1.1 (пріоритет реалізації даної можливості було збільшено)
  • Терміни: березень-квітень березень
  • Питання

На даний момент, werf v1.0 та v1.1 можна використовувати лише на одному виділеному хості для операцій складання та публікації образів та деплою додатків у Kubernetes.

Щоб відкрити можливості розподіленої роботи werf, коли складання та деплой додатків у Kubernetes запускаються на кількох довільних хостах і ці хости не зберігають свій стан між складаннями (тимчасові runner'и), від werf потрібно реалізація можливості використання Docker Registry як сховища стадій.

Раніше, коли проект werf ще називався dapp, у ньому була така можливість. Однак ми зіткнулися з низкою проблем, які необхідно врахувати при реалізації цієї функції у werf.

Примітка. Ця можливість передбачає роботу збирача всередині pod'ов Kubernetes, т.к. для цього необхідно позбутися залежності від локального Docker-сервера (у Kubernetes pod'є немає доступу до локального Docker-сервера, тому що сам процес запущений в контейнері, а роботу з Docker-сервером по мережі werf не підтримує і не підтримуватиме). Підтримку роботи в Kubernetes буде реалізовано окремо.

Офіційна підтримка GitHub Actions (НОВЕ)

Включає документацію werf (розділи посилання и керівництво), а також офіційний GitHub Action для роботи з WERF.

Крім того, дозволить працювати werf на ефемерних runner'ах.

Механіка взаємодії користувача з CI-системою буде заснована на виставленні label'ів на pull-request'и для ініціювання певних дій зі складання/викокання програми.

Локальна розробка та розгортання додатків з werf (↓)

  • Версія: v1.1
  • Терміни: січень-лютий квітень
  • Питання

Головна мета - домогтися єдиного уніфікованого конфігу для розгортання додатків як локально, так і в production, без складних дій, "з коробки".

Від werf також вимагається такий режим роботи, в якому буде зручно редагувати код програми та миттєво отримувати зворотний зв'язок від працюючого додатка для дебага.

Новий алгоритм очищення (НОВЕ)

У поточній версії werf v1.1 у процедурі cleanup не передбачено очищення образів для схеми тегування за вмістом (content-based tagging) - дані образи будуть накопичуватися.

Також у поточній версії werf (v1.0 та v1.1) використовуються різні політики очищення для образів, опублікованих за схемами тегування: Git-гілка, Git-тег або Git-комміт.

Придумано новий уніфікований для всіх схем тегування алгоритм очищення образів на основі історії коммітів у Git:

  • Зберігати не більше, ніж N1 образів, пов'язаних з N2 останніми комітами для кожного з git HEAD (гілки та теги).
  • Зберігати не більше ніж N1 образів-стадій, пов'язаних з N2 останніми комітами для кожного з git HEAD (гілки та теги).
  • Зберігати всі образи, які використовуються в будь-яких ресурсах кластера Kubernetes (скануються всі kube-контексти файлу конфігурації та namespace'и; можна обмежити таку поведінку спеціальними опціями).
  • Зберігати всі образи, що використовуються в маніфестах конфігурації ресурсів, збережених у Helm-релізах.
  • Образ може бути видалений, якщо він не пов'язаний з жодним HEAD з git (наприклад, тому що сам відповідний HEAD був видалений) і не використовується в жодному з маніфестів у кластері Kubernetes і в релізах Helm.

Паралельне складання образів (↓)

  • Версія: v1.1
  • Терміни: січень-лютий квітень*

Поточна версія werf збирає образи та артефакти, описані в werf.yamlпослідовно. Необхідно розпаралелити процес складання незалежних стадій образів та артефактів, а також забезпечити зручний та інформативний висновок.

* Примітка: термін зрушений через підвищення пріоритету реалізації розподіленої збірки, яка додасть більше можливостей горизонтального масштабування, а також використання werf з GitHub Actions. Паралельна збірка є наступним кроком оптимізації, що дає вертикальну масштабованість при складанні одного проекту.

Перехід на Helm 3 (↓)

  • Версія: v1.2
  • Терміни: лютий-березень травень*

Включає перехід на нову кодову базу Кермо 3 та перевірений, зручний спосіб міграції існуючих установок.

* Примітка: перехід на Helm 3 не додасть суттєвих можливостей у werf, тому що всі ключові фічі Helm 3 (3-way-merge та відсутність tiller) вже реалізовані у werf. Більше того, werf має додаткові можливості крім вказаних. Однак цей перехід залишається у наших планах і буде здійснено.

Jsonnet для опису конфігурації Kubernetes (↓)

  • Версія: v1.2
  • Терміни: січень-лютий квітень-травень

Werf підтримуватиме опис конфігурації для Kubernetes у форматі Jsonnet. При цьому werf залишиться сумісним із Helm і буде можливість вибору формату опису.

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

Також розглядається можливість застосування та інших систем опису конфігурації Kubernetes (наприклад, Kustomize).

Робота всередині Kubernetes (↓)

  • Версія: v1.2
  • Терміни: квітень-травень травень-червень

Мета: забезпечити складання образів та доставку програми з використанням runner'ів у Kubernetes. Тобто. складання нових образів, їх публікація, очищення та деплой може відбуватися прямо з pod'ів Kubernetes.

Щоб реалізувати цю можливість, спочатку потрібна можливість розподіленого складання образів (Див. пункт вище).

Також потрібна підтримка режиму роботи збирача без Docker-сервера (тобто Kaniko-подібна збирання або збирання в userspace).

Werf підтримуватиме збірку в Kubernetes не тільки за допомогою Dockerfile, але й за допомогою свого збирача Stapel з інкрементальними перескладаннями та Ansible.

Крок у бік відкритої розробки

Ми любимо нашу спільноту (GitHub, Telegram) і хочемо, щоб все більше людей допомагали робити werf краще, розуміли, в якому напрямку ми рухаємося, і брали участь у розробці.

Нещодавно було вирішено перейти на GitHub project boards для того, щоб відкрити робочий процес нашої команди. Зараз можна переглянути найближчі плани, а також поточні роботи за такими напрямками:

Зроблено велику роботу з issues:

  • Видалено неактуальні.
  • Існуючі наведені до єдиного формату, достатньої кількості деталей та подробиць.
  • Додані нові issues з ідеями та пропозиціями.

Як увімкнути версію v1.1

Версія доступна на даний момент у канал 1.1 ea (у каналах стабільний и твердий як камінь релізи з'являться в міру стабілізації, проте ea як така вже досить стабільна від використання, т.к. пройшла через канали альфа и бета). Активується через multiwerf наступним способом:

source $(multiwerf use 1.1 ea)
werf COMMAND ...

Висновок

Нова архітектура сховища стадій та оптимізація роботи збирача для Stapel та Dockerfile збирачів відкривають можливості реалізувати розподілені та паралельні збирання у werf. Дані можливості незабаром з'являться в тому ж релізі v1.1 і стануть автоматично доступними через механізм оновлень (для користувачів multiwerf).

У цьому релізі було додано стратегію тегування за вмістом образів. content-based tagging, - Яка стала стратегією за умовчанням. А також був перероблений лог основних команд: werf build, werf publish, werf deploy, werf dismiss, werf cleanup.

Наступним суттєвим кроком стане додавання розподілених складання. Розподілені збірки з часу v1.0 стали більш пріоритетним завданням, ніж паралельні збірки, тому що додають більше цінності werf: вертикальне масштабування збирачів та підтримка ефемерних збирачів у різних CI/CD-системах, а також можливість створити офіційну підтримку GitHub Actions. Тому терміни реалізації паралельних збірок було зрушено. Однак ми працюємо над тим, щоб скоріше реалізувати обидві можливості.

Слідкуйте за новинами! І не забувайте заглядати до нас у GitHub, Щоб створити issue, знайти вже існуючий і поставити плюс, створити PR або просто спостерігати за розвитком проекту.

PS

Читайте також у нашому блозі:

Джерело: habr.com

Додати коментар або відгук