Какой образ у контейнера
Первое поле inspect — имя, с которым контейнер создан, второе — ID
образа. Если имя с тех пор переехало на новый образ, ID это покажет.
Образ — неизменяемый набор слоёв с файлами и настройками запуска; из него Docker создаёт контейнеры.
sudo docker load -i /opt/images/alpine.tar
образ из файла
sudo docker images
образы на машине
sudo docker image ls --digests
с digest
sudo docker history nginx:alpine
слои и чем созданы
sudo docker image inspect -f '{{.Id}}' busybox
полный ID
sudo docker tag busybox:latest app:1.0
второе имя того же образа
sudo docker rmi app:1.0
снять тег или удалить образ
sudo docker image prune
удалить образы без тега
sudo docker save busybox > busybox.tar
образ в файл
sudo docker pull nginx:alpine
скачать из реестра (нужна сеть)
Образ — шаблон, из которого Docker создаёт контейнеры. В нём лежат файлы будущего контейнера — программа, библиотеки, конфиги — и настройки запуска: команда, переменные окружения, рабочий каталог, порт. Образ не меняется. Контейнер пишет в свой слой поверх образа, поэтому из одного образа можно создать сколько угодно контейнеров.
На машине тренажёра сети наружу нет. Образы лежат файлами в /opt/images,
docker load загружает их в Docker. На этой машине student не входит в
группу docker, поэтому все команды идут через sudo.
| Столбец | Что в нём |
|---|---|
| IMAGE | имя образа: репозиторий и тег |
| ID | короткий ID — первые 12 знаков хэша |
| CONTENT SIZE | слои в сжатом виде, как в файле или в реестре |
| DISK USAGE | место на диске вместе с распакованными слоями |
| EXTRA | U — образ использует хотя бы один контейнер |
После таблицы docker images печатает предупреждение This output is
designed for human readability: вид таблицы может поменяться с версией
Docker. Скрипту нужен --format — рецепт ниже.
Реестр — сервер, где хранятся образы: Docker Hub, GitLab Registry, свой
реестр компании. docker pull скачивает образ из реестра, docker push
отправляет. Полное имя образа говорит, где он лежит:
Без реестра в имени Docker идёт в Docker Hub, без тега берёт latest.
nginx:alpine — это docker.io/library/nginx:alpine. Полное имя видно в
ошибке, когда образа нет на машине: failed to resolve reference
"docker.io/library/nginx:alpine".
Образ собран из слоёв. Слой — архив с изменениями
файлов: что добавлено, изменено или удалено относительно слоёв под ним.
Каждая инструкция dockerfile, которая меняет файлы, даёт слой. Историю
слоёв показывает docker history, новые сверху:
Нижняя строка — слой Alpine: nginx:alpine собран поверх образа Alpine.
Строки с размером 0B (CMD, EXPOSE, ENV) файлов не меняют — они
записывают настройки запуска. <missing> в столбце IMAGE значит, что у
шага нет отдельного образа на этой машине: так выглядит история любого
скачанного или загруженного образа.
Одинаковые слои хранятся один раз. Десять образов на основе Alpine держат на диске одну копию его слоя.
Слои образа только читаются. Контейнер получает поверх них свой слой для записи — слой контейнера. Файл, изменённый внутри контейнера, копируется в этот слой (копирование при записи), а образ остаётся прежним.
Слой контейнера живёт, пока жив контейнер: docker stop и docker start
его сохраняют, docker rm удаляет вместе со всеми данными. Данные, которые
должны пережить пересоздание контейнера, хранят в томе — раздел
«Тома» статьи о Docker.
Тег — подвижное имя образа: часть после двоеточия.
docker tag даёт тому же образу второе имя, ID у имён один:
latest — просто тег по умолчанию. Он ставится, когда тег не указан, и
ничего не говорит о свежести: alpine:latest на машине — тот образ,
который в неё загрузили.
Тег переезжает при сборке. docker build -t app:1.1 второй раз отдаёт имя
новому образу, а прежний остаётся без имени, <none>:<none> — висячий
образ (dangling). Обычный docker images его не показывает, найти можно
фильтром:
docker images -a показывает такие образы строкой <untagged>.
docker rmi <имя> снимает тег. Если у образа есть другие имена, образ
остаётся: Untagged: busybox:latest. Последнее имя docker rmi удаляет
вместе с образом — если образ не нужен ни одному контейнеру.
Digest — SHA-256 от манифеста образа, описания
слоёв и настроек. Поменяется хоть один байт в любом слое — поменяется и
digest. Поэтому nginx@sha256:1acb… всегда означает одно и то же
содержимое, а nginx:alpine завтра может указывать на другой образ.
В Docker 29 образы хранит containerd, и у загруженного образа ID совпадает с digest.
docker save пишет образ в tar-архив со всеми слоями, docker load
загружает его обратно — на этой же или другой машине. Так образ попадает
туда, где нет доступа к реестру. Внутри архива — формат OCI: index.json,
manifest.json и каталог blobs/sha256, где каждый файл назван своим
SHA-256.
Первое поле inspect — имя, с которым контейнер создан, второе — ID
образа. Если имя с тех пор переехало на новый образ, ID это покажет.
index.json указывает на манифест по digest, файл манифеста назван тем же
digest, и sha256sum от него даёт то же число. По таким хэшам реестр и
Docker проверяют, что слой дошёл целым.
Образа с таким именем и тегом на машине нет, и Docker пошёл за ним в
реестр. docker run, docker build с таким FROM и docker compose up
так и делают. Без сети запрос падает на lookup registry-1.docker.io.
Сверь имя и тег с docker images (busybox:latest и busybox:1.36 —
разные образы) или загрузи образ из файла: docker load -i.
Образ нужен контейнеру, хотя бы остановленному. Найди его:
docker ps -a --filter ancestor=busybox, удали docker rm, потом
образ.
Контейнер создан из того образа, который был под именем в момент
docker run. Новая сборка с тем же тегом его не трогает. Пересоздай
контейнер: docker rm -f web, затем docker run с теми же ключами.
Сверить можно ID: docker inspect -f '{{.Image}}' web и
docker image inspect -f '{{.Id}}' app:1.1.
<none> вместо имениВисячие образы остаются после пересборки с тем же тегом. Они занимают
место, но не мешают. Убрать — docker image prune.
sudo docker save -o file.tar создаёт файл от root с правами 600, и
student не может его прочитать. Перенаправь вывод — sudo docker save
busybox > busybox.tar: файл создаёт твоя оболочка, он твой.
prune -a удаляет и висячие образы, и все остальные, которые сейчас не
нужны ни одному контейнеру. Без сети вернуть их нечем: файл для
docker load придётся искать заново. rmi -f снимает защиту от удаления
образа, нужного контейнеру.
image: app:latest в compose или скрипте запуска означает «что сейчас под
этим именем». После docker pull или новой сборки сервис молча
поднимется на другой версии. Пиши тег версии или digest:
nginx@sha256:1acb5b02….
inspect.docker save.Есть неточность? Сообщить об ошибке в статье