Оптимизация образов Docker дает множество преимуществ, не только экономя место для хранения и пропускную способность, но и снижая риски безопасности. Существуют различные методы оптимизации размера изображения, которые различаются в зависимости от основного языка разработки, используемого службой. В этой статье будет описано несколько общих подходов к истончению образов Docker. Необходимость уменьшить размер образа Docker Образы Docker состоят из множества слоев (до 127 слоев), а зеркальные слои основаны на ряде базовых технологий, таких как файловые системы, копирование при записи, объединение монтирования и других технологиях, вы можете проверить документацию сообщества Docker. чтобы узнать больше о драйвере хранилища Docker, и я не буду здесь вдаваться в технические подробности. Как правило, каждая инструкция в Dockerfile создает слой образа, который, в свою очередь, увеличивает размер всего образа.
Вот преимущества уменьшения размера образа Docker:
1. Сокращение времени сборки
2. Уменьшите использование диска
3. Сократите время загрузки
4. Поскольку включено меньше файлов, поверхность атаки уменьшается, а безопасность повышается.
5. Повысьте скорость развертывания
Пять советов по уменьшению размера образа Docker 0 1 Оптимизировать базовое изображение Способ оптимизации базового образа заключается в выборе подходящего базового образа меньшего размера.Обычно используемые системные образы Linux — это Ubuntu, CentOs и Alpine, среди которых более рекомендуется Alpine. Сравнение размеров выглядит следующим образом: lynzabo@ubuntu ~/s> образы докеров ТЕГ РЕПОЗИТОРИЯ ИДЕНТИФИКАТОР ИЗОБРАЖЕНИЯ РАЗМЕР СОЗДАН последняя версия Ubuntu 74f8760a2a8b 8 дней назад 82,4 МБ Альпийский последний 11cd0b38bc3c 2 недели назад 4.41MB Centos 7 49f7960eb7e4 7 недель назад 200MB debian последний 3bbb526d2608 8 дней назад 101MB lynzabo@ubuntu ~/s>
Alpine — это облегченный дистрибутив Linux, оптимизированный и включающий в себя базовые инструменты. Размер базового образа составляет всего 4,41 М. Каждый язык разработки и платформа имеют базовый образ, основанный на Alpine, что настоятельно рекомендуется.
Глядя на приведенные выше результаты сравнения размеров изображений, вы обнаружите, что наименьшее изображение также составляет 4,41 МБ, поэтому есть ли способ создать изображение меньшего размера? Ответ — да, например, размер изображения gcr.io/google_containers/pause-amd64:3.1 составляет всего 742 КБ. Почему это изображение такое маленькое? Перед расшифровкой всем рекомендую еще два базовых образа:
скретч-изображение
Scratch — это пустой образ, который можно использовать только для создания других образов.Например, если вы хотите запустить двоичный файл, содержащий все зависимости, например программу Golang, вы можете напрямую использовать скретч в качестве базового образа. Теперь позвольте мне показать вам Dockerfile изображения паузы Google, упомянутый выше:
FROM scratch ARG ARCH ADD bin/pause-${ARCH} /pause ENTRYPOINT ["/pause"]
Изображение паузы Google использует скретч в качестве базового изображения. Само это изображение не занимает места. Размер изображения, построенного с его использованием, почти такой же большой, как и сам двоичный файл, поэтому изображение очень маленькое. Конечно, он также будет использоваться в наших программах на Golang. Для некоторых программ Golang/C могут зависеть некоторые динамические библиотеки.Вы можете использовать инструменты автоматического извлечения динамических библиотек, такие как ldd, linuxdeployqt и т. д., чтобы извлечь все динамические библиотеки, а затем упаковать двоичные файлы и зависимые динамические библиотеки в Изображение.
зеркало бизибокс
Scratch — это пустой образ. Если вы хотите включить в образ некоторые распространенные инструменты Linux, хорошим выбором будет образ busybox. Сам образ имеет размер всего 1,16 МБ, что очень удобно для создания небольших образов.
0 2 Объединение инструкций Dockerfile Когда вы определяете Dockerfile, если вы используете слишком много инструкций RUN, образ часто будет иметь слишком много слоев, образ будет раздут, и вы даже можете столкнуться с проблемой превышения максимального количества слоев (127 слоев). , Следуя рекомендациям Dockerfile, мы должны объединить несколько команд в один RUN (с помощью операторов && и /), каждый RUN должен быть тщательно разработан, чтобы гарантировать очистку установочной сборки в конце, чтобы уменьшить размер образа и максимизировать использование кэша сборки. Вот файл Dockerfile до оптимизации:
FROM ubuntu
ENV VER 3.0.0
ENV TARBALL скачать.Redis.IO/релизы/горячие…
==> Install curl and helper tools...
RUN apt-get update
RUN apt-get install -y curl make gcc
==> Download, compile, and install...
RUN curl -L VER
RUN make
RUN make install
#...
==> Clean up...
WORKDIR /
RUN apt-get remove -y --auto-remove curl make gcc
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /redis-$VER
#...
CMD ["redis-server"]
Создайте образ с именем test/test:0.1.
Мы оптимизируем Dockerfile и оптимизированный Dockerfile:
FROM ubuntu
ENV VER 3.0.0
ENV TARBALL скачать.Redis.IO/релизы/горячие…
RUN echo "==> Install curl and helper tools..." && \
apt-get update &&
apt-get install -y curl make gcc &&
echo "==> Download, compile, and install..." &&
curl -L VER &&
make &&
make install &&
echo "==> Clean up..." &&
apt-get remove -y --auto-remove curl make gcc &&
apt-get clean &&
rm -rf /var/lib/apt/lists/* /redis-$VER
#...
CMD ["redis-server"]
Создайте образ с именем test/test:0.2.
Сравните два размера зеркал:
root@k8s-master:/tmp/iops# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test/test 0.2 58468c0222ed 2 minutes ago 98.1MB test/test 0.1 e496cf7243f2 6 minutes ago 307MB root@k8s-master:/tmp/iops#
Видно, что размер образа, созданного объединением нескольких команд RUN, составляет одну треть от размера каждой команды RUN.
Совет: Чтобы справиться с наличием слишком большого количества слоев изображения в образе, после версии Docker 1.13 предусмотрена функция выравнивания изображения, которая сжимает все операции в Dockerfile в один слой. Эта функция все еще находится на экспериментальной стадии, и Docker не включен по умолчанию. Если вы хотите включить ее, вам нужно добавить параметр -experimental при запуске Docker и добавить --squash, когда сборка Docker создает образ. Мы не рекомендуем использовать этот метод, следуйте рекомендациям при написании файлов Dockerfile и не пытайтесь сжимать изображения таким образом.
0 3 Используйте многоэтапные сборки Каждая инструкция в Dockerfile добавляет слой изображения к образу, и вам нужно очистить ненужные компоненты, прежде чем переходить к следующему слою образа. На самом деле, есть Dockerfile для разработки (который содержит все необходимое для создания вашего приложения) и тонкий клиент для производства, который содержит только ваше приложение и то, что вам нужно для его запуска. Это называется "режим строителя". Docker 17.05.0-ce позже поддерживает многоэтапные сборки. При многоэтапных сборках вы можете использовать несколько операторов FROM в файле Dockerfile, а каждая инструкция FROM может использовать отдельный базовый образ, так что вы можете выборочно КОПИРОВАТЬ сервисные компоненты с одного этапа на другой, только в конечном образе. нужно. Вот Dockerfile с использованием COPY --from и FROM... AS...:
Compile
FROM golang:1.9.0 AS builder WORKDIR /go/src/v9.git...com/.../k8s-monitor COPY . . WORKDIR /go/src/v9.git...com/.../k8s-monitor RUN make build RUN mv k8s-monitor /root
Package
Use scratch image
FROM scratch WORKDIR /root/ COPY --from=builder /root . EXPOSE 8080 CMD ["/root/k8s-monitor"]
Создайте образ, вы обнаружите, что сгенерированный образ имеет только содержимое, указанное командой COPY выше, а размер изображения составляет всего 2M. То, что раньше было двумя файлами Dockerfile (один файл Dockerfile для разработки и один тонкий клиент для производства), теперь можно выполнить с помощью многоэтапной сборки.
0 4 Развитие навыков зеркалирования бизнес-сервисов Когда Docker строит образ, если содержимое, относящееся к определенной команде, не меняется, он будет использовать файловый слой последнего кеша (cache).При построении бизнес-образа можно обратить внимание на следующие два момента:
1. Отдельные крупномасштабные зависимые библиотеки, которые не меняются или меняются очень мало, от собственного кода, который часто модифицируется;
2. Поскольку кеш кэшируется на локальном компьютере, на котором запущена команда сборки Docker, рекомендуется использовать определенный компьютер для сборки Docker, чтобы использовать кеш.
Ниже приведен пример создания образа приложения Spring Boot, чтобы проиллюстрировать, как создавать слои. Другие типы приложений, такие как пакеты Java WAR, модули Nodejs npm и т. д., могут использовать аналогичный подход.
1. В каталоге, где находится Dockerfile, разархивируйте пакет jar, сгенерированный maven.
$ unzip .jar -d app
2. Dockerfile Разделяем содержимое приложения на 4 части и копируем их в образ: первые 3 принципиально неизменны, а четвертая — это часто меняющийся собственный код. Последняя строка — это способ запуска приложения весенней загрузки после распаковки.
FROM openjdk:8-jre-alpine
LABEL maintainer "opl-xws@xiaomi.com" COPY app/BOOT-INF/lib/ /app/BOOT-INF/lib/ COPY app/org /app/org COPY app/META-INF /app/META-INF COPY app/BOOT-INF/classes /app/BOOT-INF/classes EXPOSE 8080 CMD ["/usr/bin/java", "-cp", "/app", "org.springframework.boot.loader.JarLauncher"]
Это может значительно повысить скорость сборки при создании образов.
0 5 Другие методы оптимизации Конечно, в дополнение к вышеупомянутым четырем типам методов существуют и другие методы оптимизации для упрощения изображения;
- Выполнение навыков инструмента apt, apk или yum в команде RUN Если вы запускаете инструменты apt, apk или yum в команде RUN, вы можете использовать некоторые советы, предоставляемые этими инструментами, чтобы уменьшить количество слоев изображения и размер изображения. Приведу несколько примеров:
(1) Добавьте опцию- no-install-recommends при выполнении apt-get install -y, вы можете установить рекомендуемые (необязательные) зависимости или добавить опцию--no-cache при выполнении apk add для достижения тот же эффект;
(2) При выполнении yum install -y вы можете одновременно установить несколько инструментов, например yum install -y gcc gcc-c++ make .... Поместите все задачи установки yum в одну команду RUN, чтобы уменьшить количество зеркальных слоев;
(3) Установка и очистка компонентов должны быть объединены в одну инструкцию, например apk --update add php7 && rm -rf /var/cache/apk/* , поскольку каждая инструкция Dockerfile будет генерировать файловый слой, если apk Команды add ... и rm -rf ... являются отдельными, и очистка не может уменьшить размер файлового слоя, созданного командой apk. Ubuntu или Debian могут использовать rm -rf /var/lib/apt/lists/* Очистите файлы кеша в зеркале; такие системы, как CentOS, используют для очистки команду yum clean all. 2. Сжать изображение Некоторые команды, поставляемые с Docker, также могут помочь в сжатии изображений, например экспорт и импорт.
docker export 747dc0e72d13 | docker import - test/test:0.3
Использование этого метода требует предварительного запуска контейнера, и в этом процессе будет потеряна некоторая исходная информация об образе, например экспортные порты, переменные среды и инструкции по умолчанию.
Проверьте информацию об истории этих двух зеркал, как показано ниже, вы можете видеть, что test/test:0.3 потерял всю информацию о зеркальном слое:
root@k8s-master:/tmp/iops# docker history test/test:0.3
IMAGE CREATED CREATED BY SIZE COMMENT
6fb3f00b7a72 15 seconds ago 84.7MB Imported from -
root@k8s-master:/tmp/iops# docker history test/test:0.2
IMAGE CREATED CREATED BY SIZE COMMENT
58468c0222ed 2 hours ago /bin/sh -c #(nop) CMD ["redis-server"] 0B
1af7ffe3d163 2 часа назад /bin/sh -c echo "==> Установить curl и helper… 15.7MB
8bac6e733d54 2 часа назад /bin/sh -c #(nop) ENV TARBALL=http://downlo… 0B
793282f3ef7a 2 hours ago /bin/sh -c #(nop) ENV VER=3.0.0 0B
74f8760a2a8b 8 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
8 дней назад /bin/sh -c mkdir -p /run/systemd && echo 'сделать… 7B
8 дней назад /bin/sh -c sed -i 's/^#\s*(deb.вселенная)$… 2.76kB
8 дней назад /bin/sh -c rm -rf /var/lib/apt/lists/0В
8 дней назад /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B
8 дней назад /bin/sh -c #(nop) ДОБАВИТЬ файл:5fabb77ea8d61e02d… 82.4MB
root@k8s-master:/tmp/iops#
Также в сообществе есть множество инструментов сжатия, например Docker-squash, который проще и удобнее в использовании, и не потеряет информацию исходного образа.Если интересно, можете попробовать.
Суммировать
Методы оптимизации и эффекты образов Docker заслуживают подробного обсуждения и практики, и я надеюсь, что эта статья поможет вам. Если у вас есть лучший метод и опыт, добро пожаловать на обмен ~