Docker автоматически строит изображения, чтение инструкций из DockerFile — текстовый файл, который содержит все команды, в порядке, необходимых для создания данного изображения.
Объяснение выше было извлечено из докера Официальные документы И суммирует то, для чего есть DockerFile. DockerFiles важно работать с тем, что они находятся наш план, наша запись слоев, добавленных к одному образу докера.
Мы узнаем, как воспользоваться Buildkit Особенности, набор улучшений введен на Docker V18.09. Интеграция BuildKit предоставит нам лучшую производительность, управление хранением и безопасность.
Цели
- уменьшить время сборки;
- уменьшить размер изображения;
- Обслуживание усиления;
- получить воспроизводимость;
- понять многоступенчатые докера;
- понять функции Buildkit.
До реквизиты
- Знание концепций докеров
- Docker установлен (в настоящее время используя V19.03)
- Приложение Java (для этого поста я использовал Пример jenkins Maven )
Давайте доберемся до этого!
Простой пример докерафила
Ниже приведен пример неоптимизированного докерафила, содержащего приложение Java. Этот пример был взят из Этот разговор конференции Dockercon . Мы пройдем через несколько оптимизаций, поскольку мы идем.
FROM debian COPY . /app RUN apt-get update RUN apt-get -y install openjdk-11-jdk ssh emacs CMD ["java", "-jar", "/app/target/my-app-1.0-SNAPSHOT.jar"]
Здесь мы можем спросить себя: Сколько времени нужно, чтобы построить на данном этапе? Чтобы ответить на него, давайте создадим этот докер на нашем локальном компьютерном компьютере и скажу докера, чтобы построить изображение.
# enter your Java app folder cd simple-java-maven-app-master # create a Dockerfile vim Dockerfile # write content, save and exit docker pull debian:latest # pull the source image time docker build --no-cache -t docker-class . # overwrite previous layers # notice the build time
0,21S User 0,23S Система 0% CPU 1: 55,17 Всего
Вот наш ответ: наша сборка берет 1m55s в этот момент.
Но что, если мы просто включим Buildkit без дополнительных изменений? Есть ли разница?
Включение Buildkit.
Buildkit можно включить с двумя методами:
- Установка переменной среды при вызове команды Docker Build, например:
time DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class .
- Включение Docker Buildkit по умолчанию, устанавливая конфигурацию демона в
/etc/docker/daemon.json
Функция правда и перезапустить демону:
{ "features": { "buildkit": true } }
Buildkit Первоначальное воздействие
DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class .
0,54s User 0,93S Система 1% CPU 1: 43,00 Всего
На том же оборудовании сборка заняла ~ 12 секунд меньше, чем раньше. Это означает, что сборка получила ~ 10,43% быстрее почти без усилий.
Но теперь давайте посмотрим на некоторые дополнительные шаги, мы можем еще больше улучшить наши результаты.
Заказ от наименьшего количества часто меняющихся
Потому что на заказ имеет значение для кэширования, мы переместим Скопировать
Команда ближе к концу DockerFile.
FROM debian RUN apt-get update RUN apt-get -y install openjdk-11-jdk ssh emacs RUN COPY . /app CMD ["java", "-jar", "/app/target/my-app-1.0-SNAPSHOT.jar"]
Избегать «копирования».
Выберите более конкретные копии аргументов для ограничения бюстов кэша. Только копировать то, что нужно.
FROM debian RUN apt-get update RUN apt-get -y install openjdk-11-jdk ssh vim COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Пара APT-Get Update & установка
Это предотвращает использование устаревшего кэша пакета. Кэшируйте их вместе или не кэшируйте их вообще.
FROM debian RUN apt-get update && \ apt-get -y install openjdk-11-jdk ssh vim COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Удалить ненужные зависимости
Не устанавливайте инструменты отладки и редактирования — вы можете установить их позже, когда вы чувствуете, что они нуждаются в них.
FROM debian RUN apt-get update && \ apt-get -y install --no-install-recommends \ openjdk-11-jdk COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Удалить кеш менеджера пакета
Ваше изображение не нуждается в этих данных кэша. Возьмите шанс освободить некоторое пространство.
FROM debian RUN apt-get update && \ apt-get -y install --no-install-recommends \ openjdk-11-jdk && \ rm -rf /var/lib/apt/lists/* COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Используйте официальные изображения, где это возможно
Существуют некоторые веские причины использования официальных изображений, таких как уменьшение времени, натраченного на обслуживание и уменьшение размера, а также имея изображение, которое предварительно настроено для использования контейнера.
FROM openjdk COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Используйте определенные теги
Не используйте Последние
Как это прокат. Это просит непредсказуемые проблемы.
FROM openjdk:8 COPY target/my-app-1.0-SNAPSHOT.jar /app CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Ищите минимальные ароматы
Вы можете уменьшить размер базового изображения. Выберите самый легкий, который подходит для вашей цели. Ниже короткий OpenJDK
Список изображений.
8 | 634 МБ. | openjdk. |
8-jre. | 443 МБ | openjdk. |
8-Jre-Slim | 204 МБ | openjdk. |
8-JRE-ALPINE | 83 МБ. | openjdk. |
Построить из источника в последовательной среде
Может быть, вам не нужен весь JDK. Если вы намереваетесь использовать JDK для Maven, вы можете использовать изображение Maven Docker в качестве основы для вашей сборки.
FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Получить зависимости на отдельном шаге
Команда DockerFile для получения зависимостей может быть кэширована. Кэширование этого шага ускорит наши сборки.
FROM maven:3.6-jdk-8-alpine WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package CMD ["java", "-jar", "/app/my-app-1.0-SNAPSHOT.jar"]
Многоступенчатые сборки: удалить зависимости сборки
Зачем использовать многоступенчатые сборки?
- Отделите сборку из среды выполнения
- СУХОЙ
- Различные детали на разработке, тестировании, специфической среде
- Грященные зависимости (параллелизм)
- наличие платформы-специфических этапов
FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn -e -B dependency:resolve COPY src ./src RUN mvn -e -B package FROM openjdk:8-jre-alpine COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar / CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"]
Пропускной пункт
Если вы создаете наше приложение в этот момент,
time DOCKER_BUILDKIT=1 docker build --no-cache -t docker-class .
0,41S User 0,54S Система 2% CPU 35,656 Всего
Вы заметите, что наше приложение берет ~ 35,66 секунды строить. Это приятное улучшение. Отныне мы сосредоточимся на функциях для более возможных сценариев.
Многоэтапные сборки: разные ароматизаторы изображения
Приведенный ниже DockerFile показывает другой этап для Debian и альпийского изображения.
FROM maven:3.6-jdk-8-alpine AS builder … FROM openjdk:8-jre-jessie AS release-jessie COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar / CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"] FROM openjdk:8-jre-alpine AS release-alpine COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar / CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"]
Чтобы построить определенное изображение на сцене, мы можем использовать --target
Аргумент:
time docker build --no-cache --target release-jessie .
Различные ароматизаторы изображения (сухой/глобальный arg)
ARG flavor=alpine FROM maven:3.6-jdk-8-alpine AS builder … FROM openjdk:8-jre-$flavor AS release COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar / CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"]
Arg
Команда может контролировать изображение, которое будет построен. В приведенном выше примере мы написали альпийский
как вкус по умолчанию, но мы можем пройти --build-arg вкус = <вкус>
на Docker Build
команда.
time docker build --no-cache --target release --build-arg flavor=jessie .
Параллельность
СООТВЕТСТВЕННОСТЬ важно при создании докеровских изображений, поскольку требуется наибольшее преимущество в доступных потоках CPU. В линейном доке докера все этапы выполняются в последовательности. С Multi-Stophing Builds мы можем быть готовы к меньшим этапам зависимости для их использования.
Buildkit даже приводит к другому бонусу производительности. Если этапы не используются позже в сборке, они напрямую пропущены вместо обработки и выброшены при заканчивании. Это означает, что на этапе представления графика ненужные этапы даже не рассматриваются.
Ниже приведен пример DockerFile, где активы веб-сайта встроены в ресурсы
сцена:
FROM maven:3.6-jdk-8-alpine AS builder … FROM tiborvass/whalesay AS assets RUN whalesay "Hello DockerCon!" > out/assets.html FROM openjdk:8-jre-alpine AS release COPY --from=builder /app/my-app-1.0-SNAPSHOT.jar / COPY --from=assets /out /assets CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"]
И вот еще один докер, где C и C ++ библиотеки отдельно скомпилированы и принимают участие в строитель
этап позже.
FROM maven:3.6-jdk-8-alpine AS builder-base … FROM gcc:8-alpine AS builder-someClib … RUN git clone … ./configure --prefix=/out && make && make install FROM g++:8-alpine AS builder-some CPPlib … RUN git clone … && cmake … FROM builder-base AS builder COPY --from=builder-someClib /out / COPY --from=builder-someCpplib /out /
Кэш приложения Buildkit.
Buildkit имеет специальную функцию, касающуюся кэша менеджеров пакетов. Вот несколько примеров папок кэша типичных местоположений:
/ var / lib / apt / lists | доп |
~ / .cache / go-build | идти |
$ Gopath / pkg / мод | Go-модули |
~ / .npm. | NPM |
~ / .cache / pip | пипс |
Мы можем сравнить этот докер с тем, который представлен в разделе Построить из источника в последовательной среде Отказ Это ранее докерфила не было специального обращения с кэш. Мы можем сделать это с типом горы под названием Cache: - mount = type = cache
Отказ
FROM maven:3.6-jdk-8-alpine AS builder WORKDIR /app RUN --mount=target=. --mount=type=cache,target /root/.m2 \ && mvn package -DoutputDirectory=/ FROM openjdk:8-jre-alpine COPY --from=builder /app/target/my-app-1.0-SNAPSHOT.jar / CMD ["java", "-jar", "/my-app-1.0-SNAPSHOT.jar"]
Построить секретные объемы
Для смешивания в некоторых функциях безопасности PublyKit, давайте посмотрим, как используются крепления секретного типа, и некоторые случаи они предназначены для. Первый сценарий показывает пример, где нам нужно скрыть файл секретов, как ~/.aws/учетные данные
Отказ
FROMRUN … RUN --mount=type=secret,id=aws,target=/root/.aws/credentials,required \ ./fetch-assets-from-s3.sh RUN ./build-scripts.sh
Чтобы построить этот докер, пройдите --secret
Аргумент как это:
docker build --secret id=aws,src=~/.aws/credentials
Второй сценарий — это метод, чтобы избежать команд, таких как Скопируйте./Keys/Private.pem/root .ssh/Private.pem
, Поскольку мы не хотим, чтобы наши SSH ключей храниться на образе докера после того, как они больше не нужны. Buildkit имеет SSH
Тип крепления, чтобы покрыть это:
FROM alpine RUN apk add --no-cache openssh-client RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts ARG REPO_REF=19ba7bcd9976ef8a9bd086187df19ba7bcd997f2 RUN --mount=type=ssh,required git clone git@github.com:org/repo /work && cd /work && git checkout -b $REPO_REF
Чтобы построить этот докер, вам нужно загрузить свой частный ключ SSH в свой SSH-агент
и добавить --ssh = по умолчанию
, с по умолчанию
Представляя местоположение частного ключа SSH.
eval $(ssh-agent) ssh-add ~/.ssh/id_rsa # this is the SSH key default location docker build --ssh=default .
Заключение
Это завершает нашу демонстрацию по использованию Docker Buildkit для оптимизации ваших Dockerfiles и, следовательно, ускорить время сборки ваших изображений.
Эти скорость получают привести к значительному экономии во времени и вычислительной мощности, которые не следует пренебрегать.
Как и Чарльз Дюхигг писал на силу привычки: « Маленькие победы — это последовательное применение небольшого преимущества ». Вы определенно пожнете преимущества, если создаете передовые практики и привычки.
Оригинал: «https://dev.to/jscrambler/dockerfile-optimization-for-fast-builds-and-light-images-3p34»