Капитанът на товарен кораб или как да започнете да използвате Docker във вашите проекти

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

Най-лесният начин да разберете идеята зад Docker е да го сравните с нормален транспортен контейнер. Имало едно време транспортните компании се сблъсквали със следните проблеми:

  • Как да транспортирате различни (несъвместими) видове товари, като храни и химикали или стъкло и тухли?
  • Как да обработваме пакети с различни размери, използвайки един и същ транспорт?

След появата на контейнерите стана възможно да се поставят тухли върху стъкло и да се съхраняват химикали до храна. Товар с различни размери може да бъде поставен в стандартен контейнер, който се товари / разтоварва от същия транспорт.

Но обратно към контейнерите в разработката на софтуер.

Написаният код понякога трябва да се споделя с други хора, например разработчици. Освен това всички негови зависимости, като библиотеки, уеб сървър, бази данни и т.н., трябва да бъдат изпратени в комплекта. Може да се сблъскате със ситуация, при която дадено приложение работи на компютър, но не може да работи на тестов сървър, компютър на програмист или изпитател.

Как се различава от виртуализацията?

Традиционно виртуалните машини се използват за избягване на неочаквано поведение. Основният проблем при тях е, че "вторичната ОС" върху основната ОС добавя гигабайти пространство към проекта. През повечето време вашият сървър ще съдържа множество виртуални машини, които ще заемат още повече място. Друг съществен недостатък е бавното зареждане.

Docker решава тези проблеми, като разделя ядрото между всичкиконтейнери, които се изпълняват като отделни процеси на основната ОС.

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

Защо имаме нужда от Docker?

Списъкът с предимства е:

  • Бърз процес на развитие. Няма нужда да инсталирате програми на трети страни като PostgreSQL, Redis, Elasticsearch. Могат да се пускат в контейнери.
  • Удобно капсулиране на приложението. Можете да предоставите вашето приложение като едно цяло.
  • Същото поведение на локална машина и тестов/производствен сървър.
  • Лесно и ясно наблюдение.
  • Лесен за мащабиране. Ако сте направили приложението си правилно, тогава то ще бъде готово за мащабиране отвъд Docker.

Поддържани платформи

Linux е родна Docker платформа, тъй като последната се основава на функции, предоставени от ядрото на операционната система. Независимо от това, можете да го стартирате на macOS или Windows. Единствената разлика е, че Docker е капсулиран върху тях в малка виртуална машина. В момента Docker за тези операционни системи е достигнал значително ниво на използваемост и е много подобен на естествено приложение.

Освен това има много допълнителни приложения като Kitematic или Docker Machine, които да ви помогнат да инсталирате и управлявате Docker на различни от Linux платформи.

Можете да видите инструкциите за инсталиране на официалния уебсайт. Ако използвате Docker на Linux, трябва да изпълните всички следните команди като root или да добавите вашия потребител към групата на docker и да влезете отново:

Терминология

Пример 1: Здравей свят

Време естартирайте първия си контейнер:

  • docker run е командата, която стартира контейнера.
  • ubuntu е изображението, което изпълнявате, като например изображението на Ubuntu OS. Когато го дефинирате, Docker започва да разглежда Docker хоста. Ако изображението не съществува локално, то ще бъде изтеглено от публичния регистър - Docker Hub.
  • /bin/echo 'Hello world' е командата, която ще бъде изпълнена в новия контейнер. Този контейнер просто ще отпечата „Hello world“ и ще спре изпълнението.

Нека се опитаме да създадем интерактивна обвивка в Docker контейнер:

  • -t е флаг, който добавя псевдо-терминал в нов контейнер.
  • -i е флаг, който ви позволява да установите интерактивна връзка, като вземете стандартния вход (STDIN) на контейнера.
  • --rm е флаг, който автоматично изтрива контейнера след прекратяване на процеса. По подразбиране контейнерите не се изтриват. Този контейнер съществува, докато текущата сесия на обвивката е установена и се унищожава, когато напуснем сесията (например SSH сесия с отдалечен сървър).

Ако искате контейнерът да продължи да работи след края на сесията, превърнете го в процес на демон:

  • --name daemon - задава името на демона за новия контейнер. Ако не посочите име, Docker ще генерира и присвои такова автоматично.
  • -d - флаг стартира контейнера във фонов режим (демонизира го).

Нека да разгледаме какви контейнери имаме в момента:

  • docker ps е команда за изброяване на контейнери.
  • -a е флаг, който показва всички контейнери (без този флаг ps ще изброява само работещи контейнери).

Командата ps показа, че имаме само два контейнера:

  • gifted_nobel (име за този контейнергенериран автоматично, той ще бъде различен на вашия компютър) - това е първият контейнер, който създадохме, той извежда "Hello world" веднъж.
  • daemon е третият контейнер, който създадохме, работещ като фонов процес.

Забележка : няма втори контейнер (с интерактивна обвивка), защото сме задали флага --rm. В резултат на това този контейнер беше автоматично изтрит веднага след изпълнението.

Нека проверим регистрационните файлове и да видим какво прави фоновият контейнер в момента:

  • docker logs - комбинира журнали на контейнери.
  • -f - флаг за наблюдение на изхода на регистрационни файлове (работи по същия начин като tail -f).

Сега нека спрем фоновия контейнер:

Уверете се, че контейнерът е спрян:

Контейнерът е спрял. Можем да го рестартираме:

Нека се уверим, че работи:

Сега нека го спрем отново и премахнем всички контейнери ръчно:

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

  • docker rm е команда за премахване на контейнер.
  • -f е флаг за rm, който спира контейнера, ако работи (принудително премахване).
  • -q е флаг за ps, който отпечатва само идентификатори на контейнери.

Пример 2: Nginx

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

Време е да създадете и стартирате по-полезен контейнер като Nginx.

Променете директорията на examples/nginx:

  • -p - съпоставяне на порт HOST PORT:CONTAINER PORT.
  • -v - том за монтиране ХОСТ ДИРЕКТОРИЯ: ДИРЕКТОРИЯ ЗА КОНТЕЙНЕР.

Важно : Командата за изпълнение приема само абсолютни пътища. В нашия примеризползвахме $(pwd), за да зададем абсолютния път на текущата директория.

Сега можете да отворите localhost във вашия браузър.

Или можете да промените /example/nginx/index.html (който е монтиран като том в /usr/share/nginx/html вътре в контейнера) и да опресните страницата.

Получете информация за контейнера test-nginx:

Тази команда показва широка системна информация за инсталацията на Docker. Тази информация включва версия на ядрото, брой контейнери и изображения, отворени портове, монтирани томове и т.н.

Пример 3: писане на Dockerfile

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

  • FROM - инсталира основното изображение.
  • RUN - изпълнява команда в контейнер.
  • ENV - задава променлива на средата.
  • WORKDIR - задава работната директория.
  • VOLUME - създава точка на монтиране за тома.
  • CMD - Задава изпълним файл за контейнера.

Сега ще създадем изображение, което ще получи съдържанието на сайта с помощта на curl и ще го запише в текстов файл. Трябва да предадем URL адреса на сайта през променливата на средата SITE_URL. Полученият файл ще бъде поставен в директория, монтирана като том:

Dockerfile е готов. Сега е време да създадете самото изображение.

Нека отидем на examples/curl и изпълним следната команда, за да създадем изображението:

  • docker bulid - създава ново локално изображение.
  • -t - задава етикет с име за изображението.

Сега имаме ново изображение и можем да видим списъка със съществуващите:

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

За да видите резултатите, записани във файл, изпълнете командата:

Нека опитаме с facebook.com:

Да видим отново резултатите:

Пример 4: Свързване на Python + Redis контейнери

Docker compose е единственият правилен начин за свързване на контейнери един към друг. В този пример ще свържем контейнерите на Python и Redis:

Нека да преминем към примери/съставяне и да изпълним следната команда:

Вече можете да си поиграете с различните изображения от Docker Hub или, ако предпочитате, да създадете свои собствени изображения, като следвате най-добрите практики, посочени по-долу. Единственото нещо, което трябва да добавите относно използването на docker-compose, е винаги да давате точните имена на вашите томове в docker-compose.yml (ако има томове в изображението). Това просто правило ще ви спести проблеми, когато проверявате обемите си.

В този случай redis_data ще бъде името в docker-compose.yml, действителното име на тома ще бъде с префикс името на проекта.

Без точното име на тома UUID ще бъде там. Ето пример от локална машина:

Ръководства за стил на докер

Docker има някои ограничения и изисквания, които зависят от архитектурата на системата (приложенията, които контейнеризирате). Можете да пренебрегнете тези изисквания или да намерите някои заобиколни решения, но в този случай няма да получите пълните предимства от използването на Docker. Силно се препоръчва да следвате следните съвети:

  • 1 приложение = 1 контейнер.
  • Стартирайте процеса на преден план (не използвайте systemd, upstart или подобни инструменти).
  • Използвайте обеми за съхраняване на данни извън контейнер.
  • Не използвайте SSH (ако трябва да влезете в контейнера, използвайте docker exec).
  • Избягвайте ръчнонастройки или действия вътре в контейнера.
  • Включете само необходимия контекст - използвайте файл .dockerignore (като .gitignore в git).
  • Избягвайте да инсталирате ненужни пакети - това ще заеме допълнително дисково пространство.
  • Използвайте кеша. Добавете контекст, който се променя често, като изходния код на вашия проект, в края на Dockerfile - кешът на Docker ще се използва по-ефективно.
  • Внимавайте с обемите. Трябва да запомните какви данни има в томовете. Тъй като томовете са постоянни и не изчезват с контейнери, следващият контейнер ще използва данните, създадени от предишния контейнер.
  • Използвайте променливи на средата: RUN, EXPOSE, VOLUME. Това ще направи вашия Dockerfile по-гъвкав.

Заключение

В заключение си струва да се отбележи, че Docker се превърна в един от необходимите инструменти за разработчици, заедно с различни IDE и Git.