Docker много чего не умеет из того, что умеет werf. Не в силу того, что werf лучше, а просто потому что эти инструменты о разном. Docker — это фундаментальное решение, которое выполняет конкретные задачи по управлению образами и контейнерами на хосте (в большинстве своём низкоуровневые операции). werf, в свою очередь, про жизненный цикл приложения в Kubernetes, который обеспечивается слаженной работой множества компонентов.
Надеюсь у вас будет время попробовать werf и дать обратную связь в наших telegram-каналах и на GitHub.
Например, пользователю не нужно думать о тегировании образа и о том, что хранится в container registry
При использовании werf выкатывание приложения в Kubernetes, а точнее синхронизация состояния с конфигурацией в Git, — это первичная задача, ради которой выстраиваются CI/CD пайплайны и используются подобные решения. Все сопутствующие артефакты вторичны и werf берёт на себя ответственность за них и не даёт пользователю стрелять себе в ногу.
Как следствие, в werf нет понятий tag и push — эти процедуры встроены в werf build
Понятия то может и нет, но если вы просто объединили эти процессы под капотом
Статья является сравнением двух инструментов. В docker пользователь может вручную выполнить тегирование и публикацию. В werf такой возможности нет — пользователь решает конкретную задачу без промежуточных состояний и работы с артефактами:
werf build — собрать образ соответствующий текущему коммиту;
werf run — запустить контейнер для текущего коммита;
werf converge — синхронизировать состояние в Kubernetes с текущим коммитом.
werf экономит время на сборку, собирая только те образы, или слои образа, которые требуются для текущего коммита и которых еще нет в container registry. Вдобавок, экономится место, поскольку нет необходимости повторно сохранять образ в реестре.
много фишек и вы наверное по сути реализовали многое из этого под капотом werf;
Мы не разрабатываем ради разработки — наши решения выстраиваются поверх существующих (кстати, docker multi-stage в виде артефактов в Stapel-сборщике появился до Docker).
это не значит, что этих механизмов не существует в обычном docker;
при грамотной настройке multistage build docker скорость сборки не будет отличаться от werf;
множество best practices для различного рода кэширования;
этих механизмов нет вообще или они сильно уступают werf.
Как уже было сказано раннее мы не изобретаем велосипед по новой, а добавляем уровни абстракции поверх. В werf водится новая сущность — стадия, которая позволяет делать больше, чем Docker может со слоями.
werf — это действительно эдакий мультикомбайн, решение для доставки приложения в Kubernetes, которое отвечает за весь жизненный цикл приложения и его артефактов (ближайший аналог от Google — skaffold).
Не уверен, что это работает и главное будет в будущем работать лучше, чем вышеупомянутое, ведь там его поддерживает гораздо большее коммьюнити
Функционал выстраивается поверх кода из upstream, а также мы делаем свой вклад в развитие используемых проектов, участвуем в обсуждении проблем и непосредственно в разработке.
Что касается поддержки, то мы имеем более 2000 внутренних инсталяций werf, которые работают на различных каналах стабильности, и получаем оперативную обратную связь.
Некоторые утверждения ложные и желаемое выдаётся за действительное. Докер умеет много что из того, что в статье преподносится, как невозможное
А есть какие-то конкретные замечания, спорные моменты?
В этой части статьи рассматриваются особенности работы с исходными файлами в Dockerfile и Stapel, особенности кеширования и слоёв. В случае с Dockerfile добавление файлов происходит на определённом шаге сборки, а в случае со Stapel оно плавающее.
В Dockerfile можно выполнить команду при любом изменении файлов:
COPY . .
RUN command
В Dockerfile можно выполнить команду при изменении определённого файла/среза файлов:
COPY trigger_file .
RUN command
COPY . .
Но в Dockerfile нельзя выполнить команду со всем исходным кодом при изменении определённого файла/среза файлов. Нет возможности реализовать некий триггер и не выполнять времязатратную команду при других изменениях.
Причём здесь docker multi-stage и как он поможет решить данный кейс — мне не понятно.
Спасибо за приятный и в то же время полезный комментарий.
Один из ключевых моментов, который мы старались осветить в этой статье — важность понимания процессов команды и вашего критерия актуальности образов (с какого момента пропадает необходимость хранить конкретный тег в registry). Таким образом, не стоит гнаться за универсальным решением, а нужно исходить из потребностей. Примитивные политики, предлагаемые сервисами, покрывают запросы большинства пользователей (ну или большинство готово мириться с проблемами, которые время от времени возникают).
Что касается AQL — очень гибкий API и может эффективно использоваться как часть вашей реализации. В нашем случае, нам требовался универсальный подход, который применим к произвольной имплементации Docker Registry.
Наш опыт показывает, что регистри не имеет достаточно данных для того, чтобы делать очистку правильно, поэтому необходимо делать это извне и брать в расчёт Git, Kubernetes и ...
В ближайших статьях мы расскажем о нашем подходе, новом алгоритме и основных моментах, которые должны учитываться при очистке.
Пока можно почитать про текущие политики и логику работы в документации.
поддерживаются ли многоуровневые имена репозиториев.
поддерживается ли стандартное, с Docker Registry API, удаление тегов.
Первое можно отрегулировать с помощью опции --images-repo-mode, а вот со вторым или самостоятельно организовывать очистку или добавлять поддержку в werf.
Можно даже самостоятельно делать импорт в начале job и экспорт архива с образами в конце. Если job-ы не запускаются параллельно, то такая схема будет работать. Иначе будут проблемы, связанные с тем, что образы стадий будут перетираться и инвалидироваться в параллельных процессах — нарушится целостность + это очень долго.
Вывод: подождать реализации распределённой сборки, где мы учтём все тонкости.
Всё верно, werf требует наличия сборочного кэша на всех этапах. И этот сборочный кэш не ограничен только docker-образами (stages).
На текущий момент поддерживается работа только на одном узле. При желании можно запустить docker-in-docker (issue), но мы не рекомендуем данный подход.
Это во многом зависит от проектов. Большинство web-студий используют единный стек технологий для всех своих продуктов, поэтому им уместно свести настройку выката к описанию файла с настройками, values.yaml, для своего или официального чарта:
Chart repository — это то, кмк, что позволяет Helm обладать таким большим сообществом и оставаться всё ещё на плаву, несмотря на местами спорные приоритеты в развитии продукта.
Condition и tags отличная альтернатива для организации выката в различные окружения велосипедам на go шаблонах. К примеру, в тестовом окружение поднимаем базу данных и очередь в кластере, а в проде используем внешние — две/три дополнительные опции в .gitlab-ci.yml и чистые чарт шаблоны.
В компании с множеством типовых проектов разумно в конце концов прийти к собственному chart repository для сопровождения и оперативного обновления компонентов. В вашем же случае с одним проектом, наверное, имеет смысл смотреть готовые решения для отдельных компонентов в официальном репозитории.
— это исключительно про порядок. Вы с тем же успехом можете выкатывать *хуки, используя kubectl apply, дожидаться их завершения и выполнять следующий шаг (в Helm поддерживается около десяти типов хуков и организация подобного на bash выглядит не очень перспективным занятием). В Helm 2 tiller используется для установки ресурсов, в Helm 3 все функции выполняет клиент, поэтому мне совсем непонятно негодование будут работать только с тиллером.
Helm 2 можно использовать без tiller в кластере, если это для вас проблема. Этой теме посвящено много статей, они сгруппированы таким термином как tillerless (по сути всё сводится к тому, что описал коллега в первом комментарии). Мы пошли дальше и встроили helm в наше собственное решение, werf.
Канареечный релиз
У вас нет никаких ограничений при построенние процесса выката на основе helm и istio хороший тому пример.
Если есть миграция бд, то хельм, ну, никак не сделает ее из блокирующей бд в неблокирующую
В хуках вы можете использовать kubectl и тут полная свобода для творчества, хотите удаляйте ресурсы, хотите скейлите их в ноль.
Хельм хорош, чтобы попробовать в кластере какой-то софт. Так же как и докер хорош именно для
запуска некоей софтины в изолированном окружении в тестовом контуре.
Чем вас не устраивает helm для выката и в другие контуры, если не секрет?
Мы деплоим в куб либо ручками, либо используя хельм как темплейтер и его выхлоп на kubectl apply.
Вы используете исключительно kubectl или у вас есть ещё дополнительные инструменты?
роллинг релиз некоего продукта
Может быть я неправильно вас понимаю, но, а как иначе?
В helm даже сущность была новая введена — release. При первой инсталляции чарта создаётся релиз, а при последующих он обновляется.
очистку устаревших ресурсов
А что вы подразумеваете под устаревшими ресурсами и почему эта задача не может быть решена командой helm delete и, при необходимости, дополнена соответствующими хуками?
Если правильно понял вопрос, то речь идёт об использовании helm исключительно для генерации манифестов:
helm template . | kubectl apply --wait -f -
При использовании helm становится удобным сопровождение инсталляций. Помимо таких базовых операций, как установка, обновление и удаление, вдобавок доступен откат до определённой версии командой helm rollback (полезно, к примеру, при неудавшемся выкате).
Всегда есть возможность посмотреть какие релизы установлены в кластере (helm list), а также посмотреть текущее состояние ресурсов конкретного релиза (helm status).
Helm так же позволяет контролировать процесс выката. Речь идёт о порядке, зависимостях и хуках. В большинстве наших проектов мы используем хуки для фикстур и миграций баз данных, но область применения на этом не ограничивается.
Во-первых, строго говоря разбивка приложения на несколько контейнеров ничего общего с микросервисной архитектурой не имеет. Ну, разбили монолит на два контейнера и разбили. И получили распределённый монолит.
Когда приложение представлено в виде нескольких компонентов, к примеру, микросервисов…
Дайте определение вложенного репозитория
Repository — коллекция образов, сгруппированная по имени.
Registry — сервис для хранения репозиториев (Docker Hub, GCR, ...).
Большинство registry поддерживает многоуровневую иерархию репозиториев. Термин вложенный репозиторий используется, чтобы подчеркнуть изоляцию группы репозиториев, а не просто возможность хранения образов с многоуровневым именем (REGISTRY/webdev/app/backend).
В Helm 3, в дополнении к Yaml / Go, будет поддерживаться Lua.
По идее должно упроститься написание сложных чартов, манифесты станут меньше и информативнее.
Да, по задумке helm должен следить за выполнением соответствующих probe при использовании опции --wait:
--wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
Но должным образом сейчас это не работает. Поддерживаются не все ресурсы и не все версии API. Да и по самой реализации есть вопросы.
Docker много чего не умеет из того, что умеет werf. Не в силу того, что werf лучше, а просто потому что эти инструменты о разном. Docker — это фундаментальное решение, которое выполняет конкретные задачи по управлению образами и контейнерами на хосте (в большинстве своём низкоуровневые операции). werf, в свою очередь, про жизненный цикл приложения в Kubernetes, который обеспечивается слаженной работой множества компонентов.
Надеюсь у вас будет время попробовать werf и дать обратную связь в наших telegram-каналах и на GitHub.
При использовании werf выкатывание приложения в Kubernetes, а точнее синхронизация состояния с конфигурацией в Git, — это первичная задача, ради которой выстраиваются CI/CD пайплайны и используются подобные решения. Все сопутствующие артефакты вторичны и werf берёт на себя ответственность за них и не даёт пользователю стрелять себе в ногу.
Статья является сравнением двух инструментов. В docker пользователь может вручную выполнить тегирование и публикацию. В werf такой возможности нет — пользователь решает конкретную задачу без промежуточных состояний и работы с артефактами:
werf build
— собрать образ соответствующий текущему коммиту;werf run
— запустить контейнер для текущего коммита;werf converge
— синхронизировать состояние в Kubernetes с текущим коммитом.Мы не разрабатываем ради разработки — наши решения выстраиваются поверх существующих (кстати, docker multi-stage в виде артефактов в Stapel-сборщике появился до Docker).
Как уже было сказано раннее мы не изобретаем велосипед по новой, а добавляем уровни абстракции поверх. В werf водится новая сущность — стадия, которая позволяет делать больше, чем Docker может со слоями.
werf — это действительно эдакий мультикомбайн, решение для доставки приложения в Kubernetes, которое отвечает за весь жизненный цикл приложения и его артефактов (ближайший аналог от Google — skaffold).
Функционал выстраивается поверх кода из upstream, а также мы делаем свой вклад в развитие используемых проектов, участвуем в обсуждении проблем и непосредственно в разработке.
Что касается поддержки, то мы имеем более 2000 внутренних инсталяций werf, которые работают на различных каналах стабильности, и получаем оперативную обратную связь.
А есть какие-то конкретные замечания, спорные моменты?
В этой части статьи рассматриваются особенности работы с исходными файлами в Dockerfile и Stapel, особенности кеширования и слоёв. В случае с Dockerfile добавление файлов происходит на определённом шаге сборки, а в случае со Stapel оно плавающее.
В Dockerfile можно выполнить команду при любом изменении файлов:
В Dockerfile можно выполнить команду при изменении определённого файла/среза файлов:
Но в Dockerfile нельзя выполнить команду со всем исходным кодом при изменении определённого файла/среза файлов. Нет возможности реализовать некий триггер и не выполнять времязатратную команду при других изменениях.
Причём здесь docker multi-stage и как он поможет решить данный кейс — мне не понятно.
Спасибо за приятный и в то же время полезный комментарий.
Один из ключевых моментов, который мы старались осветить в этой статье — важность понимания процессов команды и вашего критерия актуальности образов (с какого момента пропадает необходимость хранить конкретный тег в registry). Таким образом, не стоит гнаться за универсальным решением, а нужно исходить из потребностей. Примитивные политики, предлагаемые сервисами, покрывают запросы большинства пользователей (ну или большинство готово мириться с проблемами, которые время от времени возникают).
Что касается AQL — очень гибкий API и может эффективно использоваться как часть вашей реализации. В нашем случае, нам требовался универсальный подход, который применим к произвольной имплементации Docker Registry.
Наш опыт показывает, что регистри не имеет достаточно данных для того, чтобы делать очистку правильно, поэтому необходимо делать это извне и брать в расчёт Git, Kubernetes и ...
В ближайших статьях мы расскажем о нашем подходе, новом алгоритме и основных моментах, которые должны учитываться при очистке.
Пока можно почитать про текущие политики и логику работы в документации.
Основных момента два:
Первое можно отрегулировать с помощью опции --images-repo-mode, а вот со вторым или самостоятельно организовывать очистку или добавлять поддержку в werf.
Работаем по законам спроса и предложения: проверить все имплементации нет возможности, поэтому наращиваем набор только при должной потребности.
В ближайших планах есть поддержка JFrog Artifactory.
До nexus тоже доберёмся. Спасибо за обратную связь.
P.S. Для многих имплементаций никаких дополнительных обвязок не требуется и всё будет работать по умолчанию (Docker Registry API)
Можно даже самостоятельно делать импорт в начале job и экспорт архива с образами в конце. Если job-ы не запускаются параллельно, то такая схема будет работать. Иначе будут проблемы, связанные с тем, что образы стадий будут перетираться и инвалидироваться в параллельных процессах — нарушится целостность + это очень долго.
Вывод: подождать реализации распределённой сборки, где мы учтём все тонкости.
Всё верно, werf требует наличия сборочного кэша на всех этапах. И этот сборочный кэш не ограничен только docker-образами (stages).
На текущий момент поддерживается работа только на одном узле. При желании можно запустить docker-in-docker (issue), но мы не рекомендуем данный подход.
Это во многом зависит от проектов. Большинство web-студий используют единный стек технологий для всех своих продуктов, поэтому им уместно свести настройку выката к описанию файла с настройками,
values.yaml
, для своего или официального чарта:Chart repository — это то, кмк, что позволяет Helm обладать таким большим сообществом и оставаться всё ещё на плаву, несмотря на местами спорные приоритеты в развитии продукта.
В Helm хорошо подошли к управлению зависимостями:
Condition и tags отличная альтернатива для организации выката в различные окружения велосипедам на go шаблонах. К примеру, в тестовом окружение поднимаем базу данных и очередь в кластере, а в проде используем внешние — две/три дополнительные опции в
.gitlab-ci.yml
и чистые чарт шаблоны.В компании с множеством типовых проектов разумно в конце концов прийти к собственному chart repository для сопровождения и оперативного обновления компонентов. В вашем же случае с одним проектом, наверное, имеет смысл смотреть готовые решения для отдельных компонентов в официальном репозитории.
— это исключительно про порядок. Вы с тем же успехом можете выкатывать *хуки, используя kubectl apply, дожидаться их завершения и выполнять следующий шаг (в Helm поддерживается около десяти типов хуков и организация подобного на bash выглядит не очень перспективным занятием). В Helm 2 tiller используется для установки ресурсов, в Helm 3 все функции выполняет клиент, поэтому мне совсем непонятно негодование будут работать только с тиллером.
Helm 2 можно использовать без tiller в кластере, если это для вас проблема. Этой теме посвящено много статей, они сгруппированы таким термином как tillerless (по сути всё сводится к тому, что описал коллега в первом комментарии). Мы пошли дальше и встроили helm в наше собственное решение, werf.
У вас нет никаких ограничений при построенние процесса выката на основе helm и istio хороший тому пример.
В хуках вы можете использовать kubectl и тут полная свобода для творчества, хотите удаляйте ресурсы, хотите скейлите их в ноль.
Чем вас не устраивает helm для выката и в другие контуры, если не секрет?
Вы используете исключительно kubectl или у вас есть ещё дополнительные инструменты?
Может быть я неправильно вас понимаю, но, а как иначе?
В helm даже сущность была новая введена — release. При первой инсталляции чарта создаётся релиз, а при последующих он обновляется.
А что вы подразумеваете под устаревшими ресурсами и почему эта задача не может быть решена командой helm delete и, при необходимости, дополнена соответствующими хуками?
Если правильно понял вопрос, то речь идёт об использовании helm исключительно для генерации манифестов:
При использовании helm становится удобным сопровождение инсталляций. Помимо таких базовых операций, как установка, обновление и удаление, вдобавок доступен откат до определённой версии командой helm rollback (полезно, к примеру, при неудавшемся выкате).
Всегда есть возможность посмотреть какие релизы установлены в кластере (helm list), а также посмотреть текущее состояние ресурсов конкретного релиза (helm status).
Helm так же позволяет контролировать процесс выката. Речь идёт о порядке, зависимостях и хуках. В большинстве наших проектов мы используем хуки для фикстур и миграций баз данных, но область применения на этом не ограничивается.
Когда приложение представлено в виде нескольких компонентов, к примеру, микросервисов…
Большинство registry поддерживает многоуровневую иерархию репозиториев. Термин вложенный репозиторий используется, чтобы подчеркнуть изоляцию группы репозиториев, а не просто возможность хранения образов с многоуровневым именем (REGISTRY/webdev/app/backend).
В GCR используется термин nested repository.
В Azure nested namespaces, но по сути тоже самое.
В случае с Docker Hub многоуровневое именнование образов не поддерживается (и не планируется), поэтому и соответствующего термина нет.
По идее должно упроститься написание сложных чартов, манифесты станут меньше и информативнее.
Если уже хочется попробовать, можно собрать Helm из master.
Да, по задумке helm должен следить за выполнением соответствующих probe при использовании опции
--wait
:Но должным образом сейчас это не работает. Поддерживаются не все ресурсы и не все версии API. Да и по самой реализации есть вопросы.