Что такое слои образа (image layers)?
Слои образа — это неизменяемые (immutable) read-only блоки файловой системы, из которых состоит Docker-образ. Каждая инструкция в Dockerfile (FROM, RUN, COPY, ADD) создаёт новый слой.
Как работают слои
Пример
┌──────────────────────────┐
│ Writable Layer │ ← Контейнер (записываемый слой)
├──────────────────────────┤
│ ENTRYPOINT java -jar │ ← Только метаданные (не создаёт слой)
├──────────────────────────┤
│ COPY app.jar │ ← Слой 3
├──────────────────────────┤
│ RUN apt-get install │ ← Слой 2
├──────────────────────────┤
│ FROM ubuntu:22.04 │ ← Слой 1 (базовый образ)
└──────────────────────────┘
Кэширование слоёв
Кэширование слоёв — одна из ключевых оптимизаций Docker. При повторной сборке Docker проверяет, изменилась ли инструкция и её контекст. Если нет — используется кэшированный слой. Но если один слой инвалидируется, все последующие слои тоже пересобираются.
Оптимальный порядок инструкций
Пример
# Плохо: любое изменение в исходном коде инвалидирует кэш зависимостей
COPY . /app
RUN mvn package
# Хорошо: зависимости кэшируются отдельно
COPY pom.xml /app/
RUN mvn dependency:go-offline
COPY src /app/src
RUN mvn package
Разделение слоёв между образами
Слои разделяются между образами: если два образа используют одну базу (FROM eclipse-temurin:17-jre-alpine), базовый слой хранится на диске только один раз.
На собеседовании: покажите понимание двух вещей: (1) слои неизменяемы и кэшируются, (2) инвалидация одного слоя каскадно пересобирает все последующие. Отсюда правило: инструкции, которые меняются реже (зависимости), должны идти перед теми, которые меняются чаще (исходный код).