НейроАгент

Расчет дайджеста Docker-образа из tar-файла

Узнайте, как рассчитывать дайджест Docker-образа из сохраненных .tar-файлов. Узнайте, почему sha256sum не совпадает с дайджестом Docker, и извлеките правильный JSON-конфиг для точного расчета дайджеста.

Как вычислить дайджест 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 image save получающийся tar-файл содержит несколько ключевых компонентов, которые определяют дайджест:

  • Манифест: Описывает структуру образа и ссылается на файл конфигурации
  • Файл конфигурации: Содержит метаданные образа, переменные окружения и ссылки на слои
  • Файлы слоев: Отдельные tar-архивы, содержащие фактические файловые системы слоев

Как объясняется в документации Docker, “Каждый платформо-специфичный образ имеет свой собственный дайджест (например, sha256:94a0…ea1a для linux/amd64)”. Дайджест рассчитывается на основе содержимого этих конкретных файлов, а не всего tar-архива.

Дайджест - это SHA256 (по умолчанию) строки JSON, которая представляет конфигурацию образа. - Stack Overflow

Манифест обычно содержит ссылки на:

  • Файл конфигурации с его собственным дайджестом
  • Файлы слоев с их индивидуальными дайджестами
  • Метаданные, специфичные для платформы

Пошаговый процесс расчета дайджеста

Чтобы рассчитать дайджест Docker-образа из tar-файла, выполните следующие шаги:

  1. Извлеките tar-файл, чтобы получить доступ к его содержимому
  2. Найдите файл манифеста (обычно называется manifest.json)
  3. Извлеките файл конфигурации, на который ссылается манифест
  4. Рассчитайте SHA256 содержимого файла конфигурации
  5. Сравните с сообщенным Docker дайджестом

Фактический процесс расчета дайджеста включает:

  • Чтение манифеста для поиска ссылки на файл конфигурации
  • Извлечение содержимого файла конфигурации
  • Вычисление SHA256 содержимого JSON конфигурации
  • Использование этого результата в качестве дайджеста образа

Согласно техническому объяснению Maori Geek, “Этот SHA layer.tar ссылается внутри файла конфигурации, а расположение слоя указано в манифесте. Вот откуда берется дайджест.”


Инструменты и методы извлечения

Метод 1: Использование командной строки

bash
# Извлеките 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

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 доступен, вы можете использовать:

bash
# Загрузите образ из tar
docker image load -i /tmp/my-image.tar

# Получите дайджест
docker image inspect --format='{{index .RepoDigests 0}}' my-image

Альтернативные подходы

Использование специализированных инструментов

Существуют несколько инструментов для помощи с расчетом дайджеста Docker-образа:

  1. skopeo: Может проверять и манипулировать образами контейнеров
  2. oras: Клиент для работы с OCI артефактами
  3. cosign: Инструмент для подписи контейнеров с возможностями проверки дайджеста

Прямое сравнение с реестром

Как упоминается в блоге инженерии Remind, “Когда мы используем дайджест в качестве идентификатора, Docker не только загрузит образ с этим дайджестом, но и рассчитает sha256 дайджест того, что вы загрузили”. Вы можете проверить рассчитанный дайджест, загрузив образ с использованием дайджеста:

bash
docker pull my-image@sha256:your-calculated-digest

Практический пример

Рассмотрим полный пример:

bash
# Сохраните образ
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-файла:

  1. Извлеките tar-файл, чтобы получить доступ к его внутренней структуре
  2. Найдите файл манифеста (обычно manifest.json)
  3. Найдите путь к файлу конфигурации, на который ссылается манифест
  4. Извлеките и хешируйте JSON-содержимое конфигурации с использованием SHA256
  5. Добавьте префикс “sha256:” для соответствия формату Docker

Ключевое понимание заключается в том, что дайджесты Docker-образов рассчитываются на основе JSON-конфигурации образа, а не всего tar-файла. Этот подход обеспечивает согласованность с методом расчета дайджеста Docker и позволяет проверять целостность образа без загрузки его в Docker.

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

Источники

  1. How is digest of Docker image calculated? - Stack Overflow
  2. sha256 - get digest of saved docker image (the saved .tar file) - Stack Overflow
  3. Image digests | Docker Docs
  4. How to Digest a Docker Image | Maori Geek
  5. Calculate Docker digests and are they mutable? | Kosli
  6. Docker image digests | Remind
  7. About container image digests | Google Kubernetes Engine
  8. Explaining Docker Image IDs | Windsock.io