Рубрики
Uncategorized

Резка времени сборки пополам с помощью Docker’s Buildx Kubernetes Driver

При выпуске среды — наша основная цель, но мы не можем создавать среды без сборки. Совсем недавно… Tagged с Docker, Kubernetes, Buildx, DevOps.

При выпуске среды — наша основная цель, но мы не можем создавать среды без сборки. Недавно мы предприняли проект, чтобы пересмотреть нашу инфраструктуру сборки и определить, нужно ли ее обновить. Время сборки стало важным фактором в нашей предоставлении услуг, и нам нужен был способ улучшить опыт наших клиентов. Одной из основных областей, с которыми мы хотели улучшить, была параллелизм создания нескольких изображений докеров для одного применения.

Название статьи уже испортило решение, и альтернативный релиз «сделал это одно, чтобы сократить время их сборки пополам!» Не совсем летал с остальной частью компании, но Docker’s New BUILDX Проект соответствует счету. Во -первых, мы рассмотрим, как выглядела наша оригинальная инфраструктура и как долго строился на примере проекта. Затем мы опишем изменения, которые мы внесли для использования BuildX, и увеличение скорости, которую мы наблюдали.

Давайте начнем с диаграммы того, как выглядела наша оригинальная инфраструктура.

Как вы можете видеть, запросы на сборки будут проходить в наше основное применение рельсов, а затем разделились на различные экземпляры строителя через Sidekiq. Строитель Контейнер — это Ruby Code, который будет аутентифицировать в GitHub, клонировать репозиторий, ознакомьтесь с правильным SHA, а затем выполнить Docker Build . Из -за того, как мы создали аутентификацию, чтобы вытащить код из GitHub, одного Строитель Контейнер может клонировать только один репозиторий за раз. Это означало, что контейнер мог выполнять только один запрос на сборку за раз. Мы добавили потоки в код Ruby, чтобы иметь возможность выполнить несколько Docker Build Команды за раз, но количество контейнеров застройщиков, которые мы развернули, ограничивало наши одновременные сборки. Хотя не сложно горизонтально масштабироваться с Kubernetes, мы рассматривали эту настройку аутентификации в качестве главного узкого места.

Другая проблема, с которой мы столкнулись, заключалась в том, что у нас не было механизма для попыток разместить сборки на серверах, где они были ранее построены, вместо этого выбирая первый бесплатный сервер. Это означало, что было очень мало шансов приземлиться на том же сервере и получить полное преимущество кэширования Docker. Хотя для нас это не является нарушением сделки, мы все еще верили, что можем добиться большего успеха при создании версии нашей инфраструктуры сборки. Достаточно теоретического, давайте на самом деле построим что -то!

Приложения для выпуска могут содержать много изображений Docker и одного из наших любимых примеров, чтобы продемонстрировать это наша вилка Пример Voting-App Анкет Глядя на докер-состав Мы видим, что есть 3 разных изображения Docker, которые мы должны построить, результат , голосуйте и работник . Теперь, когда у нас есть понимание оригинальной инфраструктуры релиза и приложения, которое мы хотим построить, давайте запустим новую сборку и увидим результаты.

Примечание Я развел Потрясающее измещение Репо своему собственному GitHub, jer- k Для следующих результатов.

Мы видим, что эта совершенно новая сборка без ударов кэша заняла две минуты и 15 секунд. Далее мы хотим внести несколько изменений, чтобы убедиться, что каждое изображение Docker необходимо восстановить. Изменения перечислены ниже.

git status
On branch release_builders
Changes to be committed:
  (use "git restore --staged ..." to unstage)
    modified:   result/views/index.html
    modified:   vote/app.py
    modified:   worker/src/main/java/worker/Worker.java

Для целей этого поста в блоге я обеспечил следующую сборку на том же застройщике, что и первый, и что у нас будут кеш -хиты. Как отмечалось ранее, это не всегда было в нашей производственной среде.

Кэширование помогает и сокращает 45 секунд от сборки! Uncached Build заняла почти вдвое больше времени, чем вторая сборка с кэшированием, но мы предполагали, что мы могли бы сделать намного лучше (кэшированный и непредвзятый) с некоторыми новыми технологиями.

Одна из первых вещей, которые мы хотели решить, — это проблема параллелизма, и мы решили обеспечить, чтобы сам Docker смог справиться с большей рабочей нагрузкой. Мы наткнулись на проблему Одновременная «Docker Build» занимает больше времени, чем последовательные сборки где люди описывали то, чего мы боялись; Докер замедлился, когда многие сборки работали одновременно. К счастью для нас, этот вопрос был открыт в 2014 году, и было проведено много работы, чтобы решить эту проблему. Последний комментарий, членом команды Docker, был «Закрыть это. BuildKit очень оптимизирован для параллельных рабочих нагрузок. Если вы видите что -то подобное в Buildkit или Buildkit по сравнению с Legacy Builder, сообщите о новой проблеме с делом Repro ». Таким образом, мы решили узнать больше о BUILDKIT (Репозиторий GitHub находится здесь ). Во время исследования мы наткнулись на BUILDX , в конечном итоге, было три ключевых функции, которые, по нашему мнению, решат многие наши проблемы. Эти три особенности были Выпекать команда, BUILDX KUBERNETES драйвер и возможность для драйвера Kubernetes постоянно отправлять сборки на тот же сервер. Давайте рассмотрим каждый из них, сначала вверх Выпекать командование

buildx bake [OPTIONS] [TARGET...]
Bake is a high-level build command.

Each specified target will run in parallel as part of the build.

Выпекать Заинтриговал нас, потому что это казалось для нас встроенной командой, чтобы не использовать рубиновые резьбы для нашего параллелизма. Выпекать берет вклад файла, который может быть либо в форме Docker-Compose В .json , или .hcl . Первоначально мы протестировали Выпекать С помощью Docker-Compose из приложения-приложений, и мы были поражены тем, как плавно он построил непосредственно из коробки и как быстро он смог построить три изображения! Однако мы решили создать наш собственный .json Генератор файлов в Ruby, анализ нашего Шаблон приложения в вывод. Вот наш сгенерированный файл, например, Voting-App.

{
  "group": {
    "default": {
      "targets": [
        "vote",
        "result",
        "worker"
      ]
    }
  },
  "target": {
    "vote": {
      "context": "./vote",
      "tags": [
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/vote:latest",
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/vote:buildx-builders"
      ]
    },
    "result": {
      "context": "./result",
      "tags": [
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/result:latest",
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/result:buildx-builders"
      ]
    },
    "worker": {
      "context": "./worker",
      "tags": [
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/worker:latest",
        ".dkr.ecr.us-west-2.amazonaws.com/jer-k/release-example-voting-app/worker:buildx-builders"
      ]
    }
  }
}

Существуют и другие входные данные, которые могут пробиться в этот файл, например, сборки ARG, но, поскольку пример Voting-App не имеет никакого, они опущены.

Далее мы хотели найти больше информации о драйвере Kubernetes, и мы нашли этот пост в блоге Kubernetes Driver для Docker buildx от автора Получить запрос . Мы рекомендуем вам прочитать последнее, поскольку он покрывает вступление в работу с драйвером Kubernetes, а также к тому, как работает кэширование, что именно нам нужно. С этой информацией мы смогли начать работу над добавлением серверов BuildX в наш кластер. Мы создали общий способ развертывания серверов в разные кластеры и настроить количество реплик с окончательной командой

docker buildx create --name #{name} --driver kubernetes --driver-opt replicas=#{num_replicas},namespace=#{builder_namespace} --use

Для нас мы создали релиз-построитель Пространство имен с пятью репликами, в нашем кластере разработки. Мы можем увидеть выход, запросив стручки

kubectl get pods --namespace=release-builder
NAME                            READY   STATUS    RESTARTS   AGE
development0-86d99fcf46-26j9f   1/1     Running   0          6d10h
development0-86d99fcf46-5scpq   1/1     Running   0          6d13h
development0-86d99fcf46-jkk2b   1/1     Running   0          15d
development0-86d99fcf46-llkgq   1/1     Running   0          18d
development0-86d99fcf46-mr9jt   1/1     Running   0          20d

Поскольку у нас есть пять реплик, мы хотели убедиться, что когда мы создаем приложения, они оказываются на том же сервере, чтобы мы получили максимально возможное количество кэширования (распределенное кэширование является темой для другого дня). К счастью для нас, BUILDX , с драйвером Kubernetes, есть опция для того, чтобы отправить сборки под названием LoadBalance Анкет

loadbalance=(sticky|random) - Load-balancing strategy. 
If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"

По умолчанию липкий означает, что сборки всегда должны оказаться на одном и том же сервере из -за хеширования (более подробная информация об этом описана в вышеупомянутом сообщении в блоге). Со всем этим мы готовы проверить нашу новую установку!

Используя тот же пример-репозиторий, что и раньше, я создал новую филиал buildx_builders и указал код на серверы BUILDX.

Что мы видим, так это то, что эта Uncached Build была более чем в два раза быстрее, чем другая Uncached Build и даже быстрее, чем кэшированная сборка на старой инфраструктуре! Но Uncached Builds должны быть в прошлом с липкой балансировкой нагрузки, поэтому давайте внесем те же изменения, что и в предыдущей ветви, и увидим результаты.

Эта сборка закончилась в три раза быстрее, чем предыдущая кэшированная сборка! Эти типы увеличения скорости являются причиной, по которой мы решили переделать нашу инфраструктуру сборки. Чем быстрее заполняются сборка, тем быстрее мы можем создавать среды и помочь нашим клиентам доставить свои продукты.

Мы все еще экспериментируем с BUILDX и обучение по мере мы, но первоначальных результатов было более чем достаточно для нас, чтобы перенести наши собственные производственные сборки в новую инфраструктуру. Мы будем продолжать вести блог по этой теме, поскольку мы узнаем больше и масштабируем, так что зайдите в блог о выпуске в будущем!

Оригинал: «https://dev.to/jerk/cutting-build-time-in-half-with-docker-s-buildx-kubernetes-driver-1ji1»