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

> Образ контейнера — неизменяемый пакет из слоёв файловой системы и конфигурации; OCI — открытые спецификации формата образа, среды выполнения и реестров.

Источник: https://llmdocs.ru/wiki/oci-image/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Организация**: 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](https://llmdocs.ru/wiki/docker.md) (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](https://llmdocs.ru/wiki/kubernetes.md) работает с любой совместимой средой.

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

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

- **Слои** (*layers*) — tar-архивы (обычно сжатые gzip или zstd) с изменениями файловой системы. Каждая инструкция `RUN`, `COPY`, `ADD` в [Dockerfile](https://llmdocs.ru/wiki/dockerfile.md) порождает новый слой. Удаление файла в верхнем слое записывается специальной меткой *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` не означает «самый новый» — это просто тег по умолчанию, который никто не обязан обновлять.

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

```bash
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](https://llmdocs.ru/wiki/container-registry.md)): Docker Hub, GitHub Container Registry, GitLab Registry, Harbor, облачные реестры.

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

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

## См. также

- [Контейнеризация](https://llmdocs.ru/wiki/containerization.md)
- [Namespaces и cgroups](https://llmdocs.ru/wiki/namespaces-cgroups.md)
- [Podman](https://llmdocs.ru/wiki/podman.md)
- [Pod](https://llmdocs.ru/wiki/pod.md)

## Источники

1. [OCI Image Format Specification](https://github.com/opencontainers/image-spec)
2. [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec)
3. [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec)
4. [Open Container Initiative — About](https://opencontainers.org/about/overview/)
5. [Docker Docs — Storage drivers and image layers](https://docs.docker.com/engine/storage/drivers/)
6. [OCI Image Spec v1.1 — Artifacts and referrers](https://github.com/opencontainers/image-spec/blob/main/manifest.md)
