Что такое докер и зачем он нужен

Как жить с Docker, или почему лучше с ним, чем без него?

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

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

Итак, возможно вы прошли docker tutorial, докер кажется простым и полезным, но вы пока не знаете, как он может вам помочь с вашими проектами.

Как с этим поможет Docker под катом. Итак начнем не с docker, а с того, как мы жили без него.

Как мне доставить код на сервера?

Первое, что приходит на ум, это собрать все в пакет. RPM или DEB не играет роли.

Пакеты

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен
В системе уже есть пакетный менеджер, который может управлять файлами, обычно мы ожидаем от него следующего:

Итого вероятность справиться с задачей примерно 30% (хотя на практике всегда выпадают варианты 2 или 3). И если со второй ситуацией еще можно как-то справиться (виртуалка там или lxc), то третья ситуация или добавит в ваш зверинец еще одного зверя, или собираем ручками в /usr/local привет нулевые/слакваяря и т.д.

В целом, эта ситуация называется dependency hell. Вариантов решения этому масса, от простых chroot до сложных проектов, типа NixOs.

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен
К чему это я. Ах, ну да. Как только вы начинаете собирать все в пакеты и гонять их на одной и той же системе, у вас ситуация dependency hell обязательно будет. Решить ее можно по-разному. Или под каждый проект городить новый репозиторий плюс новую виртуалку/hardware, или ввести ограничения. Под ограничениями я имею ввиду некий набор политик компании, вроде: «У нас тут только libyy-vN.N. Кому не нравится, в отдел кадров с заявлением.». Про N.N я тоже не просто так сказал, некоторые библиотеки не могут жить на одном сервере в двух версиях. Ограничения ничего не дают в конечном итоге. Бизнес, да и здравый смысл, быстро разрушат их все.

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

Деплой через GIT

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен
Неплохо подходит для интерпретируемых языков. Не годится для чего-то, что нужно скомпилировать. И также не избавляют от dependency-hell.

Как мне запустить код на серверах?

На этот вопрос придумано много всего: daemontools, runit, supervisor. Считаем, что этот вопрос имеет как минимум один верный ответ.

Как мне обеспечить одинаковость окружения, в котором запускается и работает мой код?

Представим себе банальную ситуацию, вы все тот же DevOps, к вам приходит задача, нужно развернуть проект «Eniac» (имя взято из генератора имен для проектов) на N серверах, где N больше 20.

Вы тащите Eniac из GIT, он на известной вам технологии (Django/RoR/Go/1C), собираете его привычным методом, запускаете и… не работает. Связываетесь с разработчиком, ругаете его по первое число, что он как обычно «криворук». А он вам все обратно, и «криворук» уже вы. У разработчика все работает. С точки зрения вашего начальника, вы не можете запустить проект. Именно вы. Так как тестировщики, проект, развернутый на компьютере разработчика, все приняли.

Понимаете проблему. Идем дальше, вам удается запустить Eniac на одном сервере, и не получается еще на N-1.

Как же Docker поможет мне?

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен
Ну, во-первых давайте разберемся, как Docker использовать как средство доставки проектов на «железо».

Приватный Docker Registry

Что такое Docker Registry? Это то, что хранит ваши данные, подобно WEB серверу, который раздает deb-пакеты и файлы с метаданными для них. Docker Hub вы можете установить на виртуалке в Amazon и хранить данные в Amazon S3, или же поставить на свою инфраструктуру и хранить данные в Ceph или на ФС.

Сам docker registry тоже можно запустить dockerом. Это всего лишь приложение на python (видимо, на go не осилили написать библиотеки к хранилищам, коих большое количество поддерживает registry).

А как в это хранилище попадет наш проект, разберем позже.

Как мне запустить код на серверах?

Сейчас сравним, как мы доставляем проект обычным менеджером пакетов. Например apt:

Эта команда годится для автоматизации. Она сама все тихо сделает, останется перезапустить наше приложение.

Теперь пример для Docker:

И все. Docker скачает с вашего docker registry, расположенного по адресу 192.168.1.1 и слушающим порт 80 (у меня тут nginx), все что нужно для запуска, и запустит superproject-run.sh внутри образа.

Что случится, если в образе 2 программы, которые мы запускаем, и, скажем, в следующем релизе одна из них поломалась, однако другая напротив, набрала фич, которые нужно выкатить. Нет проблем:

И теперь у нас уже 2 разных контейнера, и внутри их может быть совершенно разные версии системных библиотек файлов и т.д.

Как мне обеспечить одинаковость окружения в котором запускается и работает мой код?

В случае со стандартными виртуальными машинами или вообще реальными системами придется следить за всем самому. Ну или изучать Chef/Ansible/Puppet или что-то еще из подобных решений. Иначе никак не гарантировать что xxx-utils одинаковой версии на всех N серверах.

В случае с docker ничего делать не нужно, просто разворачиваем контейнеры из одинаковых образов.

Сборка контейнеров

Для того, чтобы ваш код попал в docker registry (ваш или глобальный не имеет значения), вам придется его туда запушить.

Можно заставить разработчика собирать контейнер самостоятельно:

Или же собирать автоматически. Я не нашел ничего, что собирает контейнеры, поэтому вот, есть мною собранный велосипед под названием lumper

Dockerfile

На самом деле нет ничего сложного. Например соберем lumper с помошью Dockerfile.

Заключение

Для того, чтобы запускать контейнеры на серверах есть несколько путей, можно или написать init-script или посмотреть на Fig который может разворачивать целые решения из ваших контейнеров.

Также я намеренно обошел стороной темы пробросов портов, и ip маршрутизации контейнеров.

Также, так как технология молодая, у docker огоромное community. И прекрасная документация. Спасибо за внимание.

Источник

Docker — это игрушка или нет? Или всё-таки да?

Ооочень хочется прям сразу приступить к теме, но правильнее будет немного рассказать про мою историю:

Вступление

Я программист с опытом разработки frontend одностраничных приложений, scala/java и nodejs на сервере.

Довольно долго (уже точно пару — тройку лет), я придерживался мнения, что docker это манна небесная и вообще очень крутой инструмент и абсолютно каждый разработчик должен уметь пользоваться им. А отсюда вытекает, что и у каждого разработчика должен стоять docker на локальной машине. Да что там про моё мнение, вы полистайте вакансии, которые размещаются на том же hh. В каждой второй есть упоминание про docker и если вы им владеете — это будет вашим конкурентным преимуществом 😉

На своем пути я встечался с многими людьми, с их разным отношением к docker и к его экосистеме. Одни говорили, что это удобная вещь, гарантирующая кроссплатформенность. Вторые не понимали зачем им запускаться в контейнерах и какой профит от этого, третьим было вообще пофиг и они не парились (просто писали код и уходили домой — завидую, кстати, им 🙂 )

Причины использования

Почему я использовал docker? Наверное по следующим причинам:

Что мне всегда НЕ нравилось в docker:

Мне всегда не нравилось, что приходится слишком долго возиться с docker-ом на начальном этапе: я придумывал как запускать контейнеры, из каких образов запускаться, делал Makefile, которые содержали алиасы к длинным docker командам. Терпеть не мог docker-compose, потому что не хотел учить еще один инструмент экосистемы docker. И docker-compose up меня напрягала, особенно, если там еще встречались build конструкции, а не уже собранные образы. Все, что я реально хотел — это просто делать продукт эффективно и быстро. Но я никак не мог разложить по полочкам использование docker.

Знакомство с Ansible

Недавно (тройку месяцев назад), я поработал с DevOps командой, почти каждый участник которой, негативно относился к docker. По причинам:

Docker для запуска сторонних компонентов типа бд

Недавно я познакомился с ssh тунелями. Оказалось, что очень просто «пробросить» порт удаленного сервера на локальный порт. Удаленный сервер может быть как машиной в облаке, так и виртуальной машиной, запущенной в VirtualBox. Если мне или моему коллеге нужна бд (или какой нибудь другой сторонний компонент), можно просто запустить сервер с этим компонентом и загасить, когда сервер не нужен. Проброс портов дает такой же эффект, как и бд, запущенная в docker контейнере.

Эта команда пробрасывает мой локальный порт на удаленный сервер с postgresql:

Использование удаленного сервера решает проблему с разработкой в команде. Таким сервером могут пользоваться сразу несколько разработчиков, им не нужно уметь настраивать postgresql, разбираться c docker и с прочими изощрениями. На удаленном сервере можно установить ту же бд в самом docker, если поставить спецефичную версию трудно. Все что будет нужно разработчикам — это выдать ssh доступ!

Недавно прочитал, что SSH тунели — это ограниченная функциональность обычного VPN! Можно просто настроить OpenVPN или другие реализации VPN, настроить инфраструктуру и дать ее в пользование разработчикам. Это ведь так круто!

Благо, AWS, GoogleCloud и прочие, дают год бесплатного использования, так используйте их! Они копеечные, если их гасить, когда не используются. Я всегда задумывался, в каких целях мне бы понадобился удаленный сервер типа gcloud, кажется, что я нашел их.

В качестве виртуальной машины на localhost можно использовать тот же Alpine который активно используется в docker контейнерах. Ну или какие-нибудь другие облегченные дистрибутивы, чтобы побыстрее загружалась машина.

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

Немного про docker образы и дистрибуцию

Я уже писал статью, в которой хотел донести, что использование docker образов не дает никакой гарантии. Docker образы нужны только для того чтобы создать docker контейнер. Если вы зашиваетесь на docker образ значит вы завязываетесь на использование docker контейнеров и вы будете только с ними.

Вы видели где-нибудь, чтобы разработчики ПО портировали свои продукты только в docker образе?
Результат большинства продуктов — это бинарные файлы под определенную платформу, именно их просто добавляют в docker образ, который наследуется от нужной платформы. Вы не задумывались, почему в dockerhub так много похожих образов? Вбейте, например nginx, вы увидите 100500 образов от разных людей. Эти люди не разрабатывали сам nginx, они просто в свой docker образ добавили официальный nginx и приправили своими конфигами для удобства запуска контейнеров.

В общем хранить можно просто в tgz, если кому-то понадобится запускать это в docker, то пусть в Dockerfile добавляют tgz, наследуются от нужного окружения и создают дополнительные плюшки, которые не меняют самого приложения в tgz. Тот, кто будет создавать docker образ, будет знать, что это за tgz и что ему нужно для работы. Именно так я использую docker тут

Итог: мне не нужен docker registry, воспользуюсь каким нибудь S3 или просто файловым хранилищем типа google drive/dropbox

Docker в CI

Все компании, в которых я работал, похожи друг на друга. Они, как правило, продуктовые. То есть у них есть какое-то одно приложение, один стек технологий (ну может пара — тройка языков программирования).

Эти компании используют docker на своих серверах где запускается CI процесс. Вопрос — зачем нужно собирать проекты в docker контейнере на своих серверах? Почему просто не подготовить окружение для сборки, например написать Ansible плейбук, который будет ставить нужные версии nodejs, php, jdk, копировать ssh ключи и пр. на сервер, в котором будет происходить сборка?

Сейчас я понимаю, что это стрельба себе по ногам, потому что docker не приносит никакого профита со своей изоляцией. Проблемы с CI в docker с которыми я столкнулся:

Разработчики не собирают проекты в docker контейнерах ( я — когда то был таким фанатом, жалко себя в прошлом xD ). В java есть возможность иметь несколько версий и менять одной командой на ту, которая нужна сейчас. В nodejs тоже самое, есть nvm.

Вывод

Я считаю что docker очень мощный и гибкий инструмент, в этом его недостаток (звучит странно, да). На него легко «подсаживаются» компаниии, используют где нужно и не нужно. Разработчики запускают свои контейнеры, какое то свое окружение, потом это все плавно перетекает в CI, продакшн. DevOps команда пишет какие то велосипеды чтобы запустить эти контейнеры.

Используйте docker только на самом последнем этапе в вашем рабочем процессе, не тащите его в проект в начале. Он не решит ваших бизнес проблем. Он только сдвинет проблемы на ДРУГОЙ уровень и будет предлагать свои варианты решения, вы будете делать двойную работу.

Когда docker нужен: пришел к мысли что docker очень хорош в оптимизации поставленного процесса но не в построении базового функционала

Если вы все-таки решили использовать docker, то:

Спасибо, что дочитали, желаю вам прозрачных решений в ваших делах и продуктивных рабочих дней!

Источник

Изучаем Docker, часть 1: основы

Технологии контейнеризации приложений нашли широкое применение в сферах разработки ПО и анализа данных. Эти технологии помогают сделать приложения более безопасными, облегчают их развёртывание и улучшают возможности по их масштабированию. Рост и развитие технологий контейнеризации можно считать одним из важнейших трендов современности.

Docker — это платформа, которая предназначена для разработки, развёртывания и запуска приложений в контейнерах. Слово «Docker» в последнее время стало чем-то вроде синонима слова «контейнеризация». И если вы ещё не пользуетесь Docker, но при этом работаете или собираетесь работать в сферах разработки приложений или анализа данных, то Docker — это то, с чем вы непременно встретитесь в будущем.

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

Если вы пока не знаете о том, что такое Docker, сейчас у вас есть шанс сделать первый шаг к пониманию этой платформы. А именно, освоив этот материал, вы разберётесь с основами Docker и попутно приготовите пиццу.

Метафоры и Docker

Мы постоянно сталкиваемся с метафорами. Если заглянуть в словарь Ожегова, то окажется, что метафора — это «скрытое образное сравнение, уподобление одного предмета, явления другому». Метафоры помогают нам ухватывать суть новых для нас явлений. Например, виртуальные контейнеры можно сравнить с обычными пластиковыми контейнерами. Такое сравнение, через сопоставление уже известных нам свойств обычных контейнеров со свойствами виртуальных контейнеров, поможет сначала с ними познакомиться, а потом и понять их сущность.

Как вы понимаете, мы собираемся начать разговор о Docker с понятия «контейнер».

Контейнер

Как и обычный пластиковый контейнер, контейнер Docker обладает следующими характеристиками:

Живые организмы

Ещё один подход к размышлениям о контейнерах Docker заключается в сравнении их с экземплярами живых организмов. «Экземпляр» — это нечто, существующее в некоей форме. Это не просто код. Это код, который стал причиной существования чего-то большего, чем он сам, чего-то, образно говоря, живого. Как и другие живые организмы, экземпляры контейнеров появляются на свет, живут и умирают.

Монстр, вызванный к жизни

Контейнеры Docker — это вызванные к жизни образы Docker.

Программное обеспечение

Контейнеры Docker можно сравнивать не только с обычными контейнерами или с живыми организмами. Их можно сравнить и с программами. В конце концов, контейнеры — это программы. И, на фундаментальном уровне, контейнер представляет собой набор инструкций, который выполняется на некоем процессоре, обрабатывая какие-то данные.

Контейнер — это программа

Во время выполнения контейнера Docker внутри него обычно выполняется какая-то программа. Она выполняет в контейнере некие действия, то есть — делает что-то полезное.

Например, код, который работает в контейнере Docker, возможно, отправил на ваш компьютер тот текст, который вы сейчас читаете. Вполне возможно и то, что именно код, выполняющийся в контейнере Docker, принимает голосовые команды, которые вы даёте Amazon Alexa, и преобразует их в инструкции для ещё каких-нибудь программ, работающих в других контейнерах.

Благодаря использованию Docker можно, на одном и том же компьютере, одновременно запускать множество контейнеров. И, как и любые другие программы, контейнеры Docker можно запускать, останавливать, удалять. Можно исследовать их содержимое и создавать их.

Концепции Docker

▍Виртуальные машины

Предшественниками контейнеров Docker были виртуальные машины. Виртуальная машина, как и контейнер, изолирует от внешней среды приложение и его зависимости. Однако контейнеры Docker обладают преимуществами перед виртуальными машинами. Так, они потребляют меньше ресурсов, их очень легко переносить, они быстрее запускаются и приходят в работоспособное состояние. В этом материале можно найти подробное сравнение контейнеров и виртуальных машин.

▍Образ контейнера Docker

Выше мы уже говорили об «образах». Что это такое? Хороший вопрос. То, что в терминологии Docker называется «образом», или, по-английски, «image», это совсем не то же самое, что, например, фотография (это — одно из значений слова «image»).

Образы Docker — это не фотографии

Образы контейнеров Docker можно сравнить с чертежами, с формочками для печенья, или с пресс-формами для изготовления пластиковых изделий. Образы — это неизменные шаблоны, которые используются для создания одинаковых контейнеров.

Образы контейнеров Docker похожи на формочки для печенья

В образе контейнера Docker содержится образ базовой операционной системы, код приложения, библиотеки, от которого оно зависит. Всё это скомпоновано в виде единой сущности, на основе которой можно создать контейнер.

▍Файл Dockerfile

Файл Dockerfile содержит набор инструкций, следуя которым Docker будет собирать образ контейнера. Этот файл содержит описание базового образа, который будет представлять собой исходный слой образа. Среди популярных официальных базовых образов можно отметить python, ubuntu, alpine.

И, наконец, в образе может содержаться, поверх всех остальных, ещё один тонкий слой, данные, хранящиеся в котором, поддаются изменению. Это — небольшой по объёму слой, содержащий программу, которую планируется запускать в контейнере.

▍Контейнер Docker

▍Репозиторий контейнеров

Если вы хотите дать возможность другим людям создавать контейнеры на основе вашего образа, вы можете отправить этот образ в облачное хранилище. Самым крупным подобным хранилищем является репозиторий Docker Hub. Он используется при работе с Docker по умолчанию.

Мы уже довольно много всего обсудили. Пришло время собрать всё это вместе и сравнить работу с контейнерами Docker с приготовлением пиццы.

Готовим с Docker

Готовая пицца — это контейнер

Духовка — это платформа Docker

Духовка, в которой готовится пицца, напоминает платформу Docker. Духовку устанавливают на кухне, с её помощью можно готовить еду. Точно так же Docker устанавливают на компьютере для того, чтобы «готовить» контейнеры.

Духовку, если она электрическая, включают, поворачивая ручку регулятора температуры. Команда docker run image_name — это нечто вроде такого регулятора температуры, «поворот» которого приводит к тому, что система создаёт и запускает контейнер.

Готовая пицца — это и есть контейнер Docker.

А есть пиццу — значит пользоваться приложением, запущенным в контейнере.

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

Итоги

Здесь мы, на концептуальном уровне, рассмотрели основы Docker. Надеемся, приведённые здесь сравнения помогли вам разобраться в том, что такое Docker, и ощутить ценность метафор в деле освоения новых технологий.

Уважаемые читатели! Эта публикация представляет собой перевод первой статьи из серии учебных материалов по Docker. По словам автора, всего планируется выпустить 5 таких материалов. Уже готовы вторая, третья и четвёртая части. Подскажите нам, стоит ли переводить следующие статьи этой серии?

Источник

Лабораторная работа: введение в Docker с нуля. Ваш первый микросервис

Привет, хабрапользователь! Сегодня я попробую представить тебе очередную статью о докере. Зачем я это делаю, если таких статей уже множество? Ответов здесь несколько. Во-первых не все они описывают то, что мне самому бы очень пригодилось в самом начале моего пути изучения докера. Во-вторых хотелось бы дать людям к теории немного практики прямо по этой теории. Одна из немаловажных причин — уложить весь накопленный за этот недолгий период изучения докера опыт (я работаю с ним чуть более полугода) в какой-то сформированный формат, до конца разложив для себя все по-полочкам. Ну и в конце-концов излить душу, описывая некоторые грабли на которые я уже наступил (дать советы о них) и вилы, решение которых в докере просто не предусмотрено из коробки и о проблемах которых стоило бы задуматься на этапе когда вас распирает от острого желания перевести весь мир вокруг себя в контейнеры до осознавания что не для всех вещей эта технология годна.

Что мы будем рассматривать в данной статье?

В Части 0 (теоретической) я расскажу вам о контейнерах, что это и с чем едят
В Частях 1-5 будет теория и практическое задание, где мы напишем микросервис на python, работающий с очередью rabbitmq.
В Части 6 — послесловие

Часть 0.0: прогреваем покрышки

Что такое Докер? это такой новомодный способ изоляции ваших приложений друг от друга с помощью linux namespaces. Он крайне легок в управлении, расширении, миграции и подходит для огромного спектра задач начиная от разработки приложений и сборки пакетов и заканчивая тестами-пятиминутками (запустить-проверить 1-2 команды-закрыть и забыть, да так чтобы еще и мусор за тобой прибрали). Читайте подробнее на офф сайте. Стоит только представлять себе на первом этапе, что контейнер состоит из слоев, т.е. из слепков состояний файловой системы. Я расскажу об этом чуть позже.

Лабораторная инфраструктура данной статьи может быть воспроизведена как на одной ОС с Linux на борту, так и на серии виртуальных машин\vps\whatever. Я делал все на одном дедике (dedicated server) с ОС Debian. Здесь и далее я предполагаю что вы работаете в одной ОС Debian 9. Команды и подходы от ОС к ОС могут отличаться, описать все в одной статье нереально, поэтому выбрана наиболее знакомая мне серверная ОС. Надеюсь для вас не составит труда установить себе виртуальную машину и дать ей выход в интернет.

Часть 0.1 Сравнение с VM

Важно помнить, что Docker — средство изоляции процесса(задачи), а это значит относиться к докеру как к виртуалке нельзя. Он является оберткой вокруг средств контейнеризации ( cgroups + namespaces ) конкретно linux kernel. Но он имеет многие похожие фишки, как и у виртуализации:

Часть 0.2 Процессы в контейнерах

Теперь, когда мы выяснили что такое docker, посмотрим в бинокль что там внутри. Нужно запомнить следующие постулаты:

Часть 0.3 Откуда брать эти ваши контейнеры? как хранить?

Существуют публичные и приватные хранилки официальных и неофициальных образов. Они называются docker registry. Самый популярный из них — Docker hub. Когда вы докеризуете какой-либо сервис, сходите сначала на хаб и посмотрите, а не сделал ли это кто-то уже за вас?

Также это будет сильным подспорьем для вас в момент изучения. поскольку на хабе виден готовый Dockerfile, то вам можно будет подглядеть у крутых дядек, а как они делают ту или иную штуку. Много их хранится на github и других подобных ресурсах.

Кроме публичных registry существуют еще и приватные — платные и бесплатные. Платные вам понадобятся, когда вы в замучавшись обуслуживанием воскликните «да пусть вот эти ребята следят за всей этой слоёной docker-вакханалией в этих ваших registry». И правда, когда вы активно пользуетесь при DevOps докером, когда люди или автоматика билдит сотни контейнеров, то рано или поздно у вас начнет подгорать от того как это чистить и обслуживать.

Не все конечно так плохо, естественно. Для десятка человек и пары билдов в день подойдет и свой registry. Для личного пользования тем более.

Зачем может пригодиться registry? это единое место хранения и обмена контейнерами между вами, другими людьми или автоматикой. И вот это по-настоящему крутая штука. Положить и забрать готовый контейнер можно всего одной командой, а при условии того что весит он копейки (по сравнению с VM), то плюсы просто на лицо. Правда стоит помнить, что docker — инструмент, docker registry не хранит данных ваших рабочих контейнеров. Таким образом можно иметь крайне удобный воркфлоу: разработчики пишут продукт, билдят новый контейнер, пушат его в репозиторий. Тестироващики забирают его, тестируют, дают отмашку. Девопсы затем с помощью, например, ansible накатывают контейнеры на прод. Причем вам абсолютно не важно, 1 у вас сервер или 100, с помощью ansible и registry раскатывание контейнеров в прод — одно удовольствие. Здесь же и весь фарш с CI — новые версии могут быть автоматически скачаны билд-сервером. Посему очень рекомендую, даже для личного пользования, завести себе VPS\DS с registry, это очень удобно — обмениваться контейнерами.

Скачать образ из репозитория:

Загрузить образ в репозиторий:

В приватные репозитории нужно еще и логиниться, для этого вам пригодится команда

где потребуется ввести логин и пароль.

Запустить свой registry можно всего одной командой:

Подробнее на офф сайте. SSL, авторизация — все это можно.

Часть 0.4 Контейнеры и образы (images)

Докер образ (image) — это некоторый набор слоёв. Каждый слой — результат работы команды в Dockerfile. Грубо говоря образ — это шаблон на основе которого вы будете запускать контейнеры. Все что запускается на основе этого образа есть контейнер, или инстанс. т.е. с одного образа можно запустить несколько одинаковых копий этого образа — контейнеров. Причем потом, после каких-то манипуляций, из этого контейнера можно создать шаблон — новый образ. Хранится все это безобразие в /var/lib/docker.
документация.

Список образов в вашей системе можно глянуть командой:

Часть 0.5 Как именовать контейнеры и образы (images)?

У образа существует 3 поля, имеющих отношения к именованию:

1) Репозиторий
2) Тег
3) Image ID

Репозиторий — реальный или нереальный, это то место, откуда или куда ваш образ будет скачан\загружен, или это просто выдуманное имя, если загружать никуда вы его не собираетесь.
Тег — обычно это версия продукта. По идее — это любой набор символов. (из разрешенного списка [a-z0-9.-] итп.) если тега нет, то автоматически используется слово latest. тег ставится через символ: от имени репозитория и подставляется автоматически если его не указать при push\pull.
ImageID — локально генерируемый уникальный ID вашего образа, по которому этим образом можно оперировать.

Таким образом вы или автор контейнера влияете на репозиторий и\или тег, а система локально — на ID. Но, кстати вам никто не мешает переиспользовать любое чужое имя репозитория, другой вопрос что запушить (push, загрузить) в него вы не сможете

1/2/3-blah.blah.blah — имя вашего локального образа, вы его выдумали
projects/my_first_docker — тоже имя вашего локального образа
projects/my_first_docker:latest — то же самое имя, но с тегом. эквивалентно предыдущему.
projects/my_first_docker:1.13.33 — а вот это уже конкретная версия образа в этом репозитории.
projects/my_first_docker:1.13.34
projects/my_first_docker:1.13.35
… итд — все это один и тот же проект, но версии ваших образов будут разными.

wallarm/node — а вот это уже скачанный с публичного докер хаба образ с лучшим WAF от компании Wallarm.
debian:stretch — образ debian, версия образа — stretch (не число, но слово)
centos:7 — аналогично debian.
mongo:3.2 — образ mongodb версии 3.2, скачанный с публичного репозитория
nginx — latest stable nginx — аналогично.

Причем чаще всего на хабе можно увидеть разнообразные версии нужного вам софта. Так например mongo даст вам скачать и 3.2 и 3.4 и 3.6 и даже дев версию. и разные промежуточные. и еще кучу других.

Следует помнить: один и тот же образ может иметь сколько угодно имен репозитория и тегов, но будет иметь одинаковый imageid. При этом, образ не будет удален, пока все теги этого образа не будут удалены. т.е. скачав образ debian, задав ему новый тег вы получите в списке 2 образа с разными именами, но одинаковыми imageid. и удалив debian:stretch, вы просто удалите один из тегов, а сам образ останется жить.

Чтобы задать другое имя для существующего образа используется команда:

Для удаления образа:

А вот контейнеры имеют 2 имени:

1) CONTAINER ID
2) Name

С id — тут то же самое — это уникальное имя конкретного уникального запущенного инстанса образа. проще говоря — уникальное имя запущенного образа. Образ может быть запущен сколько угодно раз и каждая копия получит уникальное имя.

Для удаления контейнера:

Часть 0.6 Ладно, все это чужие контейнеры, а как мне сделать свое, с нуля?

Для создания своих контейнеров существует механизм сборки — docker build. Он использует набор инструкций в Dockerfile для сборки вашего собственного образа. При сборке контейнера внутри используется оболочка sh и ваши команды исполняются в ней.

Следует знать следующее:

Часть 0.7 Напоследок и «Это не докер-вэй»

Докер довольно таки мусорит слоями при билде. Кроме того вы можете оставлять кучу остановленных контейнеров. Удалить все это одной командой

Это не докер-вэй

Докер по задумке виртуализирует именно один процесс (с любым кол-вом потомков). Никто вам не мешает конечно запихнуть в один контейнер и 10 процессов, но тогда пеняйте на себя.
Сделать это можно с помощью, например, supervisor.

Но, скажете вы, как же быть со службами, которые ну всю свою жизнь будут вместе и не должны разделяться? использовать контент, который будут генерировать друг для дргуга?

Для того чтобы сделать это красиво и правильно есть docker-compose — это yaml файл, который описывает N ваших контейнеров и их взаимоотношения. какой контейнер с каким скрестить, какие порты друг для друга открыть, какими данными поделиться.

В случае с compose вам, на самом деле, и управлять своим проектом проще. например, связка nginx+uwsgi+mongo — это 3 контейнера, хотя точно известно, что никто кроме nginx не будет ходить в uwsgi, а кроме uwsgi — никто в mongo. да и жить они будут всегда вместе. (ЭТО ЧАСТНЫЙ СЛУЧАЙ). Вот тут у нас получается следующая ситуация — ваше приложение (api) будет обновляться часто — вы его пишете и пушите каждый день. а, например, релизы nginx или mongodb выходят куда реже — может месяц, может дольше. Так зачем каждый раз билдить этого тяжеловеса, когда изменения то всего происходят в одном месте? Когда придет время обновить nginx, вы просто смените имя тега и всесто ребилда проекта, просто скачается новый контейнер с nginx.

Часть 1: когда уже практика?

На этом этапе можно попробовать потрогать контейнеры и поучить необходимые команды. Я — сторонник вбивания команд из туториалов вручную. Поэтому — только скриншоты.

1. Попробуем скачать дебиан образ

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

2. Глянем, что получилось. В моем случае, я для фильтра использовал слово debian, т.к. иначе вывалилось бы в выводе куча других образов. вам его использовать не обязательно. Ну и как результат — у вас будет 2 одинаковых imageid с разными тегами (первые две у меня).
З.Ы. привет в будущее! для тех, кто доживет до debian10 и будет читать эту статью, у вас будет не такой же результат что и у меня. Надеюсь, понимаете почему.

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

3. Запустим bash-процесс внутри образа debian:stretch. Посмотрите его pid — он равен единице. Т.е. это тот самый главный процесс, вокруг которого мы и пляшем. Обратите внимание — мы не смогли так просто выполнить ps aux — в контейнере нет нужного пакета. поставить его мы можем как и обычно — с помощью apt.

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

4. Выйдем из контейнера (exit | Ctrl+D ) и попробуем запустить баш заново — это в верхней консоли (вы можете открыть другую, я для простоты скриншотов сделал так). В нижнем окне — посмотрим список запущенных контейнеров

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

Вот это да! а куда делся procps? да никуда. его тут нет и не было. когда мы запустили образ заново — то взяли тот самый слепок без установленной программы. а куда делся результат нашей работы? А вон он валяется — в состоянии exited. Как и куча других запущенных мною ранее контейнеров и остановленных впоследствии.
Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

Все это — мусор. Но его еще можно оживить:

1. выходим из контейнера в 1-м терминале
2. во втором терминале копируем ID контейнера, подходящего по timeshtamp как и тот который мы тогда остановили
3. в 1 терминале запускаем этот контейнер командой start. он уходит в background
4. во втором терминале смотрим список запущенных контейнеров — по таймштампу тот что запущен 7 секунд — явно наш.
5. Финт ушами. аттачимся к уже запущенному контейнеру с помощью команды exec и запускаем второй инстанс bash’a.
6. выполняем ps aux — обратите внимание, тот, первый bash, с pid 1 живет. а мы в контейнере теперь управляем им через bash с pid=7. и теперь, если мы выйдем, контейнер будет жить.
Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

Итак:
run — взять образ X и создать контейнер Z с процессом Y
exec — взять контейнер Z и запустить в нем процесс N, при этом процесс Y будет работать как и прежде.

1) Контейнер может жить как в background, так и в foreground, лишь бы был жив процесс, который мы виртуализируем.
2) контейнер — это развернутый из образа инстанс
3) контейнеры можно останавливать и запускать без потери данных (но не стоит, это не докер-вэй)

Часть 2: делаем собственный докер-образ

Учимся использовать dockerfile.
Здесь — два подхода к разработке:

1) взять готовый и подточить под себя
2) сделать самому с нуля

Вариант первый — когда вы уверены что за вас прекрасно сделали уже всю работу. Например, зачем устанавливать nginx, когда можно взять готовый официальный контейнер с nginx. Особенно это касается тех систем, которые не ставятся в одну команду или которые например в debian имеют устаревшие версии, а на докер хабе их билдят более свежие стабильные. Тем более там уже сделана автосборка — свежие версии там прилетают довольно быстро.

Вариант второй — вы параноик или вам не нравится подход автора образа (например, официального не нашлось, а есть только на хабе васи пупкина). Никто не мешает посмотреть как сделал это василий, а потом пойти и сделать самому. Ну или в случае если вы просто пишете свою логику, которой точно нигде нет, как например докер образ для билда ваших deb-пакетов в jenkins. А ведь это очень удобно!

Dockerfile это файл с набором инструкций, которые будут совершены в чистом контейнере указанного вами образа, а на выходе вы получите свой образ.

Самое главное что вам нужно указать — это директивы FROM и CMD (в принципе не обязательно). Приведу пример такого файла:

Что такое докер и зачем он нужен. Смотреть фото Что такое докер и зачем он нужен. Смотреть картинку Что такое докер и зачем он нужен. Картинка про Что такое докер и зачем он нужен. Фото Что такое докер и зачем он нужен

FROM — какой образ взять за основу.
MAINTAINER — автор данной разработки (кого пинать за работу этого, нового образа)
RUN — команда, исполняемая внутри контейнера, на основании которой будет получен новый образ. Обратите внимание — обычные bash-переносы и && — делает код читаемым и красивым.
Вы также можете писать хоть 10 RUN — команд (но каждая с новой строки), в которых описывать свою логику.
EXPOSE — какие порты, по какому протоколу будут доступны снаружи контейнера при использовании docker-compose. Тут важно помнимать, что это не значит что они будут доступны извне сразу. т.е. имеется ввиду, что пока вы при запуске этого образа не укажете мапинг портов хост: контейнер, никак внутрь попасть не получится. поэтому нужно знать какие порты у вас на каком этапе прописаны:

И только так — получается, обращаясь на хост по 80 порту вы мапитесь в контейнер на 80 порт. при запуске контейнера этот порт был открыт, а внутри контейнера приложение слушает 80 порт. и так, вы с 80 порта хоста попадете на 80 порт приложения. Естественно порты можно делать любыми. Так, можно запустить множество контейнеров, внутри которых nginx’ы слушают 80-й порт, а мапинг снаружи сделать такой: 8000:80, 8001:80, 8002:80… ну итд, идея понятна. таким образом можно сделать 1 образ с одним конфигом, а запустить его паралельно и независимо множество раз.

CMD — и вот это самое ключевое место. Это та команда, которая будет выполняться при запуске контейнера и работать все это время. Помните да? пока работает процесс, живет контейнер. Здесь подход такой же как в systemd — процесс не должен уходить в background — это незачем, процесс то всего один внутри этого контейнера. Отсюда кстати и разные подходы логирования. например можно оставлять вывод в STDOUT, а можно в логи. Главное, чтобы процесс (главный процесс) после запуска оставался жить. а форков-тредов может быть сколько душе угодно.
Кроме CMD есть еще один вид шаманства — ENTRYPOINT. это обычно shell скрипт, которому в качестве аргумента передается значение CMD.

Нужно запомнить следующие вещи:

1) итоговая команда запуска процесса в контейнере = сумма ENTRYPOINT + CMD.
2) вы можете писать в докер файле любой вариант сочетания entrypoint и cmd — оставлять или то или другое, или оба сразу.

Зачем нужна такая сложность? Правильные пацаны пишут entrypoint для раскрытия всего многообразия возможностей. Если вы пишете образ чисто под себя, можно оставить чисто только один CMD и не писать ENTRYPOINT вообще.

Это примитивный пример что можно сделать, манипулируя вводами. Рассмотреть можно десятки сценариев различного использования комбинаций ENTRYPOINT+CMD. Просто помните, что можно предусмотреть несколько различных видов запуска вашего контейнера у конечного пользователя, который не имеет досупа к вашему dockerfile.

Помимо указанных мною команд, существуют и многие другие, например ADD, COPY — позволяет положить набор данных внутрь контейнера, причем если ADD в качестве источника указать архив, она распакует и положит содержимое в указанное место. удобно для редко изменяемого набора файлов.

Порядок в Dockerfile важен! (с точки зрения оптимизации)
При внесении изменений в Dockerfile и последующий ребилд образа затрагивает тот набор команд, начиная с которого происходит изменение.
Пример:

Внося изменения хоть в один символ конфига вы будете вызвать снова и снова каждый раз установку пака из 100500 программ. а вот если эти строчки расположить в обратном порядке, то билд будет происходить почти мгновенно — т.к. слой с этими программами уже существует.

Часть 3: связь ФС контейнера с хостом

Теперь давайте рассмотрим способ доступности данных с хостовой ос из контейнера. Причин этого может быть несколько: передача файлов, конфигурации, или просто сохранение обработанных данных на диск. Как я уже упоминал ранее данные не пропадают просто так если выключить контейнер, но они и остаются в этом контейнере. вытащить потом их — это ненужная и глупая задача. Докер-вэй — монтирование хостового каталога\файла внутрь контейнера. А если проще — мапинг папки\файла снаружи на папку\файл внутри. поскольку это монтирование, то изменение с одной стороны всегда будет видно и с другой. Таким образом, внося изменение в конфиг с хостовой ос — вы можете заставить сервис внутри контейнера работать по-другому. И наоборот — для сохранения базы данных на хосте в одном, строго определенном, удобном для вас месте. Или логов.

В этом месте позволю себе дать вам еще один линк на полезный ман, а именно на статью-сборник команд по докеру с кратким пояснением.Тыц

В отдельных случаях проще передавать переменные сред окружения, чем конфиги. и докер позволяет это делать, как зашитыми для билда в Dockerfile (ENV key=value), так и через ключ при запуске контейнера, так и через отдельный файл, если таких переменных много.

Часть 4: Удобный запускатор ваших сервисов

Когда вы уже набилдили себе парочку контейнеров, возникает вопрос, как же их автоматически запускать, не прикладывая к этому усилий? ответ прост — через systemd!

Например, создайте файл:

и занесите туда строки:

на что здесь следует обратить внимание:

Вот и пожалуйста — управляем вашей службой как обычным systemd демоном, а journalctl — смотрим stdout вашего демона.

Часть 5: приблизимся к реальности. Построим нашу инфраструктуру

Т.е. будет 3 контейнера, первый будет ставить задачи в очередь, последний считывать. Все это будет управляться через systemd.

sender.py будет ставить каждые 5 секунд в очередь рандомное число от 1 до 7, а воркер (receiver.py) будет считывать это число и имитировать работу — методом простоя кол-ва секунд равное полученному числу.

Мы будем пытаться сделать наши микросервисы так, как это делают правильные пацаны — внутри контейнера код сервиса, а конфиги и логи — снаружи. Это позволит нам поменять адреса очереди, логин, пароль итд без нового билда контейнера. Просто поправить файлик и перезапустить контейнер, вот и все дела. Таким образом нам понядобится директория в /etc и в /var/log, куда мы будем мапить логи и конфиги, соответственно. Вообще такой подход удобен. зайдя на любой сервер с докером, где могут сосуществовать рядом один или несколько микросервисов, вы всегда знате где искать конфиги или логи. А главное, у вас на сервере будет полная чистота. ssh да docker, чего еще надо? (ну, много чего, понятно, например службу мониторинга или puppet, но мы уже избавляемся от кучи всего сервисо-зависимого. А главное — сервис уже не зависит от хостовой ОС. Имейте весь парк серверов на дебиане, а внутри контейнера — все что угодно. Да, эти же аргументы приводят и к виртуализации, но тут история куда легковеснее. ведь мы тащим по сервакам инструмент, а не целую виртуализированную ОС)

1. RabbitMQ
RabbitMQ — диспетчер обмена сообщениями между приложениями. в нашем случае будет использована примитивная очередь. в эту очередь будет помещаться задание и приниматься воркером. Конфиги настройки очереди мы захардкодим внутрь контейнера. Всего в папке rabbitmq у нас будет 3 файла — Dockerfile и 2 файла с конфигами. Их содержимое — в спойлерах под листингом. Настройка очереди, пользователя, прав доступа — в json файле definitions.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *