У нас было 2 мешка травы, 75 таблеток мескалина unix environment, docker репозиторий и задача реализовать команды docker pull и docker push без докер клиента.  UPD: Вопрос: Для чего всё это?
Ответ: Нагрузочное тестирование продукта (НЕ средствами баша, скрипты приведены в образовательных целях). Не использовать докер клиент было решено для уменьшения дополнительных прослоек (в разумных пределах) и соответственно эмулирования более высокой нагрузки. В результате убрали все системные задержки докер клиента. Получили сравнительно чистую нагрузку непосредственно на продукт. В статье использовались тулы GNU-версий. Для начала разберемся что делают эти команды. Итак для чего используется docker pull? Согласно документации: Там же находим ссылку на understand images, containers, and storage drivers.  Отсюда мы можем понять что docker image это набор неких layers, которые содержат в себе информацию о последних изменениях в имедже, которые очевидно нам и нужны. Дальше смотрим в registry API. Здесь говорится следующее: Итак первый шаг согласно документации это “Pulling an Image Manifest”. Пулить мы его конечно не будем, но данные из него нам нужны. Дальше приводится пример запроса: GET /v2/{name}/manifests/{reference} Наш докер репозиторий развернут локально, попробуем выполнить запрос:  В ответ получаем json из которого нам интересны на данный момент только лееры, точнее их хэши. Получив их, можем по каждому пройтись и выполнить следующий запрос: "GET /v2/{name}/blobs/{digest}" digest в данном случае и есть хэш, который мы получили. Пробуем   посмотрим что за файл мы в итоге получили в качестве первого леера.  т.е. лееры представляют из себя tar архивы, распаковав которые в соответствующем порядке мы получим содержимое имеджа. Напишем небольшой баш скрипт чтобы всё это можно было автоматизировать Теперь можем запустить его с желаемыми параметрами и получить содержимое необходимого имеджа Тут будет чуть посложнее. Начнем опять с документации. Итак нам надо загрузить каждый леер, собрать соответствующий манифест и загрузить его тоже. Вроде звучит просто. Изучив документацию можем разделить процесс загрузки на несколько шагов: Но в документации упущен один шаг, без которого ничего не получится. Для монолитной загрузки так же как и для частичной (chunked) перед тем как грузить леер необходимо выполнить PATCH запрос: "PATCH /v2/{repoName}/blobs/uploads/{uuid}
Content-Length: {size of chunk}
Content-Type: application/octet-stream
{Layer Chunk Binary Data}". В противном случае вы не сможете продвинуться дальше первого пункта, т.к. вместо ожидаемого кода ответа 202 будете получать 4хх. Теперь алгоритм выглядит как: Для начала нам понадобиться любой имедж. Я буду использовать archlinux:latest  Теперь сохраним его себе локально для дальнейшего разбора  Распакуем полученный архив в текущую директорию   Как видим каждый леер лежит в отдельной папке. Теперь посмотрим на струткуру манифеста, который мы получили   Не густо. Посмотрим какой манифест нужен для загрузки, согласно документации.  Очевидно существующий манифест нам не подходит, значит сделаем свой с блэкджеком и куртизанками леерами и конфигами. У нас всегда будет минмум один config файл и массив лееров. Версия схемы 2 (актуальна на момент написания статьи), mediaType оставим без изменений: После создания базового манифеста необходимо его наполнить валидными данными. Для этого используем шаблон json объекта леера: его мы будем добавлять в манифест для каждого леера. Далее нам надо узнать размер конфиг файла и заменить заглушки в манифесте на реальные данные Теперь можно инициировать процесс загрузки и сохранить себе uuid, которым должны сопровождаться все последующие запросы. Полный скрипт выглядит примерно так: можем использовать готовый скрипт: UPD: Что мы получили в результате?
Во-первых, реальные данные для анализа, посколькоу тесты запускаются в blazemeter и данные по запросам докер клиента весьма не информативные в отличии от чистых HTTP запросов. Во-вторых, переход позволил нам увеличить колличество виртуальных пользователей для docker upload примерно на 150% и получить при этом avg response time на 20-25% быстрее. Для docker download получилось увеличить количество пользователей на 500%, avg response time при этом снизился примерно на 60%. Спасибо за внимание. IT