Рубрики
Uncategorized

Сокращение Времени создания изображения Docker за счет использования Механизма Кэша построения

Автор оригинала: David Wong.

При использовании Docker для развертывания PHP или node.js приложения, распространенный метод заключается в том, чтобы упаковать код и образы среды в зеркало и запустить. Некоторые облачные поставщики обеспечивают очень удобную работу, просто отправьте наш код в VCS, затем они помогут нам извлечь код замены и создать наш образ в соответствии с файлом Dockerfile в пакете кода и развернуть его в кластере.

PHP и узел. У JS очень хорошая экология, с множеством пакетов, но как только появятся новые пакеты, файлы в нашем проекте станут очень большими, поэтому при использовании совместной работы с VCS мы будем игнорировать каталог пакетов зависимостей (node_modules/поставщик). Но мы забыли использовать composer или NPM для перезагрузки пакета при создании образа после каталога пакета, поэтому файл Dockerfile, вероятно, будет выглядеть так.

FROM node
COPY . /src
RUN cd /src && npm install

Это не кажется проблемой, но если для установки дополнительных пакетов требуется много времени и ожидания исправления аварийной ошибки, есть ли какой-либо способ ускорить процесс?

Мы знаем, что сборки Docker являются многоуровневыми, одним слоем инструкций, без полосы. --no-cache=true Докер не будет перестраивать этот слой, но будет использовать кэширование, если слой не будет изменен в случае инструкций. Давайте сначала рассмотрим описание официальных документов Докера.

  • Начиная с родительского изображения, которое уже находится в кэше, следующая инструкция сравнивается со всеми дочерними изображениями, полученными из этого базового изображения, чтобы увидеть, было ли одно из них построено с использованием точно такой же инструкции. Если нет, кэш будет признан недействительным.
  • В большинстве случаев достаточно просто сравнить инструкцию в файле Dockerfile с одним из дочерних изображений. Однако некоторые инструкции требуют дополнительного изучения и объяснения.
  • Для инструкций по ДОБАВЛЕНИЮ и КОПИРОВАНИЮ проверяется содержимое файла(файлов) на изображении и вычисляется контрольная сумма для каждого файла. Время последнего изменения и последнего доступа к файлам не учитывается в этих контрольных суммах. Во время поиска в кэше контрольная сумма сравнивается с контрольной суммой в существующих изображениях. Если в файле(файлах) что-либо изменилось, например содержимое и метаданные, кэш будет признан недействительным.

Проще говоря, если произойдет изменение в слое n, кэш после слоя N выйдет из строя. В большинстве случаев способ определить, произошло ли изменение, состоит в том, чтобы определить, соответствуют ли инструкции на этом уровне инструкциям по построению в кэше. Но для команд КОПИРОВАНИЯ и ДОБАВЛЕНИЯ вычисляется контрольная сумма файлов в зеркальном отображении и файлов каталога построения, а затем проводится сравнение, чтобы определить, есть ли изменения в этом слое.

В идеале мы надеемся, что package.json возможно composer.json Установочные пакеты будут переустановлены при внесении изменений, а кэширование используется для сокращения времени сборки без изменений.

После понимания приведенных выше правил давайте посмотрим на файл Dockerfile выше. Если мы не изменим код, вторая сборка также может использовать кэширование, но если мы изменим код, COPY ./src кэш этого слоя выйдет из строя, а кэш следующего слоя выйдет из строя. Но в большинстве случаев восстановление образа означает, что код был изменен, но package.json и composer.json Эти два файла меняются нечасто, поэтому нам нужно отделить два файла от операции установки, поэтому есть

FROM node

COPY package.json /src/package.json
RUN cd /src && npm install

COPY . /src

оставайтесь package.json Напишите пакет зависимостей внутри

{
  "dependencies": {
    "express": "^4.16.4"
  }
}

Затем напишите один index.js

const app = require('express')();

app.listen(8080)

А потом мы построим его в первый раз, посмотрите на него. докер история Вывод

LIN2UR:~ lin2ur$ docker history demo
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
3c913c9e997b        6 seconds ago       /bin/sh -c #(nop) COPY dir:e3c12f06720cf5f3b…   1.6MB               
21373087419a        6 seconds ago       /bin/sh -c cd /src && npm install               3MB                 
64896ee5240d        14 seconds ago      /bin/sh -c #(nop) COPY file:87de28b86afd2c1c…   53B                               

Идентификатор ИЗОБРАЖЕНИЯ каждого слоя соответствует инструкциям в файле Dockerfile 64896ee5240d => КОПИРОВАТЬ пакет.json/src/package.json 21373087419a => ЗАПУСТИТЬ cd/src и & npm установить 3c913c9e997b => КОПИРОВАТЬ ./src

Теперь давайте пересмотрим его. index.js Смоделируйте изменения в нашем бизнес-коде, а затем создайте его

LIN2UR:~ lin2ur$ docker history demo
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
5d697905ad0a        6 seconds ago       /bin/sh -c #(nop) COPY dir:d698db67dac047bd2…   1.6MB               
21373087419a        4 minutes ago       /bin/sh -c cd /src && npm install               3MB                 
64896ee5240d        4 minutes ago       /bin/sh -c #(nop) COPY file:87de28b86afd2c1c…   53B                                

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

LIN2UR:~ lin2ur$ docker build --rm -f "Dockerfile" -t demo .
Sending build context to Docker daemon  1.902MB
Step 1/4 : FROM node
 ---> c63e58f0a7b2
Step 2/4 : COPY package.json /src/package.json
 ---> Using cache
 ---> 64896ee5240d
Step 3/4 : RUN cd /src && npm install
 ---> Using cache
 ---> 21373087419a
Step 4/4 : COPY . /src
 ---> 5d697905ad0a
Successfully built 5d697905ad0a
Successfully tagged demo:latest

Как вы можете видеть, на этапах 2 и 3 используется кэширование, которое намного короче, чем при первой сборке. Теперь мы package.json Добавляем пакет для имитации изменений пакета зависимостей

LIN2UR:~ lin2ur$ docker history demo
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
020ce95b1987        29 seconds ago      /bin/sh -c #(nop) COPY dir:ea4d7afd475895520…   1.6MB               
d9697dfc7022        31 seconds ago      /bin/sh -c cd /src && npm install               3MB                 
71d8a2fb458a        38 seconds ago      /bin/sh -c #(nop) COPY file:87bd25345a96e6b3…   51B                 

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

LIN2UR:~ lin2ur$ docker build --rm -f "Dockerfile" -t demo .
Sending build context to Docker daemon  1.902MB
Step 1/4 : FROM node
 ---> c63e58f0a7b2
Step 2/4 : COPY package.json /src/package.json
 ---> 71d8a2fb458a
Step 3/4 : RUN cd /src && npm install
 ---> Running in ce424d6af936
Step 4/4 : COPY . /src
 ---> 020ce95b1987
Successfully built 020ce95b1987
Successfully tagged demo:latest

Из-за второго этажа package.json Изменения делают недействительными этот слой и последующие кэши, а затем переустановите пакет для достижения желаемых результатов.