В процессе создания контейнера всегда невозможно построить зеркало, а увеличенное изображение способно повысить эффективность передачи в дополнение к экономии дискового пространства машины. В этой статье в основном хочется рассказать о принимаемых мерах при оптимизации размера изображения, конечно же, не все программы оказывают существенное влияние на уменьшение размера зеркала, и конкретные проекты также следует специально анализировать. В этой статье я использую зеркалирование проекта 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, я думаю, есть следующие направления оптимизации.
- Базовый ruby:2.5.3 основан на buildpack-deps, который содержит множество дополнительных пакетов, возможно, используя более светлый образ, так как базовый образ может еще больше уменьшить пространство.
- В файле слишком много команд RUN, и каждая команда будет накладываться друг на друга, что может привести к увеличению объема.
- Не рекомендуется копировать весь каталог проекта на зеркало.По мере роста проекта в публичном каталоге проекта Rails могут быть статические ресурсы, такие как изображения.Упаковывать эти вещи в зеркало не имеет смысла.большой.
- Можно ли использовать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
Это сэкономит вам больше времени.