Как вычислить дайджест Docker-образа из сохраненного .tar файла?
При сохранении Docker-образа в локальный файл с помощью:
docker image save my-image --output /tmp/my-image.tar
Я могу просмотреть дайджест образа с помощью:
docker images --digests
Однако, когда я пытаюсь вычислить дайджест непосредственно из .tar файла с помощью:
sha256sum /tmp/my-image.tar
Полученная контрольная сумма не совпадает с тем, что показывает Docker. Как можно определить правильный дайджест Docker-образа путем прямого чтения .tar файла?
Дайджест Docker-образа не вычисляется как хеш SHA256 всего tar-файла. Вместо этого он рассчитывается на основе манифеста образа и файлов конфигурации JSON внутри tar-архива. Чтобы получить правильный дайджест из сохраненного tar-файла, необходимо извлечь и хешировать конкретный JSON-контент, который Docker использует для расчета дайджеста.
Содержание
- Понимание структуры Docker-образа
- Пошаговый процесс расчета дайджеста
- Инструменты и методы извлечения
- Альтернативные подходы
- Практический пример
Понимание структуры Docker-образа
При сохранении Docker-образа с помощью docker image save получающийся tar-файл содержит несколько ключевых компонентов, которые определяют дайджест:
- Манифест: Описывает структуру образа и ссылается на файл конфигурации
- Файл конфигурации: Содержит метаданные образа, переменные окружения и ссылки на слои
- Файлы слоев: Отдельные tar-архивы, содержащие фактические файловые системы слоев
Как объясняется в документации Docker, “Каждый платформо-специфичный образ имеет свой собственный дайджест (например, sha256:94a0…ea1a для linux/amd64)”. Дайджест рассчитывается на основе содержимого этих конкретных файлов, а не всего tar-архива.
Дайджест - это SHA256 (по умолчанию) строки JSON, которая представляет конфигурацию образа. - Stack Overflow
Манифест обычно содержит ссылки на:
- Файл конфигурации с его собственным дайджестом
- Файлы слоев с их индивидуальными дайджестами
- Метаданные, специфичные для платформы
Пошаговый процесс расчета дайджеста
Чтобы рассчитать дайджест Docker-образа из tar-файла, выполните следующие шаги:
- Извлеките tar-файл, чтобы получить доступ к его содержимому
- Найдите файл манифеста (обычно называется
manifest.json) - Извлеките файл конфигурации, на который ссылается манифест
- Рассчитайте SHA256 содержимого файла конфигурации
- Сравните с сообщенным Docker дайджестом
Фактический процесс расчета дайджеста включает:
- Чтение манифеста для поиска ссылки на файл конфигурации
- Извлечение содержимого файла конфигурации
- Вычисление SHA256 содержимого JSON конфигурации
- Использование этого результата в качестве дайджеста образа
Согласно техническому объяснению Maori Geek, “Этот SHA layer.tar ссылается внутри файла конфигурации, а расположение слоя указано в манифесте. Вот откуда берется дайджест.”
Инструменты и методы извлечения
Метод 1: Использование командной строки
# Извлеките tar-файл
mkdir -p /tmp/extracted
tar -xf /tmp/my-image.tar -C /tmp/extracted
# Найдите файл манифеста
find /tmp/extracted -name "manifest.json"
# Извлеките ссылку на файл конфигурации (пример)
cat /tmp/extracted/manifest.json | jq -r '.[0].Config' # Для парсинга JSON
# Рассчитайте SHA256 файла конфигурации
sha256sum /tmp/extracted/config.json
Метод 2: Использование скрипта на Python
import tarfile
import hashlib
import json
def calculate_docker_digest(tar_path):
with tarfile.open(tar_path, 'r') as tar:
# Извлекаем манифест
manifest_file = tar.extractfile('manifest.json')
manifest = json.load(manifest_file)
# Получаем путь к файлу конфигурации из манифеста
config_path = manifest[0]['Config']
# Извлекаем и хешируем содержимое конфигурации
config_file = tar.extractfile(config_path)
config_content = config_file.read()
# Рассчитываем дайджест SHA256
digest = hashlib.sha256(config_content).hexdigest()
return f"sha256:{digest}"
# Использование
print(calculate_docker_digest('/tmp/my-image.tar'))
Метод 3: Использование инструментов Docker
Если Docker доступен, вы можете использовать:
# Загрузите образ из tar
docker image load -i /tmp/my-image.tar
# Получите дайджест
docker image inspect --format='{{index .RepoDigests 0}}' my-image
Альтернативные подходы
Использование специализированных инструментов
Существуют несколько инструментов для помощи с расчетом дайджеста Docker-образа:
- skopeo: Может проверять и манипулировать образами контейнеров
- oras: Клиент для работы с OCI артефактами
- cosign: Инструмент для подписи контейнеров с возможностями проверки дайджеста
Прямое сравнение с реестром
Как упоминается в блоге инженерии Remind, “Когда мы используем дайджест в качестве идентификатора, Docker не только загрузит образ с этим дайджестом, но и рассчитает sha256 дайджест того, что вы загрузили”. Вы можете проверить рассчитанный дайджест, загрузив образ с использованием дайджеста:
docker pull my-image@sha256:your-calculated-digest
Практический пример
Рассмотрим полный пример:
# Сохраните образ
docker image save nginx:alpine --output /tmp/nginx.tar
# Извлеките tar
mkdir /tmp/nginx_extracted
tar -xf /tmp/nginx.tar -C /tmp/nginx_extracted
# Изучите структуру манифеста
cat /tmp/nginx_extracted/manifest.json | jq .
# Извлеките и рассчитайте дайджест конфигурации
CONFIG_PATH=$(cat /tmp/nginx_extracted/manifest.json | jq -r '.[0].Config')
sha256sum "/tmp/nginx_extracted/$CONFIG_PATH"
# Сравните с дайджестом Docker
docker image inspect nginx:alpine --format='{{index .RepoDigests 0}}'
Результат должен совпадать между вашим рассчитанным дайджестом и сообщенным Docker дайджестом.
Как отмечено в техническом объяснении Windsock.io, “Дайджесты, которые Docker использует для слоев ‘diff’ на хосте Docker, содержат sha256 хеш tar-архивированного содержимого diff.” Это также применимо к расчету файла конфигурации.
Заключение
Чтобы рассчитать правильный дайджест Docker-образа из сохраненного tar-файла:
- Извлеките tar-файл, чтобы получить доступ к его внутренней структуре
- Найдите файл манифеста (обычно
manifest.json) - Найдите путь к файлу конфигурации, на который ссылается манифест
- Извлеките и хешируйте JSON-содержимое конфигурации с использованием SHA256
- Добавьте префикс “sha256:” для соответствия формату Docker
Ключевое понимание заключается в том, что дайджесты Docker-образов рассчитываются на основе JSON-конфигурации образа, а не всего tar-файла. Этот подход обеспечивает согласованность с методом расчета дайджеста Docker и позволяет проверять целостность образа без загрузки его в Docker.
Для производственного использования рассмотрите возможность реализации автоматизированных скриптов, следующих этому процессу, или используйте существующие инструменты, такие как skopeo, которые внутренне обрабатывают эти расчеты. Всегда проверяйте рассчитанные дайджесты против официальных отчетов Docker для обеспечения точности.
Источники
- How is digest of Docker image calculated? - Stack Overflow
- sha256 - get digest of saved docker image (the saved .tar file) - Stack Overflow
- Image digests | Docker Docs
- How to Digest a Docker Image | Maori Geek
- Calculate Docker digests and are they mutable? | Kosli
- Docker image digests | Remind
- About container image digests | Google Kubernetes Engine
- Explaining Docker Image IDs | Windsock.io