Създаване на изображение на Docker. Разбиране на Docker. Основните компоненти на Docker

Docker е най-разпространената система за контейнеризация, която ви позволява да стартирате софтуера, необходим за разработка в контейнери, без да го инсталирате в локалната система. В рамките на този материал ще анализираме управлението на докер контейнери.

Docker се състои от няколко компонента:
  1. Образ- набор от софтуер, конфигуриран от разработчиците, който се изтегля от официалния уебсайт
  2. Контейнер- реализация на изображението - обект на сървъра, създаден от него, контейнерът не трябва да е точно копие и може да се коригира с помощта на Dockerfile
  3. Сила на звука- областта на диска, използвана от контейнера и в която се записват данните. След изтриване на контейнера софтуерът не остава, данните могат да се използват в бъдеще

Мрежа е изградена върху цялата структура по специален начин, който ви позволява да препращате портове по желания начин и да направите контейнера достъпен отвън (по подразбиране той работи на локален IP адрес) чрез виртуален мост. В този случай контейнерът може да бъде достъпен както за света, така и за един адрес.

Управление на Docker контейнери: основни възможности

Инсталирайте Docker на сървър на Ubuntu или Debian, ако вече не е инсталиран съгласно инструкциите. По-добре да изпълнявате команди като непривилегирован потребител чрез sudo

Пускането на най-простия контейнер ще покаже, че всичко работи

Основни команди за управление на контейнери

Можете да покажете всички активни контейнери по този начин

С превключвателя -a ще се покажат всички контейнери, включително неактивните

Dicker присвоява имена на контейнери произволно, ако е необходимо, можете да посочите името директно

docker run — име hello-world

Стартирайте контейнер с име my-linux-container въз основа на изображението на ubuntu и отидете на конзолата на контейнера, като посочите bash shell

docker run -it — име my-linux-container ubuntu bash

За да излезете от контейнера и да се върнете към хоста, системата трябва да работи

Всички изображения, въз основа на които са създадени контейнери, се изтеглят автоматично от hub.docker.com, когато контейнерът е създаден за първи път, тези, които вече съществуват локално, могат да се видят чрез стартиране на docker изображения

Създаването на контейнер от вече изтеглено изображение ще бъде много по-бързо (почти мигновено)

Когато излезете от контейнера с изход, той спира, за да не се случи това, можете да излезете с клавишната комбинация CTRL + A + P

Можете да премахнете всички контейнери, които не са активни

docker rm $ (docker ps -a -f status = exited -q)

Или ги изтрийте един по един

Вместо идентификатор в последната команда, можете да посочите име

В docker контейнерите се управляват с помощта на малък брой интуитивни команди:

начален идентификатор на докер контейнера

идентификатор на спиране на докер контейнера

ИД за рестартиране на докер контейнер

ИД за проверка на докер контейнера

Последното е особено полезно, показва цялата информация за контейнера, конфигурационните файлове и използваните дискови дялове. Целият списък с команди може лесно да бъде намерен в помощта или на официалния уебсайт на Docker.

Изграждане на вашето Docker изображение и използване на Dockerfile

Изображенията обикновено се създават от съществуващи чрез използване на допълнителни опции, посочени в Dockerfile

ОТ ubuntu
CMD ехо "здравей свят"

Сега се създава ново изображение на базата на стандартния c ubuntu

Създайте изображението, като му дадете име (точката в края на командата означава, че се използва текущата директория и следователно Dockerfile в нея)

docker build -t my-ubuntu.

докер изображениясега ще покаже и новосъздаденото изображение на my-ubuntu

Може да се стартира и конзолата ще се покаже Здравей свят и това е единствената разлика от изображението по подразбиране

Обикновено имаме нужда от по-сложни правила, например, трябва да включим python3 в изображението - нека отидем в нова директория и да създадем Dockerfile

ОТ ubuntu
CMD apt-get update && apt-get install python3

Всички инструкции са написани на един ред

docker build -t my-ubuntu-with-python3.

Започваме контейнера, като влизаме вътре

docker run -it my-ubuntu-with-python3 bash

Вътре, като root, трябва да изпълните dpkg -l | grep python3, командата ще покаже, че пакетът присъства в системата, което означава успех

Фактът, че Docker наистина е задължителен инструмент за разработчик и администратор на всеки голям проект. Но дори и да не е така, Docker все още трябва да знае: в много близко бъдеще той ще бъде навсякъде, от настолна Linux дистрибуция до пул от сървъри на AWS. И най-хубавото е, че справянето с Docker е доста лесно, ако, разбира се, разбирате как работи правилно.

Apt-влезте в света на виртуалните среди

Docker се основава на технологии за пространства от имена и cgroups (първият осигурява изолация, вторият осигурява групиране на процеси и ограничаване на ресурсите), следователно, по отношение на виртуализацията, не се различава много от LXC / OpenVZ, с който сме свикнали, и няма много да говорим тук. Същата естествена скорост, същите методи за изолация, базирани на механизмите на ядрото на Linux. По-горе обаче започва съвсем друга история. Акцентът на Docker е, че ви позволява да разгръщате пълноценна виртуална среда и да стартирате приложение в нея толкова лесно, колкото, например, рестартиране на уеб сървър.

Абстрахираме се от детайлите на конкретни дистрибуции и си представяме, че имаме чист CentOS и искаме да изпълним конкретна команда в него в напълно виртуална среда без достъп до основната система. Трябва ли да изтеглите изображения на дистрибуции, да ги разположите в системата и да настроите виртуална среда? Изобщо не, всичко, което трябва да направите, е да изпълните две команди:

$ sudo yum инсталирайте docker-io $ sudo docker run -t ubuntu: последно / usr / bin / top

И това е всичко. Току-що стартирахме най-горната помощна програма в контейнер със среда, базирана на най-новата налична в момента версия на Ubuntu, извеждайки информация към текущия терминал. И всичко това с една проста команда (инсталацията не се брои). Не е зле, нали? Като цяло можем дори да "влезем" в този контейнер и да направим всичко, което обикновено се прави с прясно инсталирана система:

$ sudo docker run -t -i ubuntu: последно / bin / bash # apt-get update # apt-get install nginx #

Както виждате, всичко е наред и с мрежата, така че можем да актуализираме системата, да инсталираме и конфигурираме всеки софтуер. Изглежда малко като магия, но всъщност е много просто. Docker е един вид apt-get в света на контейнерите, само че вместо пакети има изображения на файлова система и вместо официалните хранилища на Debian / Ubuntu има облачно хранилище, наречено Docker Hub.

Когато направихме "docker run ...", системата направи следното:

  1. Помощната програма docker се свърза с демона на dockerd на нашата локална машина, поздрави от нас и поиска да стартира най-новата версия на Ubuntu (както е посочено от последния маркер в командата) в изолиран контейнер.
  2. Демонът на dockerd провери своя бележник, отиде в директорията / var / lib / docker и установи, че изображението на файловата система от най-новата версия на Ubuntu не е на нашата машина, затова реши да се свърже с Docker Hub, за да разбере дали има има ли такова изображение.
  3. След като говори с Docker Hub, той се увери, че изображението все още съществува, и поиска да ни го изпрати.
  4. След като получи необходимото изображение, dockerd монтира своята файлова система, направи chroot в нея и изпълни командата, посочена в последния аргумент, ограничавайки неговия "обхват" с помощта на пространства от имена (всъщност той прекъсна достъпа си до основната файлова система, хоста системни процеси, IPC и други, заключени в пясъчната кутия), но хвърли файловете на устройството на текущия терминал в него (флагът -t), за да може нашият връх да нарисува своя псевдографичен интерфейс.

Акцентът на този модел е, че Docker Hub е отворен за всеки и всеки може да подготви свое собствено изображение (повече за това по-късно) и да го публикува за инсталиране на друга машина и/или от друго лице. Към момента на писането на тази статия повече от 45 хиляди изображения са публикувани в Docker Hub за всички случаи, от изображения на „голи“ дистрибуции до изображения с предварително конфигурирани сървърни и настолни приложения, работещи в минималистична Linux среда.

Ами ако искаме да стартираме Firefox във виртуална среда? Не може да бъде по-лесно, отворете Docker Hub в браузър, щракнете върху Преглед и търсене и въведете във firefox. На екрана ще се появи списък с резултати. Гледаме, kennethkl / firefox изглежда е доста подходящ. Кликваме върху него и виждаме информация как да започнем цялото нещо. Авторът ни казва да изпълним команда като тази:

$ sudo docker run -d --name firefox -e DISPLAY = $ DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix kennethkl / firefox

Да опитаме. Да, наистина, след кратко изтегляне на изображението получаваме стандартен Firefox на екрана. Между другото, използвайки същия пример, можете да се запознаете с още четири полезни опции на командата docker run:

  • -d - "демонизира" контейнера, тоест просто изключва Docker от виртуалната среда STDOUT и му позволява да работи във фонов режим;
  • --name - името на контейнера, което ще получи вместо идентификатора;
  • -e - ви позволява да "препратите" променлива на средата към виртуалната машина;
  • -v - препраща посочения файл или директория (формат / файл / на / хост / система: / файл / в / виртуална машина или просто / файл / на / хост / система, ако пътищата съвпадат).

В този случай променливата и файлът са необходими, за да може Firefox да има достъп до дисплея на локалната машина. Това е доста несигурно, тъй като всеки процес в контейнера не само ще може да стартира всеки софтуер на вашия работен плот, но също така, например, да прихваща натискане на клавиши или движения на курсора. Но например ще стане.

Има по-лесен начин да намерите изображения на Docker с помощта на командата за търсене на docker:

$ sudo docker търсене nginx

ИНФО

Всеки потребител на Docker може да стартира свой собствен частен център. Нарича се "registry" и се предлага като готово изображение. Всичко, което трябва да направите, е просто да го стартирате: docker run -p 5555: 5555 регистър.

Демонът на Docker е достъпен не само с помощта на клиента, но и чрез RESTful API, както локално, така и от отдалечена машина. Стандартните портове на Docker са tcp / 2375 e tcp / 2376.

Не е необходимо изображението на Docker да се стартира веднага след изтеглянето, първо можете да го изтеглите на вашата локална машина с помощта на командата docker pull и едва след това да стартирате: docker pull ubuntu.

Наслоена торта

Docker ви позволява да направите работата с виртуални среди възможно най-удобна, опростявайки както процеса на разгръщане на среди, така и настройването на взаимодействието им с хост системата (което е само последният пример). Но това не е единственият му акцент.

Ако вече сте играли с изображението на Ubuntu от първите два примера, вероятно сте забелязали, че всяко ново стартиране на контейнера става от нулата и всички промени, направени в предишната сесия, се губят. Това изобщо не е грешка, това е една от ключовите характеристики на архитектурата на Docker, която я прави още по-интересно и привлекателно решение.

Факт е, че в по-голямата част от случаите „образът на Docker“ изобщо не е монолитно изображение на файлова система, а вид слоеве, състоящ се от няколко изображения на файлова система, на базата на които се формира контейнерът. В същото време отделните FS изображения изобщо не са отговорни за определени части от структурата на директорията (както например в случай на разделяне на диск под Linux на дялове / home, / var, / boot), а са наслоени един върху друг, използвайки AUFS механизма на ядрото Linux (има също поддръжка за същата функционалност чрез използването на btrfs, устройство за картографиране и наслагване).

За да разберем как работи това, нека се върнем към нашия контейнеризиран Ubuntu. Стартираме контейнера и инсталираме nginx, както е показано във втория пример в началото на статията, но не го прекратяваме. Вместо това стартираме друг терминал и виждаме списъка с работещи контейнери:

$ sudo docker ps

Тази команда ще покаже всички работещи контейнери заедно с техния идентификатор, използвано изображение, стартирана команда, време на работа и други. Интересуваме се от стойността в колоната CONTEINER ID. Копирайте го и изпълнете следната команда:

$ sudo docker commit идентификатор на контейнера ubuntu-nginx

След като приключи, можете да излезете от контейнера, като по този начин приключите работата му. И тогава просто стартираме контейнера ubuntu-nginx и виждаме, че nginx не е изчезнал никъде и е на мястото си:

$ sudo docker run -i -t ubuntu-nginx / bin / bash # който nginx / usr / sbin / nginx

какво направихме? Създадохме друг слой, тоест допълнително FS изображение, и генерирахме ново изображение на Docker, базирано на вече съществуващото изображение на Ubuntu Docker, включително нашето FS изображение, което съдържа nginx. Звучи малко объркващо, нали? Всъщност е доста просто.

Вече разбрахме, че всяко изображение на Docker се състои от няколко изображения на файлова система. Когато стартираме контейнера, тези изображения се монтират и сглобяват в една структура на директории с помощта на AUFS. Например, първото изображение може да съдържа само основна инсталация на Ubuntu, второто добавя набор от стандартни демони към него, третото - помощни програми за администриране и т.н. Docker монтира всички слоеве в режим само за четене, но за да можем да променим съдържанието на изображението, друг първоначално празен слой е свързан отгоре в режим на четене/запис.


По подразбиране, след като контейнерът приключи (което се случва след последния процес, изпълняван в него), последният слой се изтрива и всички наши промени се губят. Въпреки това, използвайки командата docker commit, можем да „коммитираме“ промените, като създадем ново изображение на Docker въз основа на съществуващите FS изображения плюс FS изображението с нашите промени. Това ще запази направените от нас промени. По желание можем да стартираме контейнера ubuntu-nginx, да направим промени в него и по същия начин да запазим в ново изображение на Docker, използвайки commit, като добавим още един слой. Можете да използвате командата docker images, за да видите списък с всички получени изображения (и от Docker Hub), и командата docker history, за да видите историята на формирането на слоя:

$ sudo история на докерите ubuntu-nginx

Този подход към изображенията осигурява по-голяма гъвкавост в управлението на контейнери, спестява много време и ви позволява лесно да прехвърляте вече конфигурирани Docker изображения между машини (изображението може да бъде качено в Docker Hub и след това да се разположи на друга машина). По-малко очевиден плюс е спестяването на дисково пространство. Ако разположим на машина цял зоопарк от контейнери, всеки от които първоначално ще бъде базиран на едно базово изображение (същото Ubuntu, например) - всички те ще се отнасят към това основно изображение и няма да дублират съдържанието му.


Docker извън Linux

Единственият начин да стартирате Docker на OS X или Windows е да го инсталирате във виртуална машина. Не е нужно да го правите ръчно, можете да използвате готово решение, например boot2docker. Това е набор от скриптове, които ви позволяват бързо да разположите виртуална машина на Linux и Docker във VirtualBox и да я стартирате с автоматичен SSH достъп. Инструкции за използването му и самият инсталатор могат да бъдат намерени на официалния уебсайт на Docker.

Мрежова конфигурация

За да могат контейнерите да комуникират помежду си и с външния свят, Docker автоматично повдига моста на виртуалната мрежа и конфигурира правилата за маскиране (NAT) за външния мрежов интерфейс. Това означава, че няма да е възможно да се достигне до контейнерите отвън. Въпреки това можем да конфигурираме пренасочване на портове, така че заявка към конкретни портове на външния мрежов интерфейс на машината да се пренасочва автоматично към посочените портове на контейнера. Например в Mirantis основният възел Fuel (това е GUI за разгръщане и конфигуриране на OpenStack) работи в Docker и използва пренасочване на портове, за да отвори достъп до контейнера ful / nginx (порт 8000):

$ sudo docker run -d -p 8000: 8000 гориво / nginx_6.0: най-нов /usr/local/bin/start.sh

Можем да пренасочим порт 8000 към всеки друг порт на контейнера, като просто променим второто число в опцията -p, но това няма смисъл в тази конфигурация.

Препращане на файлове и Dockerfile

В началото на статията вече се запознахме с флага -v, който ви позволява да препращате всеки файл или директория от хост системата към контейнера. Това е много удобна функция, може да се използва както за съхранение на някои временни данни, така и за споделяне на файлове между няколко контейнера. В Mirantis тази функция се използва за препращане на конфигурационни файлове за услугата Fuel / astute (/ etc / astute) вътре в контейнера:

$ sudo docker run -d -v / etc / astute fuel / astute_6.0: най-новото /usr/local/bin/start.sh

Същото може да се направи с помощта на командата VOLUME в Dockerfile. Самият Dockerfile е локален еквивалент на Makefile, но ако последният е за изграждане на приложения от източник, тогава Dockerfile ви позволява да създавате изображения за Docker. Целта му е да опрости създаването на нови изображения, без да е необходимо да стартирате контейнер, да извършвате каквито и да е операции в него и да извършвате комит. Можете просто да напишете Dockerfile и Docker ще направи всичко вместо вас. Например, помислете за Dockerfile за изграждане на Fuel / astute:

ОТ гориво / centos ПОДДЪРЖАТЕЛ Матю Мозесон [защитен с имейл]ИЗПЪЛНИ rm -rf /etc/yum.repos.d / *; \ echo -e "\ nname = Nailgun Local Repo \ nbaseurl = http: // $ (route -n | awk" /^0.0.0.0/ (отпечатайте $ 2 ) "): _ PORT_ / os / x86_64 / \ ngpgcheck = 0"> /etc/yum.repos.d/nailgun.repo; \ yum почистване на всички; \ yum --quiet install -y ruby21-nailgun-mcagents sysstat ДОБАВЯНЕ и т.н. ДОБАВЯНЕ start.sh /usr/local/bin/start.sh RUN puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/astute-only.pp; [[$? == 0 || $? == 2]] ИЗПЪЛНИ chmod + x /usr/local/bin/start.sh; \ echo -e "\ nname = Nailgun Local Repo \ nbaseurl = файл: / var / www / nailgun / centos / x86_64 \ ngpgcheck = 0 "> /etc/yum.repos.d/nailgun.repo; yum clean all VOLUME / etc / astute CMD /usr/local/bin/start.sh

Не е трудно да се разбере за какво служи. Той създава изображение на базата на гориво / centos, изпълнява няколко команди за подготовка на изображението, добавя файлове от текущата директория към изображението, прилага манифеста на Puppet, променя разрешенията за някои файлове, препраща директорията / etc / asture / от хоста система към контейнера и стартира контейнера с помощта на командата /usr/local/bin/start.sh.

За да създадете контейнер, просто поставете Dockerfile и всички файлове, които ще бъдат добавени към него в директория и изпълнете следната команда:

$ sudo docker build fuel / astute_6.0: най-нов

В този случай избрахме името гориво / astute_6.0: последно, въпреки че може да бъде всичко.

Нюанси на работа с Docker

Docker е изграден около идеята, че във всеки контейнер трябва да работи само една услуга. Пакетирате Apache, MySQL, nginx, Varnish и каквото е необходимо на вашия проект в различни контейнери и след това използвате Docker, за да изградите всичко заедно. Този подход осигурява голяма гъвкавост, тъй като ви позволява лесно да променяте конфигурацията, да тествате актуализации и да мигрирате отделни услуги към други машини.

По същата причина не е обичайно да се използва Docker за стартиране на пълноценни Linux среди с init демон, cron и syslog демони и други стандартни компоненти за разпространение. Вместо това просто стартираме услугата, от която се нуждаем, и тя работи във виртуална среда съвсем сама:

$ sudo docker run -d -p 80 ubuntu-nginx / usr / sbin / nginx

Но тук има малък проблем. Docker изключва контейнера веднага след като процесът, изпълняван в него (в този случай, nginx) бъде прекратен и тъй като nginx е демонизиран по подразбиране, тоест той разклонява нов процес и завършва този, който стартирахме на ръка, тогава Docker незабавно излиза и контейнер чрез заковаване на раздвоен Docker.

В случай на nginx, можете да заобиколите този проблем, като добавите демон изключен; първия ред в неговата конфигурация. Други демони ще изискват свои собствени настройки, а някои могат да бъдат предотвратени да демонизират директно от командния ред. Например, sshd предоставя флаг -D за това:

$ sudo docker run -d -p 22 ubuntu-ssh / usr / sbin / sshd -D

По всяко време можете да се свържете с контейнера с помощта на командата docker exec, за да видите регистрационните файлове или да промените настройките (по-нататък идентификаторът на контейнера е или идентификаторът, който може да се види в изхода на docker ps, или името, посочено в стартиране в опцията --name ):

$ sudo docker exec -ti ID на контейнера / bin / bash

Но тук има и една малка пречка. Както знаем, цялата информация, натрупана по време на работата на виртуалната среда, ще бъде загубена, ако прекратим работата на виртуалната среда, а с нея изчезнат логовете и промените, направени в настройките. Също така не можем да създаваме безкрайно слоеве (макар и само защото не може да има повече от 127 от тях), но можем да поемем по малко по-различен път и да използваме системата за агрегиране на журнали, вградена в Docker. Разбира се, Docker не може да събира регистрационни файлове на отделни приложения, но може да събира STDOUT изход, тоест всеки конзолен изход. Всичко, което остава за нас, е да променим конфигурацията на nginx, така че регистрационните файлове да се изливат в / dev / stdout и след това да ги прегледаме с помощта на командата docker logs:

$ sudo docker регистрира идентификатор на контейнера

Друга и по-правилна опция е просто да преместите регистрационните файлове (и, ако е необходимо, настройките) към хост системата, като използвате вече описаната опция -v:

$ sudo mkdir / root / logs $ sudo docker run -d -v / root / logs: / var / logs -p 80 ubuntu-nginx / usr / sbin / nginx

Ако е необходимо, контейнерът може да бъде спрян правилно чрез прекратяване на изпълняваната в него услуга с помощта на командата docker stop:

$ sudo docker стоп идентификатор на контейнера

И ако не работи правилно по някаква причина, можете да го убиете с kill:

$ sudo docker kill идентификатор на контейнера

Когато правите това, се случва едно важно нещо, което много начинаещи забравят: Docker запазва мета информацията за контейнера. Всъщност това означава, че ако стартирате, например, nginx, като посочите името му с помощта на аргументите на командата за изпълнение на docker, директории, които трябва да бъдат предадени на контейнера, портове, променливи на средата и други подобни, тогава цялата тази информация ще бъде запазен, когато контейнерът приключи и за да го стартирате следващия път, не е нужно да го указвате, а просто изпълнете следната команда (можете да използвате име вместо ID):

$ sudo docker стартов идентификатор на контейнера

Ако не е необходимо да запазвате състоянието (например за тестване или проверка на някаква функционалност), тогава можете да използвате флага --rm, който ще принуди Docker да унищожи напълно контейнера след като приключи (запазване на изображението):

$ sudo docker run --rm -i -t busybox / bin / bash

Можете да унищожите всички предварително запазени контейнери, като използвате следната команда:

# docker rm $ (docker ps -a -q)

Docker може самостоятелно да рестартира контейнери, ако се сринат и дори да ги стартира по време на стартиране на системата. Всичко, което трябва да направите, е просто да използвате опцията --restart:

$ sudo docker run --restart = винаги \ -d -v / root / logs: / var / logs -p 80 \ ubuntu-nginx / usr / sbin / nginx

По всяко време изображението може да бъде експортирано в един файл и след това импортирано на друга машина. За това са предвидени командите docker save и docker restore. Използването им е много лесно, експортирането става по следния начин:

$ sudo docker save -o ubuntu-nginx.img ubuntu-nginx

И вносът е така:

$ sudo docker load -i ubuntu-nginx.img

заключения

Docker е отличен инструмент. За непосветен човек може да изглежда като играчка, която вече не е подходяща за нищо друго освен за стартиране на софтуер в пясъчник, но може да помогне за решаването на огромен набор от задачи, за които ще говорим в следващата статия.

Предимства на Docker пред LXC, OpenVZ и други решения за виртуализация на ниво ОС

  1. Docker използва преносим общ формат на изображения. Това означава, че тези изображения могат да бъдат прехвърлени на друга машина без никакви проблеми и споделени за използване от други потребители.
  2. Изображението може да служи като основа за други изображения. В Docker се счита за нормално да се използват няколко слоя за формиране на крайното изображение. Можете да започнете с основно изображение на Ubuntu, след което да добавите Apache 2.4, за да създадете микроуслуга Ubuntu + Apache.
  3. Когато извършвате ангажимент, изображението може да бъде версияно, точно както в GIT.
  4. Docker има голяма общност и обширна екосистема, която включва значителен брой инструменти за мащабиране, групиране, наблюдение, разполагане и управление на контейнери.

Засегнали сме темата повече от веднъж и разгледахме много системи за тяхното изграждане. Днес ще представим още една страхотна система с Docker контейнери.

Нека започнем с описание на основната функционалност, която ще бъде полезна в следващите статии от поредицата, и накратко да си припомним архитектурата на Docker. Docker използва архитектура клиент-сървър и се състои от клиент-докер помощна програма, която осъществява достъп до сървъра чрез RESTful API, и демон в операционната система Linux (вж. Фиг. 1). Въпреки че Docker работи на операционни системи, различни от Linux, те не са обхванати в тази статия.

Основните компоненти на Docker:
    • Контейнери- потребителски среди, изолирани с помощта на технологии на операционната система, в които се изпълняват приложения. Най-простият начин е да дефинирате Docker контейнер като приложение, стартирано от изображение. Между другото, точно това Docker идеологически се различава от, например, от LXC ( Linux контейнери), въпреки че използват същите технологии на ядрото на Linux. Разработчиците на проекта Docker се ангажират с принципа, че един контейнер е едно приложение.
    • Изображения- шаблони за приложения само за четене. Нови нива могат да се добавят върху съществуващите изображения, които заедно представляват файловата система, модифицирайки или допълвайки предишното ниво. Обикновено ново изображение се създава или чрез запазване на вече работещ контейнер в ново изображение върху съществуващо, или чрез използване на специални инструкции за помощната програма. За да разделите различните нива на контейнер на ниво файлова система, AUFS, btrfs, vfs и Device Mapper... Ако възнамерявате да използвате Docker във връзка с SELinux, тогава е задължително Картограф на устройства.
    • регистрисъдържащи хранилища ( хранилище) изображения, - мрежови хранилища на изображения. Те могат да бъдат както частни, така и публични. Най-известният регистър е.

Операционните системи GNU / Linux използват стандартни технологии на ядрото на Linux за изолиране на контейнери, като:
  • Пространства от имена ( Пространства от имена на Linux).
  • Контролни групи ( Cgroups).
  • Инструменти за управление на привилегии ( Възможности на Linux).
  • Допълнителни, задължителни системи за сигурност, като напр AppArmor или SELinux.

Нека разгледаме изброените технологии малко по-подробно.

Механизъм за контролна група (Cgroups)предоставя инструмент за фина настройка на разпределението, приоритизирането и управлението на системните ресурси. Контролните групи са внедрени в ядрото на Linux. В съвременните дистрибуции управлението на cgroup се осъществява чрез systemd, обаче остава възможно да се контролира с помощта на библиотеката libcgroupи комунални услуги cgconfig... Основните йерархии на cgroup (наричани още контролери) са изброени по-долу:

  • blkio- задава ограничения за входно-изходни операции и за достъп до блокови устройства;
  • процесор- използвайки планировчика на процеси, разпределя процесорното време между задачите;
  • cpuacct- Генерира автоматични отчети за използването на ресурсите на процесора. Работи съвместно с контролера процесорописано по-горе;
  • cpuset- присвоява определени процесори и възли на паметта на задачите;
  • устройства- регулира достъпа на задачите до конкретни устройства;
  • фризер- преустановява или възобновява задачи;
  • памет- задава лимити и генерира отчети за използване на паметта по задачи на контролната група;
  • net_cls- извършва маркиране на мрежови пакети с идентификатор на клас ( класид). Това позволява на контролера на трафика ( команда tc) и защитна стена ( iptables) вземете предвид тези тагове при обработка на трафика;
  • perf_event- ви позволява да наблюдавате контролните групи с помощта на помощната програма перф;
  • hugetlb- ви позволява да използвате големи страници с виртуална памет и да прилагате ограничения към тях.

пространства от имена,от своя страна те контролират не разпределението на ресурсите, а достъпа до структурите от данни на ядрото. Всъщност това означава изолиране на процесите един от друг и възможността паралелно да имат "идентични", но не припокриващи се един с друг йерархии от процеси, потребители и мрежови интерфейси. При желание различните услуги могат дори да имат свои собствени loopback интерфейси.

Примери за пространства от имена, използвани от Docker:
  • PID, ID на процеса- изолиране на йерархията на процесите.
  • NET, работа в мрежа- изолация на мрежови интерфейси.
  • Компютър, междупроцесна комуникация- управление на взаимодействието между процесите.
  • MNT, Маунт- управление на точките за монтиране.
  • UTS, Unix Timesharing System- изолиране на ядрото и идентификаторите на версията.

Механизъм, наречен Възможностиви позволява да разделите привилегиите на root потребител на малки групи от привилегии и да ги присвоите отделно. Тази функционалност се появи в GNU / Linux от версията ядра 2.2.Първоначално контейнерите се стартират с ограничен набор от привилегии.

Можете да активирате и деактивирате опциите на командата docker:
  • операции за монтиране;
  • достъп до контакти;
  • Извършване на някои от операциите във файловата система, като промяна на атрибутите на файловете или на собственика.

Можете да научите повече за привилегиите, като използвате страницата man. ВЪЗМОЖНОСТИ (7).

Инсталиране на Docker

Нека да разгледаме инсталирането на Docker с помощта на CentOS като пример. Когато работите с CentOS, имате избор: да използвате най-новата версия от u pstreamили версия, изградена от проекта CentOS с добавки на Red Hat. Описание на промените е достъпно на страницата.

По принцип това е обратно пренасяне на корекции от нови версии нагоре по веригата и промени, предложени от разработчиците на Red Hat, но все още не приети в основния код. Най-забележимата разлика по време на това писане е, че в по-новите версии услугата docker е разделена на три части: демон docker, containerd и runc... Red Hat все още не смята тази промяна за стабилна и доставя монолитна версия 1.10 изпълним файл.

Настройки на хранилището за инсталиране версии нагоре по веригата, както и инструкции за инсталиране на други дистрибуции и операционни системи, са дадени в ръководството за инсталиране на официалния уебсайт. По-конкретно, настройките за хранилището на CentOS 7:

# cat /etc/yum.repos.d/docker.repo name = Docker Repository baseurl = https: //yum.dockerproject.org/repo/main/centos/7 enabled = 1 gpgcheck = 1 gpgkey = https: // yum .dockerproject.org / gpg

# котка /etc/yum.repos.d/docker.repo

име = Хранилище

baseurl = https: / / yum .dockerproject .org / repo / main / centos / 7

активиран = 1

gpgcheck = 1 gpgkey = https: / / yum .dockerproject .org / gpg

Инсталирайте необходимите пакети и стартирайте и активирайте услугата:

# yum install -y docker-engine # systemctl стартира docker.service # systemctl активира docker.service

# yum install -y docker-engine

# systemctl стартирайте docker.service

# systemctl активира docker.service

Проверка на състоянието на услугата:

# състояние на systemctl docker.service

# състояние на systemctl docker.service

Можете също да видите системна информация за Docker и средата:

# информация за докер

Ако изпълните подобна команда и инсталирате Docker от хранилищата на CentOS, ще видите малки разлики поради използването на по-стара версия на софтуера. От изхода информация за докераможем да разберем какво се използва като драйвер за съхранение на данни Картограф на устройство, а като съхранение - файл в / var / lib / docker /:

# ls -lh / var / lib / docker / devicemapper / devicemapper / data -rw -------. 1 root root 100G 27 декември 12:00 / var / lib / docker / devicemapper / devicemapper / data

# ls -lh / var / lib / docker / devicemapper / devicemapper / data

Rw - - - -. 1 корен корен 100G 27 декември 12:00 / var / lib / / devicemapper / devicemapper / data

Опциите за стартиране на демон, както обикновено се случва в CentOS, се съхраняват в / etc / sysconfig /... В този случай името на докер файла. Съответна линия / etc / sysconfig / dockerописващи опции:

ОПЦИИ = "- selinux-enabled --log-driver = journald"

Ако сте изпълнили командата docker като потребител без root или член на групата docker, ще видите грешка като тази:

$ docker търсене в mysql

$ търсене в mysql

Предупреждение: неуспешно получаване на крайна точка на системния регистър по подразбиране от демон (Не може да се свърже с демона на Docker. Демонът на docker работи ли на този хост?). Използване на системата по подразбиране: https: // индекс. docker.io/v1/

Не може да се свърже с демона на Docker. Докер демонът работи ли на този хост?

Имайте предвид, че действителното добавяне на потребител към докер групата е равносилно на добавяне на този потребител към основната група.

Разработчиците на RHEL / CentOS имат малко по-различен подход към сигурността на демона на Docker от самите разработчици на Docker нагоре. За повече информация относно подхода на Red Hat вижте статия от разработчика на RHEL Дан Уолш.

Ако искате "стандартното" поведение на Docker, инсталирано от хранилищата на CentOS (тоест описано в официалната документация), тогава трябва да създадете група за докери и да добавите към опциите за стартиране на демона:

ОПЦИИ = "- selinux-enabled --log-driver = journald ↵ --group = docker"

ОПЦИИ = "--selinux-enabled --log-driver = journald ↵ --group = docker"

След това рестартираме услугата и проверяваме дали файлът на docker socket принадлежи към групата на docker, а не root:

# ls -l /var/run/docker.sock

Намиране на изображения и Docker тагове

Нека се опитаме да намерим контейнер в Docker Hub.

$ docker search haproxy

$ търси хапрокси


В този изход получихме списък с множество HA прокси изображения. Най-горният елемент в списъка е HA прокси от официалното хранилище. Такива изображения се различават по това, че в името няма символ «/» отделяне на името на хранилището на потребителя от името на самия контейнер. Примерът зад официалния показва две haproxy изображения от отворени потребителски хранилища eeacms и милион12.

Изображения като двете по-долу можете да създадете сами, като се регистрирате в Docker Hub. Официалните са подкрепени от специален екип, спонсориран от Docker, Inc. Характеристики на официалното хранилище:

  • Това са препоръчителни изображения за използване въз основа на най-добри практики и най-добри практики.
  • Те са основни изображения, които могат да бъдат отправна точка за повече персонализиране. Например базови изображения на Ubuntu, CentOS или библиотеки и среди за разработка.
  • Съдържа най-новите версии на софтуера с фиксирани уязвимости.
  • Това е официалният канал за дистрибуция на продуктите. За да търсите само официални изображения, можете да използвате опцията – Филтър „е-официален = вярно“команди докер търсене.

Звезди в командния изход докер търсенесъответства на популярността на изображението. Това е аналогът на бутона катов социалните мрежи или маркиране за други потребители. Автоматизираниозначава, че изображението се създава автоматично от персонализиран скрипт с помощта на Docker Hub. Обикновено трябва да дадете предпочитание на автоматично събирани изображения поради факта, че съдържанието му може да бъде проверено чрез запознаване със съответния файл.

Изтеглете официалното HA прокси изображение:

$ docker pull haproxy Използване на таг по подразбиране: последно

Пълното име на изображението може да изглежда така:

[потребителско име] име на изображение [: етикет]

Можете да видите списъка с изтеглени изображения с командата докер изображения:

Пускане на контейнери

Не е необходимо да изтегляте изображението, за да стартирате контейнера. Ако е налично, ще се зареди автоматично. Нека се опитаме да стартираме контейнер с Ubuntu. Няма да изброяваме хранилището и ще изтеглим най-новото официално изображение, поддържано от Canonical.

$ docker run -it ubuntu [защитен с имейл]:/#

$ run - това е ubuntu

root @ d7402d1f7c54: / #

Освен отбора бягай, посочихме две опции: -i- контейнерът трябва да работи интерактивно и - трябва да се подчертае псевдотерминал. Както можете да видите от изхода, имаме права на root потребител в контейнера и идентификаторът на контейнера се показва като име на хост. Последното може да не е вярно за всички контейнери и зависи от разработчика на контейнера. Нека проверим дали това наистина е средата на Ubuntu:

[защитен с имейл]: / # cat / etc / * освобождаване | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

root @ d7402d1f7c54: / # котка / etc / * освобождаване | grep DISTRIB_DESCRIPTION

DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

Команда Uname за такива цели няма да работи, тъй като контейнерът работи с ядрото на хоста.

Една от опциите може да бъде уникално име на контейнер, което може да бъде посочено за удобство, в допълнение към ID на контейнера.Дава се като – Име<имя>. Ако опцията е пропусната, името се генерира автоматично.

Автоматично генерираните имена на контейнери не носят семантичен товар, но като интересен факт може да се отбележи, че имената се генерират на случаен принцип от прилагателното и името на известен учен, изобретател или хакер. В кода на генератора за всяко име можете да намерите кратко описание на това с какво е известна дадената фигура.

Можете да видите списъка с работещи контейнери с командата. За да направите това, отворете втори терминал:

Ако обаче издадем командата, няма да намерим контейнера, създаден от изображението на mysql. Да използваме опцията който показва всички контейнери, не само работещи контейнери:

Очевидно необходимите параметри не са посочени при стартиране на контейнера. За описание на променливите на средата, необходими за стартиране на контейнер, вижте официалното изображение на MySQL в Docker Hub. Нека опитаме отново, използвайки опцията който задава променливите на средата в контейнера:

$ docker run --name mysql-test ↵ -e MYSQL_ROOT_PASSWORD = docker -d mysql

Последният параметър е командата, която искаме да изпълним вътре в контейнера. В този случай това е командният интерпретатор. Баш... Настроики -тоса подобни по предназначение на използваните по-рано в командата docker run.

Всъщност след изпълнение на тази команда в контейнера mysql-тестдобавя се още един процес - bash... Това може да се види ясно с помощта на командата pstree. Съкратен изход към командата docker exec: