Сводка процесса уменьшения размера докеров

Docker
Сводка процесса уменьшения размера докеров

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

Почему встроенный образ такой большой?

Прежде чем оптимизировать размер изображения, мы должны сначала узнать, почему созданное нами изображение такое большое? Следующее используется для создания изображения в моем проектеDockerfileдокумент

FROM ruby:2.5.3

RUN apt-get update -y && apt-get install -y \
        build-essential \
	    imagemagick \
        default-libmysqlclient-dev
RUN apt-get install -y \
        nodejs \
        yarn
RUN rm -rf /var/lib/apt/lists/*

WORKDIR /beansmile-web
COPY . /beansmile-web

RUN bundle install

Я определяю файл изображения небрежно, и информация об изображении, которую он создает, выглядит следующим образом:

web1                 latest               1a8a32d5253a        9 hours ago         1.26GB

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

Для приведенного выше файла Dockerfile, я думаю, есть следующие направления оптимизации.

  1. Базовый ruby:2.5.3 основан на buildpack-deps, который содержит множество дополнительных пакетов, возможно, используя более светлый образ, так как базовый образ может еще больше уменьшить пространство.
  2. В файле слишком много команд RUN, и каждая команда будет накладываться друг на друга, что может привести к увеличению объема.
  3. Не рекомендуется копировать весь каталог проекта на зеркало.По мере роста проекта в публичном каталоге проекта Rails могут быть статические ресурсы, такие как изображения.Упаковывать эти вещи в зеркало не имеет смысла.большой.
  4. Можно ли использоватьmulti-stageМетод построения, отбросить какой-то менее критический ресурс, чтобы итоговое изображение было меньше?

Проанализировать раздел ниже.

Специфический анализ

Направление 1: основано на небольших операционных системах

Размер изображения, окончательно построенного в предыдущем примере, очень велик, в основном из-за большого размера самого связанного базового изображения.

REPOSITORY          TAG                  IMAGE ID            CREATED             SIZE
ruby                2.5.3                60c3a1518797        3 weeks ago         871MB
web1                latest               1a8a32d5253a        9 hours ago         1.26GB

Видно, что сам наш базовый образ Ruby имеет размер более 800 М, а процесс сборки образа также требует установки зависимостей, в результате чего получается окончательныйwebОбъем изображения достигнет 1,26G. Этот объем не способствует передаче по сети, сообщил чиновник.Рубиновый базовый образСуществует много версий.В дополнение к различным версиям самого Ruby существует множество базовых образов, созданных для разных операционных систем, и размер базовых образов Ruby, созданных этими разными операционными системами, сильно различается.

REPOSITORY          TAG                  IMAGE ID            CREATED             SIZE
ruby                2.5.3-slim-stretch   20132a4ab93d        2 weeks ago         129MB
ruby                2.5.3                60c3a1518797        3 weeks ago         871MB
ruby                2.5.3-alpine         b3361f13ff1f        3 weeks ago         43.6MB

на основеalpineОбраз Ruby для операционной системы самый маленький — 43,6 МБ.slim-stretchТоже хороший выбор. Возможно, использование более легкого изображения даст возможность для оптимизации.

Советы по опыту:Из моего собственного опыта сборки, используяslim-stretchможет быть, большерядом с людьмивыбора, это линия Debian, менеджер пакетов сubuntuэто то же самоеapt-get, использовал кubuntuопределенно будет чувствовать себя более сердечным.alpineИспользуемый менеджер пакетовapk(Вы думали об установочном пакете Android?), имена некоторых часто используемых пакетов немного отличаются, и их нужно медленно решать самостоятельно. *

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

Направление 2: Уменьшите количество слоев зеркалирования

На официальном сайте Docker сказано, что образ состоит из слоев, доступных только для чтения, и чем меньше слоев, тем выше производительность образа. Это также причина, по которой официально рекомендуется использовать определенный базовый образ для создания собственного образа проекта, а не голый образ ОС (например, образ Ubuntu).

В приведенном выше примере мы использовали триRUNкоманда, это непреднамеренно создаст еще два слоя, на самом деле мы можем объединить их в одинRUNЗаказ

RUN apt-get update -y && apt-get install -y \
        build-essential \
	    imagemagick \
        default-libmysqlclient-dev \
        nodejs \
        yarn \
        && rm -rf /var/lib/apt/lists/*

Воссоздайте изображение на основе этого измененияweb2

REPOSITORY          TAG                  IMAGE ID            CREATED             SIZE
web2                latest               221a316a6903        14 minutes ago      1.25GB
web1                latest               1a8a32d5253a        9 hours ago         1.26GB

Видно, что это изменение не оказывает явного влияния на уменьшение размера зеркального изображения.

Официальное заявление такое

In older versions of Docker, it was important that you minimized the number of layers in your images to ensure they were performant.

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

Направление 3: игнорировать некоторые файлы

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

  • public/: Используется для хранения некоторого каталога некоторых статических файлов, если в каких ресурсах, таких как большое количество картинок, оказывают большое влияние на размер изображения.
  • tmp/: используются для хранения некоторых ресурсов кэша, файлов процесса проекта и т. д. Эти файлы не очень полезны для зеркалирования.
  • log/: Используется для хранения информации, связанной с журналом.

PS: Конечно, каждый рассматривает реальный проект по-разному.Эти каталоги являются только решениями, основанными на моей личной ситуации с проектом, и не являются универсальными.

Чтобы игнорировать эти файлы, мы используем файл с именем.dockerignoreфайл, поместите его в текущую директорию, его запись такая же, как.gitignoreФайл очень похож, содержимое составляет примерно следующим образом

/public/**
/tmp/**
/log/**

затем восстановите образ

web3                latest               fb13cc1301b2        About a minute ago   1.2GB
web2                latest               221a316a6903        23 hours ago         1.25GB
web1                latest               1a8a32d5253a        33 hours ago         1.26GB

Влияние этого метода не очень велико, поскольку в настоящее время доля «мусорных» ресурсов, содержащихся в этих локальных каталогах, невелика.

Направление 4: многоступенчатая схема

Это официально рекомендуемое решение, его можно использовать после Docker17.05.использовать

In Docker 17.05 and higher, you can do multi-stage builds and only copy the artifacts you need into the final image. This allows you to include tools and debug information in your intermediate build stages without increasing the size of the final image.

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

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

Однако в процессе сборки я столкнулся со следующими проблемами.

  • Процесс установки зависимостей с помощью бандлов предполагает не только введение рубинового кода,mysql2иnokogiriПомимо введения кода Ruby, эти сторонние библиотеки также будут скомпилированы во время установки и сгенерируют некоторые общие библиотеки.Если вы копируете зависимые ресурсы из одного образа в другой, вам необходимо скопировать код ruby ​​в каталог, связанный с пакетом. Кроме того, вам придется копировать общие библиотеки, от которых зависят эти сторонние библиотеки, что более проблематично, чем ожидалось.
  • Мы рассчитываем завершить построение статических файлов в одном образе, тогда мы сможем избежать установки nodejs и пряжи в финальном образе для компиляции зависимостей, связанных со статическими ресурсами. Однако позже было решено, что такой подход не подходит. С одной стороны разница между образом с установленным nodejs и зеркалом без установленного nodejs составляет около 30M, с другой стороны необходимо запускатьbin/rails cИспользование среды выполнения JS — важная операция как для разработки, так и для производства, поэтому не рекомендуется отказываться от среды выполнения JS в финальном образе.

Конечная конструкция

Есть 4 направления оптимизации, упомянутые ранее, но кажется, что в итоге только

  • Соберите соответствующий базовый образ более легкой операционной системы.
  • многоступенчатый.

Это оказывает большее влияние на конечный объем зеркала. учитываяmulti-stageПользы от решения может быть не столько хлопот, сколько хлопот, поэтому я окончательно отказался от этого решения, и лучше сразу перейти к самому обтекаемому, чем ходить вот такruby:2.5.3-alpineСоздайте свой собственный образ проекта в качестве базового образа. Самая большая проблема при выборе оптимизированной операционной системы заключается в том, что все основные зависимости в процессе сборки образа проекта приходится решать одну за другой, что требует много времени и сил.Вот Dockerfile, который я получил после повторного тестирования (только к вашему сведению, ведь то, от чего зависит ваш проект, может отличаться)

FROM ruby:2.5.3-alpine

RUN apk --update --upgrade add \
        # bundle 安装相关的依赖
        git \
        curl \
        # mysql2 依赖
        mysql-dev \
        # 基础设施,比如gcc相关的东西
        build-base \
        # nokogiri 相关依赖
        libxslt-dev \
        libxml2-dev \
        # 图片处理相关依赖
        imagemagick \
        # tz相关,如果没有bundle的时候会报错
        tzdata \
        nodejs \
        yarn \
        && rm -rf /var/cache/apk/*

WORKDIR /beansmile-web
COPY . /beansmile-web/
RUN bundle install

Построенное изображение выглядит следующим образом

web4                latest               71b75128d0d9        14 hours ago         586MB

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

Суммировать

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