img

Кэш Docker: как выполнить повторную сборку образа и очистить кэш Docker

21 ноября
20:00
Бесплатный вебинар
Введение в Docker
Ведущий — Филипп Игнатенко.
Руководитель центра разработки
Записаться
img
img

 

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

Кэш сборки 

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

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

Как оптимизировать кэш сборки

Для того, чтобы понять, в чем заключаются проблемы, связанные с кэшем сборки Docker, давайте создадим собственное простенькое приложение Docker для ngnix. Прежде чем мы приступим к созданию образа, нам нужно создать Dockerfile, который отвечает за обновление библиотек и добавление пользовательской начальной страницы:

FROM nginx:1.21.6

# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>My Custom Startpage</body></html>' > /usr/share/nginx/html/index.html

Теперь мы можем создать образ Docker:

$  docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e12...  5.8s
=> [2/3] RUN apt-get update && apt-get -y upgrade           3.6s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...        0.2s

=> exporting to image                                       0.1s
=> exporting layers                                         0.1s
=> writing image                                            0.0s
=> naming to docker.io/library/my-custom-nginx

[+] Building 11.3s (7/7) FINISHED

В данном примере я удалил часть вывода для того, чтобы его было проще читать. Если вы создаете образ впервые, то вы могли заметить, что этот процесс занимает довольно много времени – в данном случае 11.3s.

Самый долгий шаг - apt-get update && apt-get -y upgrade. Время его выполнения зависит от того, сколько зависимостей обновляется и насколько высока скорость вашего интернета. Эта команда проверяет наличие обновлений пакетов в операционной системе и устанавливает их при их наличии.

А теперь вы можете выполнить эту команду снова и выиграть время, воспользовавшись кэшем сборки:

$ docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1…   0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade        0.0s
=> CACHED [3/3] RUN echo '<html><bod>My Custom Startpage...     0.0s

=> exporting to image                                           0.0s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 1.1s (7/7) FINISHED

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

FROM nginx:1.21.6

# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>New Startpage</body></html>' > /usr/share/nginx/html/index.html

А теперь снова создадим образ:

$ docker build -t my-custom-nginx .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1…   0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade        0.0s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...            0.2s

=> exporting to image                                           0.0s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 2.1s (7/7) FINISHED

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

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

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

Как использовать параметр --no-cache для сборки Docker

Причины отключения кэширования сборки могут быть самые разные. Вы можете повторно произвести сборку образа на базе основного образа, не используя при этом кэшированные слои, но используя при этом параметр --no-cache

$ docker build -t my-custom-nginx .

=> CACHED [1/3] FROM docker.io/library/nginx:1.21.6@sha256:...  0.0s
=> [2/3] RUN apt-get update && apt-get -y upgrade               3.5s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...            0.2s

=> exporting to image                                           0.1s
=> exporting layers                                             0.0s
=> writing image                                                0.0s
=> naming to docker.io/library/my-custom-nginx

Building 5.5s (7/7) FINISHED

Здесь были построены и созданы новые слои. docker build запустила в этот раз обе команды, то есть применила подход «все или ничего». Либо вы указываете параметр --no-cache, который позволит выполнить все команды, либо вы кэшируете по максимуму.

Как применить аргументы Docker для очистки кэша

Другой вариант позволяет создать некую отправную точку в Dockerfile. Для этого вам нужно изменить Dockerfile следующим образом:

FROM nginx:1.21.6
 
# Update all packages { // Обновляем все пакеты }
RUN apt-get update && apt-get -y upgrade

# Custom cache invalidation { // Обновление пользовательского кэша }
ARG CACHEBUST=1

# Use a custom startpage { // Используем пользовательскую начальную страницу }
RUN echo '<html><bod>New Startpage</body></html>' > /usr/share/nginx/html/index.html

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

$ docker build -t my-custom-nginx --build-arg CACHEBUST=$(date +%s) .

=> [1/3] FROM docker.io/library/nginx:1.21.6@sha256:e1211ac1...    0.0s
=> CACHED [2/3] RUN apt-get update && apt-get -y upgrade           0.0s
=> [3/3] RUN echo '<html><bod>My Custom Startpage...               0.3s

=> exporting to image                                              0.0s
=> exporting layers                                                0.0s
=> writing image                                                   0.0s
=> naming to docker.io/library/my-custom-nginx

Building 1.0s (7/7) FINISHED

Указав --build-arg CACHEBUST=$(date +%s), вы постоянно будете устанавливать для параметра новой значение, что будет приводить к повторной сборке всех последующих слоев. 

Заключение

Кэширование сборок в Docker – довольно полезная функция. Она ускоряет процесс сборки образов Docker за счет повторного использования слоев, которые были созданы ранее.

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

Понимание того, как работает сборка в Docker, крайне важно, так как это может сделать процесс создания контейнеров Docker более эффективным. 

Ссылка
скопирована
Получите бесплатные уроки на наших курсах
Все курсы
DevOps
Скидка 25%
DevOps-инженер с нуля
Научитесь использовать инструменты и методы DevOps для автоматизации тестирования, сборки и развертывания кода, управления инфраструктурой и ускорения процесса доставки продуктов в продакшн. Станьте желанным специалистом в IT-индустрии и претендуйте на работу с высокой заработной платой.
Получи бесплатный
вводный урок!
Пожалуйста, укажите корректный e-mail
отправили вводный урок на твой e-mail!
Получи все материалы в telegram и ускорь обучение!
img
Еще по теме:
img
Git Flow - это специальная система ветвления для Git. Она помогает команде лучше контролировать и добавлять различные версии про
img
Docker — популярная платформа виртуализации на уровне ОС. Она поставляет приложения в пакетах (контейнерах), которые, представля
img
Хуки в Git — это bash-скрипты, которые запускаются до или после команд Git, например, коммитов и пушей. Они позволяют автоматизи
img
  Nomad и Kubernetes – это две самые популярные платформы оркестровки, предназначенные для оркестровки динамических рабочих нагр
img
  Давайте узнаем о новом Ops-течении – GitOps! DevOps поспособствовал цифровизации многих компаний. Речь идет о командах разрабо
img
  Канареечное (canary) развёртывание – это метод разработки и развертывания программного обеспечения, который позволяет выпускат
21 ноября
20:00
Бесплатный вебинар
Введение в Docker