Image manifest указывает на расположение конфига и набора слоёв для образа контейнера на конкретной ОС и архитектуре. Поле size указывает общий размер объекта. Теперь можно исследовать далее:
Распакуем базовый первый слой из архива и изучим его:
$ mkdir rootfs
$ tar -C rootfs -xf mysterious-image/blobs/sha256/0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa
$ tree -L 1 rootfs/
rootfs/
├── bin
├── dev
├── etc
├── home
├── lib
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin
├── srv
├── sys
├── tmp
├── usr
└── var
Это файловая система ОС! Можно изучить версию дистрибутива
$ cat rootfs/etc/issue
Welcome to Alpine Linux 3.10
Kernel \r on an \m(\l)$ cat rootfs/etc/os-release
NAME="Alpine Linux"ID=alpine
VERSION_ID=3.10.1
PRETTY_NAME="Alpine Linux v3.10"HOME_URL="https://alpinelinux.org/"BUG_REPORT_URL="https://bugs.alpinelinux.org/"
Распакуем следующий слой и изучим его:
$ tar -C layer -xf mysterious-image/blobs/sha256/6d8c9f2df98ba6c290b652ac57151eab8bcd6fb7574902fbd16ad9e2912a6753
$ tree -L 1 layer/
layer/
└── my-file
1 directory, 1 file
Тут лежим доп файл, созданный командой "/bin/sh -c touch my-file" - это можно увидеть в секции history. По сути исходный Dockerfile выглядел так:
FROMalpine:latestRUNecho HelloRUN touch my-file
Buildah
В 2017 году Red Hat разработали инструмент для создания образов контейнеров по стандарту OCI - как аналог docker build.
Создадим Dockerfile vim Dockerfile и впишем в него:
FROMalpine:latestRUNecho HelloRUN touch my-file
Запустим сборку контейнера на базе этого файла - buildah bud
Buildah поддерживает много команд:
buildah images # список образовbuildah rmi # удалить все образыbuildah ps # показать запущенные контейнеры
Почему вдруг buildah ps показ запущенных контейнеров, когда это инструмент для их СОЗДАНИЯ? А потому что в процессе создания как в buildah, так и в docker идёт запуск промежуточных контейнеров, их модификация в runtime. Каждый шаг модификации создаёт записи в history. Это потенциальная проблема ИБ: можно влезть в контейнер, пока он собирается (и запущен), если там что-то большое, и модифицировать его.
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05f4aa4aa95c 54da47293a0b "/bin/sh -c 'apt-get…"11 seconds ago Up 11 seconds interesting_heyrovsky
> docker exec -it 05f4aa4aa95c sh
# echo "Hello world" >> my-file
После сборки можно удостовериться, что созданный файл на месте:
> docker run clang cat my-file
Hello world
Создание контейнеров без Dockerfile
У buildah есть императивные команды к любой команде из Dockerfile, типа RUN или COPY. Это даёт огромную гибкость, т.к вместо огромных Dockerfile можно делить процесс создания контейнеров на части, между ними запускать любые вспомогательные инструменты UNIX.
Создадим базовый контейнер с Alpine Linux и посмотрим как он работает:
buildah from alpine:latest
buildah ps
Можно запускать команды в контейнере, а также создать в нёс файл:
По-умолчанию, buildah не делает записи history в контейнер, это значит порядок команд и частота их вызова не влияют на итоговые слои. Можно поменять это поведение ключом --add-history или переменной ENV BUILDAH_HISTORY=true.
Сделаем коммит нового контейнера в образ для финализации процесса:
buildah commit alpine-working-container my-image
buildah images # новый образ теперь в локальном реестре
Можно выпустить образ в реестр Docker, либо на локальный диск в формате OCI:
buildah unshare создаёт новое пространство имён, что позволяет подключить файловую систему как текущий не-root пользователь;
--mount автоматически подключает, путь кладём в переменную среды MOUNT;
Далее мы делаем commit на изменения, и mount на автомате убирается при покидании buildah unshare сессии.
Мы успешно модифицировали файловую систему контейнера через локальный mount. Проверим наличие файла:
> buildah run -t alpine-working-container cat test-from-mount
it-works
Вложенные контейнеры
У buildah нет даемона, значит, не нужно подключать docker.sock в контейнер для работы с Docker CLI. Это даёт гибкость и возможность делать вложенные схемы: установим buildah в контейнер, созданный buildah:
> buildah from opensuse/tumbleweed
tumbleweed-working-container
> buildah run -t tumbleweed-working-container bash
# zypper in -y buildah
Теперь вложенный buildah готов к использованию. Нужно указать драйвер хранения VFS в контейнере, чтобы получить рабочий стек файловой системы:
# buildah --storage-driver=vfs from alpine:latest# buildah --storage-driver=vfs commit alpine-working-container my-image
Получили вложенный контейнер. Заложим его в хранилище на локальной машине -> для начала заложим образ в /my-image:
ВАЖНОЕ ЗАМЕЧАНИЕ: все действия с buildah не потребовали sudo. Buildah создаёт всё необходимое для каждого пользователя в папках:
~/.config/containers, конфигурация
~/.local/share/containers, хранилища контейнеров
Декомпозиция Dockerfile в несколько разных с помощью CPP макросов.
podman
Инструмент для замены Docker. podman использует buildah как API для создания Dockerfile с помощью podman build. Это значит, что они разделяют одно хранилище под капотом. А это значит, что podman может запускать созданные buildah контейнеры: