Образ контейнера и OCI

Материал из llmdocs — справочник разработчика
Образ контейнера и OCI
ОрганизацияOpen Container Initiative (Linux Foundation)
Основанаиюнь 2015
СпецификацииImage Spec, Runtime Spec, Distribution Spec
Версии 1.0июль 2017 (Image и Runtime), май 2021 (Distribution)
Эталонная средаrunc
АдресацияSHA-256 дайджесты (content-addressable)
ИнструментыDocker, Podman, Buildah, containerd, skopeo, crane

Образ контейнера (англ. container image) — неизменяемый пакет, содержащий всё, что нужно для запуска приложения: файловую систему с программой и её зависимостями плюс метаданные о том, как её запускать (команда, переменные окружения, рабочий каталог, пользователь). Из одного образа можно запустить сколько угодно контейнеров. OCI (Open Container Initiative) — организация при Linux Foundation, которая стандартизировала формат образов, способ их запуска и протокол раздачи, чтобы образ, собранный одним инструментом, работал в любом другом.[4]

История

Формат образов в массы принёс Docker (2013). Когда вокруг контейнеров выросла экосистема, конкуренты (CoreOS со своим форматом appc) и сама Docker договорились о едином стандарте: в июне 2015 года была основана OCI. Docker передал в неё код своей низкоуровневой среды выполнения — так появился runc — и формат образа Docker v2, ставший основой спецификации. Версии 1.0 Image Spec и Runtime Spec вышли в 2017 году, Distribution Spec — в 2021-м, а версия 1.1 (2024) добавила хранение произвольных артефактов (подписей, SBOM) рядом с образами.[6]

Три спецификации

Спецификация Что описывает
Image Spec[1] формат образа: манифест, конфигурация, слои, индекс для нескольких платформ
Runtime Spec[2] как запустить «распакованный» контейнер (bundle): каталог rootfs + config.json
Distribution Spec[3] HTTP API реестра для загрузки и выгрузки образов (/v2/...)

Благодаря этому разделению Docker, Podman, Buildah, containerd и CRI-O взаимозаменяемы: собрали образ одним — запустили другим, а Kubernetes работает с любой совместимой средой.

Устройство образа

Образ OCI состоит из объектов, каждый из которых адресуется по содержимому — SHA-256 дайджесту (например, sha256:9b2a…):

  • Слои (layers) — tar-архивы (обычно сжатые gzip или zstd) с изменениями файловой системы. Каждая инструкция RUN, COPY, ADD в Dockerfile порождает новый слой. Удаление файла в верхнем слое записывается специальной меткой whiteout.
  • Конфигурация — JSON с командой запуска (Entrypoint, Cmd), переменными, портами, архитектурой и историей сборки.
  • Манифест — JSON со ссылками на конфигурацию и слои по дайджестам.
  • Индекс (image index, «мультиархитектурный образ») — список манифестов для разных платформ: linux/amd64, linux/arm64 и т. д. Клиент сам выбирает подходящий.

При запуске контейнера слои накладываются друг на друга с помощью объединяющей файловой системы (обычно overlayfs), а сверху добавляется тонкий записываемый слой контейнера.[5] Слои общие: если десять образов основаны на одном python:3.12-slim, базовые слои хранятся и скачиваются один раз.

Теги и дайджесты

Полное имя образа: реестр/репозиторий:тег@дайджест, например docker.io/library/nginx:1.27.

  • Тег — изменяемый ярлык: latest или 1.27 сегодня и через месяц могут указывать на разные образы.
  • Дайджест — неизменяемый: nginx@sha256:… всегда даёт ровно тот же образ. В продакшене и CI образы рекомендуют фиксировать по дайджесту.

Тег latest не означает «самый новый» — это просто тег по умолчанию, который никто не обязан обновлять.

Работа с образами

docker build -t registry.example.com/app:1.4.0 .     # собрать
docker image inspect app:1.4.0                       # конфигурация и слои
docker history app:1.4.0                             # какой инструкцией создан каждый слой
docker push registry.example.com/app:1.4.0           # загрузить в реестр
docker buildx build --platform linux/amd64,linux/arm64 -t app:1.4.0 --push .

skopeo inspect docker://docker.io/library/alpine:3.20   # посмотреть образ без скачивания

Образы хранятся в реестрах (Container registry): Docker Hub, GitHub Container Registry, GitLab Registry, Harbor, облачные реестры.

Хорошие практики

  • Минимальная база: alpine, -slim, distroless — меньше размер и меньше уязвимостей.
  • Многоэтапная сборка (multi-stage): компилятор и инструменты сборки остаются в промежуточном этапе и не попадают в итоговый образ.
  • Порядок инструкций от редко меняющихся к часто меняющимся — так кеш слоёв работает лучше.
  • Не класть секреты в слои: удалённый в следующем слое файл всё равно остаётся в истории образа.
  • Подписывать образы (cosign, Notation) и сканировать на уязвимости (Trivy, Grype).

См. также

Источники

  1. OCI Image Format Specification
  2. OCI Runtime Specification
  3. OCI Distribution Specification
  4. Open Container Initiative — About
  5. Docker Docs — Storage drivers and image layers
  6. OCI Image Spec v1.1 — Artifacts and referrers