Более быстрые конвейеры CI/CD с Docker

Проблема

Одним из ключевых методов быстрого продвижения в разработке программного обеспечения является непрерывная поставка. Однако уход за агентами сборки — рутинная работа. Докер помогает в этом, сохраняя простой агент сборки и помещая все инструменты сборки в образ Docker. Однако это влечет за собой новую проблему — скорость. Создание зависимостей от нового агента сборки может занять довольно много времени, особенно в Java. В этой статье показано, как ускорить сборку с помощью некоторых функций Docker.

Чем отличается этот подход?

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

Стек технологий

Мы рассмотрим примеры в

  • Рубин
  • Питон
  • Ява
  • JavaScript

Все будут использовать Docker, и мы добавим такие сервисы AWS, как CodePipeline, КодБилд а также Реестр эластичных контейнеров (ECR) в качестве простого примера того, как запустить конвейер сборки.

мельчайшие детали

Разные языки программирования имеют разные системы управления зависимостями пакетов:

Для целей установки зависимостей все они делают примерно одно и то же:

  • посмотрите в файле конфигурации зависимости, которые вы объявили
  • иди и найди пакеты для этих зависимостей в официальном репозитории
  • загрузите их в свою локальную систему
  • сделать их доступными для вашего кода

Например, если я хочу использовать Redux в своем приложении JS React, я могу yarn add react-redux и я закончу с package.json файл, содержащий ссылку на react-redux (а также локальную установку в моем node_modules). Поскольку я не хочу полагаться на то, что люди будут помнить о правильной установке при развертывании на серверах, я не храню все зависимости в git; я просто храню package.json файл. Если кто-то получит мой код с GitHub, он сможет yarn install и они получат избыточность (вместе со всеми остальными вещами в package.json файл).

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

Докер спешит на помощь

В Docker есть две полезные функции:

Если мы возьмем Java в качестве примера, мы можем использовать следующее Dockerfile.tests для запуска наших тестов:

FROM openjdk:8-jdk-alpine
RUN apk update
RUN apk add maven
WORKDIR /opt/code
COPY ./pom.xml .
RUN mvn dependency:go-offline
COPY . .

Это означает, что зависимости приходят с RUN mvn dependency:go-offline но остальная часть нашего кода приходит с COPY . . (поэтому зависимости остаются на предыдущем уровне).

Затем мы можем предоставить конфигурацию CI, которая использует docker build с --cache-from чтобы убедиться, что нам нужно запускать уровень зависимостей только при изменении зависимостей.

В качестве примера опишем пару конфигураций CodeBuild. Если предположить, что у нас есть репозиторий ECR, настроенный по адресу 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-imgмы можем настроить несколько шагов в CodePipeline:

  • Шаг 1: получите исходный код из системы управления версиями (например, GitHub)
  • Шаг 2: используйте стандартный контейнер CodeBuild для создания тестового образа докера.
  • Шаг 3: используйте новый тестовый образ непосредственно в CodeBuild для запуска тестов.

Шаг 1

Создайте веб-перехватчик GitHub через CodePipeline. Это можно сделать в консоли, через кли или с CloudFormation

Шаг 2

это пример спецификация сборки который входит в ECR, извлекает последний тестовый образ, создает новый тестовый образ, используя последний в качестве кеша, и отправляет новый в ECR:

phases:
  pre_build:
    commands:
      - $(aws ecr get-login --no-include-email --region ap-southeast-2)
      - docker pull 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-img:latest
  build:
    commands:
      - docker build --tag 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-img:latest --file Dockerfile-tests --cache-from 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-img:latest .
  post_build:
    commands:
      - docker push 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-img:latest

Шаг 3

Спецификация сборки для запуска тестов на следующем шаге CodePipeline проста, если шаг настроен на использование 999999999.dkr.ecr.ap-southeast-2.amazonaws.com/some-img:latest изображение, которое мы только что создали:

phases:
  build:
    commands:
      - mvn test

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

Рубин:

COPY ./Gemfile .
RUN bundle install
COPY . .

Питон:

COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .

JavaScript:

COPY ./package.json .
RUN yarn install
COPY . .

и т.п.

Заключительные мысли и следующие шаги

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

Обо мне

Я главный инженер, с опытом программирования на Java, Python, Ruby, JavaScript и C#, со слабым знанием LabVIEW, C++, VisualBasic и ColdFusion. Я баловался Хаскеллом.

У меня есть большой опыт работы с AWS и некоторые знания в Azure и GCP.


Приложение — Технология, упомянутая в этом посте

Докер

Docker — это способ упаковки приложений в контейнер который включает все файлы, необходимые для запуска приложения, включая файлы операционной системы, но не ядро ​​операционной системы. Напротив, виртуальная машина (ВМ) содержит ядро ​​и виртуализированные аппаратные интерфейсы.

Веб-сервисы Амазонки

АВС — это облачные сервисы провайдер, где вычислительная мощность, сетевые и другие услуги предоставляются по запросу. Это позволяет использовать инфраструктуру как код и помогает командам тратить время на решение проблем клиентов, а не на обслуживание центров обработки данных.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *