Когато използваме Docker, започваме с базово изображение. Зареждаме го, създаваме промени и те се записват в слоеве, образуващи друг образ.
Така в крайна сметка имам образ за моята PostgreSQL инстанция и образ за моето уеб приложение, чиито промени продължават да се съхраняват.
Какво представлява контейнерът?
Екземпляр на изображение се нарича контейнер. Имате изображение, което представлява набор от слоеве, както сте описали. Ако стартирате това изображение, ще имате работещ контейнер на това изображение. Можете да имате много работещи контейнери на едно и също изображение.
Можете да видите всичките си образи с docker images
, докато можете да видите работещите си контейнери с docker ps
(и можете да видите всички контейнери с docker ps -a
).
Така че работеща инстанция на образ е контейнер.
От статията ми за Автоматизиране на разгръщането на Docker:
В Dockerland има образи и контейнери. Двете са тясно свързани, но се различават. За мен разбирането на тази дихотомия изясни Docker в голяма степен.
Образът е инертен, неизменен файл, който по същество представлява моментна снимка на контейнера. Изображенията се създават с командата build и ще създадат контейнер, когато се стартират с run. Образите се съхраняват в регистър на Docker, например registry.hub.docker.com. Тъй като могат да станат доста големи, образите са проектирани да бъдат съставени от слоеве от други образи, което позволява да се изпращат минимално количество данни при прехвърляне на образи по мрежата.
Местните образи могат да бъдат изброени, като се стартира docker images
:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 13.10 5e019ab7bf6d 2 months ago 180 MB
ubuntu 14.04 99ec81b80c55 2 months ago 266 MB
ubuntu latest 99ec81b80c55 2 months ago 266 MB
ubuntu trusty 99ec81b80c55 2 months ago 266 MB
<none> <none> 4ab0d9120985 3 months ago 486.5 MB
Някои неща за отбелязване:__
-t
на командата docker build
или от маркирането с docker tag
на съществуващ образ. Свободни сте да маркирате изображенията, като използвате номенклатура, която има смисъл за вас, но знайте, че docker ще използва тага като местоположение на регистъра при docker push
или docker pull
.[REGISTRYHOST/][USERNAME/]NAME[:TAG]
. За ubuntu
по-горе, REGISTRYHOST се подразбира като registry.hub.docker.com
. Така че, ако планирате да съхранявате вашето изображение, наречено my-application
, в регистър на адрес docker.example.com
, трябва да маркирате това изображение с docker.example.com/my-application
.latest
не е магически, той е просто тагът по подразбиране, когато не посочите таг.<none>
TAG и REPOSITORY. Лесно е да забравите за тях.Повече информация за изображенията можете да намерите в документацията на Docker и речника.
Ако използваме метафора за програмиране, ако имиджът е клас, то контейнерът е инстанция на клас - обект за изпълнение. Надяваме се, че контейнерите са причината, поради която използвате Docker; те са леки и преносими капсули на среда, в която се изпълняват приложения.
Преглед на локалните работещи контейнери с docker ps
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2ff1af05450 samalba/docker-registry:latest /bin/sh -c 'exec doc 4 months ago Up 12 weeks 0.0.0.0:5000->5000/tcp docker-registry
Тук стартирам докеризирана версия на докер регистъра, така че да имам лично място за съхранение на моите изображения. Отново някои неща, които трябва да се отбележат:
docker ps
извежда само работещи контейнери. Можете да прегледате всички контейнери (работещи или прекъснати) с docker ps -a
.--name
.Едно от ранните ми разочарования от Docker беше изглеждащото постоянно натрупване на немаркирани образи и спрени контейнери. В няколко случая това натрупване водеше до претоварване на твърдите дискове, което забавяше лаптопа ми или спираше автоматичния конвейер за изграждане. Говорим за "контейнери навсякъде"!
Можем да премахнем всички немаркирани образи, като комбинираме docker rmi
със скорошната заявка dangling=true
:
docker images -q --filter "dangling=true" | xargs docker rmi
Docker няма да може да премахне образи, които се намират зад съществуващи контейнери, така че може да се наложи първо да премахнете спрените контейнери с docker rm
:
docker rm `docker ps --no-trunc -aq`
Това са известни проблеми с Docker и може да бъдат отстранени в бъдещи версии. Въпреки това, при ясно разбиране на образите и контейнерите, тези ситуации могат да бъдат избегнати с няколко практики:
docker rm [CONTAINER_ID]
.docker rmi [IMAGE_ID]
.Въпреки че е най-просто да се мисли за контейнер като за работещ образ, това не е съвсем точно.
Образът всъщност е шаблон, който може да се превърне в контейнер. За да се превърне образът в контейнер, енджинът на Docker взема образа, добавя файлова система за четене и запис отгоре и инициализира различни настройки, включително мрежови портове, име на контейнера, идентификатор и ограничения на ресурсите. Работещият контейнер има текущо изпълняващ се процес, но контейнерът може и да бъде спрян (или изключен в терминологията на Docker). Излезлият контейнер не е същото като образ, тъй като той може да бъде рестартиран и ще запази настройките си и всички промени във файловата система.