2016-04-23 1 views
2

Я использую докер для создания изображений из файла докеров. В процессе произошла некоторая ошибка, поэтому выход сборки с кодом ошибки.Почему docker создает изображение из файла docker, создаст контейнер при неправильном построении выхода?

Когда я запускаю docker images Я вижу непомеченное изображение. поэтому я попытался удалить его docker rmi xxxxx. Но он всегда терпит неудачу, он говорит, что изображения нельзя удалить, потому что они используются остановленным контейнером.

Так что я копаю немного глубже. Я запускаю docker ps -a, теперь я вижу длинный список остановленного контейнера, который создается при сбое процесса сборки.

Почему будет создан контейнер? Я думал, что образ похож на понятие «класс» в программировании, а контейнер - это экземпляр класса. Прежде чем изображение будет успешно создано, почему создается экземпляр? Как я могу создать образ без всех остановленных контейнеров?

ответ

4

Каждая строка вашего Dockerfile создает промежуточный контейнер для выполнения директивы Dockerfile для этой строки.

Если директива успешно, что позволит создать промежуточное изображение, которое будет служить основой для следующего контейнера будет запуск (выполнить следующую строку вашего Dockerfile)

Если указанная директива выходит из строя, что может оставить контейнер в состоянии Exited, который, в свою очередь, блокирует промежуточное изображение, из которого он был создан.
Просто cleanup all the containers then all the images, и повторите попытку.

Если вы попытались повторно создать свой файл Dockerfile, вы получите коллекцию промежуточных изображений и контейнеров.

Вот почему, когда моя сборка (в конце концов) прошла успешно, я всегда очистки дополнительные контейнеры, изображения и (с грузчиком 1.10+) томов в моей build script:

cmdb="docker build${proxy}${f} -t $1 $2" 
# echo "cmdb='${cmdb}" 
if eval ${cmdb}; then 
    docker rm $(docker ps -qa --no-trunc --filter "status=exited" 2>/dev/null) 2>/dev/null 
    docker rmi $(docker images --filter "dangling=true" -q --no-trunc 2>/dev/null) 2>/dev/null 
    docker volume rm $(docker volume ls -qf dangling=true 2>/dev/null) 2>/dev/null 
    exit 0 
fi 
1

Процесс сборки создает промежуточный для каждый шаг в файле докеров. Как вы можете видеть в этом примере:

... 
Removing intermediate container e07079f73a9f 
Step 3 : RUN cd /opt/ 
---> Running in 78d480a57cca 
---> 324e9006d642 
Removing intermediate container 78d480a57cca 
Step 4 : RUN unzip /opt/mule-ee-distribution-standalone-3.7.3.zip -d /opt/ 
---> Running in 81aa445c770c 
... 
---> e702e1cff4ee 
---> removing intermediate container 81aa445c770c 

Для ускорения процесса сборки промежуточный контейнер будет использоваться в качестве кеша. Эти контейнеры будут удалены после успешной сборки, но когда вы попытаетесь построить несколько раз, «старые» промежуточные контейнеры и изображение все равно будут находиться в вашей системе.

Если вы хотите сохранить промежуточные контейнеры после завершения сборки, вы должны использовать --rm=false. По умолчанию это true, поэтому после успешной сборки промежуточные контейнеры будут удалены. Когда сборка выходит из строя во время использования промежуточного контейнера, этот контейнер выйдет. Промежуточное «изображение для этого контейнера» имеет метки <none>:<none> и не может быть удалено нормально, потому что есть (возбужденный) контейнер, который находится на этом изображении. Вы можете удалить изображение с помощью флага -f (force): docker rmi -f image-id

Смежные вопросы