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

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


Докерфайл

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


Сборка докера

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

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


Многоэтапные сборки Docker

многоступенчатая сборка докеров

Каждый микросервис должен быть отдельным контейнером. Если вы используете только одноэтапную сборку Docker, вы упускаете некоторые мощные функции процесса сборки. С другой стороны, многоэтапная сборка Docker имеет много преимуществ перед одноэтапной сборкой для развертывания микросервисов.

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

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

Создание двух Dockerfile; один для разработки и один для производства не считается идеальным в мире DevOps, и именно здесь пригодятся многоэтапные сборки Docker, поскольку мы можем создать один оптимизированный файл Dockerfile для всех сред — Dev, Staging и Production.


Примеры многоэтапной сборки Docker


Пример Java:

Чтобы лучше понять концепцию многоэтапных сборок Docker, давайте рассмотрим простое приложение Hello World на Java.

Добавьте следующий код в файл с именем HelloWorld.java

class HelloWorld {
   public static void main(String[] a) {
       System.out.println("Hello world!");
   }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Затем создайте Dockerfile со следующим содержимым:

FROM openjdk:11-jdk
COPY HelloWorld.java .
RUN javac HelloWorld.java
CMD java HelloWorld
Войти в полноэкранный режим

Выйти из полноэкранного режима

Создайте образ с помощью следующей команды:
docker build -t helloworld:huge .

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

FROM openjdk:11-jdk AS build
COPY HelloWorld.java .
RUN javac HelloWorld.java

FROM openjdk:11-jre AS run
COPY --from=build HelloWorld.class .
CMD java HelloWorld
Войти в полноэкранный режим

Выйти из полноэкранного режима

Создайте образ с помощью следующей команды:

docker build -t helloworld:small .

Теперь давайте сравним оба изображения. Проверьте изображения, созданные с помощью следующей команды:

docker images

докер образы

Надеюсь, вы видите разницу в размерах между двумя изображениями. Таким образом, вы можете разделить среды сборки и среды выполнения в одном Dockerfile. Использовать среду сборки в качестве зависимости [COPY --from=build HelloWorld.class .] при создании Dockerfile с подходом многоэтапной сборки Docker. Это поможет минимизировать размер образов Docker.


Пример Node.Js

Давайте научимся на простом приложении NodeJs с простым Dockerfile.

FROM node:14-alpine
ADD . /app
WORKDIR /app
COPY package.json .
RUN npm install --production
COPY . .
EXPOSE 3002
CMD [ "node", "app.js" ]
Войти в полноэкранный режим

Выйти из полноэкранного режима

Давайте создадим образ с помощью следующей команды:
docker build -t [DockerHub username]/image name:tag

Отправьте образ в Docker Hub с помощью команды
docker push [DockerHub username]/image name:tag

Я отправил изображение на DockerHub, и вот изображение и размер ниже,

пример изображения последний

Теперь давайте попробуем использовать концепцию многоэтапной сборки Docker и изменим наш существующий Dockerfile.

FROM node:14-alpine as base
ADD . /app
WORKDIR /app
COPY package.json .
RUN npm install 
FROM alpine:latest
COPY --from=stage1 /app /app
WORKDIR /app
EXPOSE 3002
CMD [ "node", "app.js" ]
Войти в полноэкранный режим

Выйти из полноэкранного режима

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

многоэтапный пример

Теперь сравните размеры изображений. Один с обычным Dockerfile — 48,81 МБ, а другой, созданный с помощью многоэтапной сборки Docker, — 7,12 МБ. Вы видите разницу? Образ, созданный с помощью многоэтапного подхода к сборке Docker, более оптимизирован.

Еще один пример, показывающий, как можно эффективно использовать многоэтапные сборки Docker, — это сценарий, в котором вы хотите разделить файл Dockerfile для разных сред.

Обычный Dockerfile выглядит следующим образом:

FROM node:14-alpine

WORKDIR /src
COPY package.json package-lock.json /src/
RUN npm install --production

COPY . /src

EXPOSE 3000

CMD ["node", "bin/www"]
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы создадим 3 простых этапа из вышеуказанного Dockerfile.

  1. Базовый этап: этот этап будет иметь много общего с исходным Dockerfile.
  2. Стадия производства: Этот этап будет включать в себя вещи, полезные для производственной среды.
  3. Стадия разработки: на этом этапе будут компоненты, полезные для среды разработки.

Измененный файл Dockerfile выглядит следующим образом:

FROM node:14-alpine as base

WORKDIR /src
COPY package.json package-lock.json /src/
EXPOSE 3000

FROM base as production
ENV NODE_ENV=production
RUN npm ci
COPY . /src
CMD ["node", "bin/www"]

FROM base as dev
ENV NODE_ENV=development
RUN npm install -g nodemon && npm install
COPY . /src
CMD ["nodemon", "bin/www"]
Войти в полноэкранный режим

Выйти из полноэкранного режима


Некоторые заметные преимущества использования многоэтапной сборки,

  • Оптимизирует общий размер образа Docker.
  • Устраняет необходимость создания нескольких файлов Dockerfile для разных этапов.
  • Легко отлаживать определенный этап сборки
  • Возможность использовать предыдущую стадию как новую стадию в новой среде
  • Возможность использовать кешированное изображение для ускорения всего процесса
  • Снижает риск обнаружения уязвимостей, поскольку размер образа становится меньше при многоэтапных сборках.


Развертывание приложений с помощью Harness

Подпишитесь на бесплатную пробную версию Упряжь и выберите вкладку TryNextGen для бесперебойной работы. Создайте новый проект и выберите модуль Continuous Delivery. Начните создавать новый конвейер и добавьте все необходимые детали.

Упряжная платформа

выберите этап

Примечание: Чтобы Harness творил чудеса, вам нужно что-то, называемое «Делегатом», которое будет работать в вашем кластере Kubernetes.

Что такое Harness Delegate?
Harness Delegate — это сервис/программное обеспечение, которое необходимо установить/запустить на целевом кластере. [Kubernetes cluster in our case] для подключения ваших артефактов, инфраструктуры, совместной работы, проверки и других поставщиков с Harness Manager. Когда вы настраиваете Harness в первый раз, вы устанавливаете делегата Harness.

Мы не будем углубляться в Delegate в этой статье, так как это может быть отдельный блог. На данный момент просто знайте, что делегат выполняет все операции по развертыванию за вас. Если вы хотите узнать больше о Delegate, вы можете прочитать здесь.

компакт-диск начать

Затем укажите сервис, инфраструктуру и стратегию развертывания для вашего приложения. После того, как все настроено, сохраните конфигурацию и запустите развертывание приложения.

Быстрый старт с компакт-диска

Ну вот! После успешного запуска конвейера вы должны увидеть, что ваше приложение развернуто в указанном кластере Kubernetes. Это можно проверить с помощью команды kubectl «kubectl get pods». Хотите попробовать Harness CD? подписаться на Бесплатная пробная версия компакт-диска Harness.


Вывод

Многоэтапные сборки помогают создавать оптимизированные образы Docker, которые можно запускать где угодно. Если оптимизация доставки программного обеспечения является одной из ваших целей, вам обязательно нужно понять, как работают многоэтапные сборки Docker. Благодаря такому подходу развертывание программного обеспечения может выполняться быстрее, а образ можно повторно использовать для экономии времени и усилий. Многоэтапные сборки — отличный способ упростить процесс создания образов и сэкономить время разработчиков.

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