Как стать автором
Обновить

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

Время на прочтение26 мин
Количество просмотров337K
Всего голосов 108: ↑107 и ↓1+106
Комментарии36

Комментарии 36

Спасибо за статью. Docker как-раз лежал в ящике «изучить обязательно», но руки всё не доходили)
Отличный материал, спасибо за статью!

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

Спасибо большое

Чем больше разбираюсь с Docker тем сильнее начинает казаться, что это просто костыль такой являющийся следствием:
1. Крайне плохой совместимости диструтивов между собой
2. Стремлением бездумно писать софт таская с собой десятки либ разных версий. И очень часто из-за того, чтобы из огромной либы вызывать лишь один метод.

В итоге приложение-уродец без докера ну никак не заработает.

Нормально спроектированному софту никакие докеры не нужны.
докер — не панацея, а подход к проектированию. Никто не говорит, что его нужно использовать везде. Докер подойдет, например, для микросервисной архитектуры.

С другой стороны, уверен, что в гугле тоже не дураки сидят. а они используют докер. и множество-множество других крупных и не очень корпораций. Так может быть это вы не разобрались с чем его готовить?
В сферическом вакууме возможно и не нужны. В реальном мире когда работаешь с кучей проектов со своим уникальным окружением без виртуализации не обойтись. Сначала был Vagrant, теперь Docker. Удобно. Да, на счет продакшена тут уже 50/50. Можно использовать контейнеры, а можно а разворачивать все старым дедовским способом. Но без Docker на стадии разработки уже никак. Типичный недавний пример проект клиента — сервис на Python, сервис на NodeJS, Postgres, Redis (+для отладки почты mail сервер я добавил schickling/mailcatcher). Как с таким проектом вы будете работать? А с Docker достаточно иметь правильно составленные Dockerfile + docker-compose.yml и одна команда docker-compose up (или ручной запуск в любом сочетании). Можно конечно использовать Ansible + VirtualBox, но это уже дело вкуса.
Зачастую тут дело не во вкусе, а в системных ресурсах. Зачем разводить N виртуальных систем, когда можно полностью утилизировать одну-две?
верно. одна система виртуализации и одна система контейнерезации. этого хватит за глаза.
Чем больше разбираюсь с Docker тем сильнее начинает казаться, что это просто костыль такой являющийся следствием:
1. Крайне плохой совместимости диструтивов между собой
2. Стремлением бездумно писать софт таская с собой десятки либ разных версий. И очень часто из-за того, чтобы из огромной либы вызывать лишь один метод.

В итоге приложение-уродец без докера ну никак не заработает.

Нормально спроектированному софту никакие докеры не нужны.


DLL Hell или как там оно называется в Unix — существовал за много десятилетий до Докера.
Докер просто предлагает кардинальный способ решения проблемы и предоставляет для этого универсальный инструмент.

Ну во первых проблема не столько в различных дистрибутивах, а в в их различные поколения. Типичная проблема: в одном приложении библиотека aaa.so требуется версии 1.31 и не выше, а другом приложении так же aaa.so, но не ниже 1.33. И эта проблема возникает на одном и том же дистрибутиве запросто.

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


С Докером мы просто получаем то, что могли бы получить если бы программисты писали код строго по правилам — то есть получаем софт, который смотрит в мир жестко определенным портом и пишет на диск в жестко определенное место. И никому не мешает. Все остальное — сочетать этот софт друг с другом — это уже задача админа.

Собственно в современных средствах написани программ также предпринято попытки создавать программы без Докера и без проблемы с зависимостями. Например Go/golang представляет из себя единственный бинарный файл, который может запускаться на любой системе (разумеется бинарный файл должен соответствовать классу системы 32/64 бита, Linux, FreeBSD, Windows, MacOSX). На конкретный дистрибутив операционной системе Go плевать.

Докер же пытается решить эту проблему более глобально — для любого ПО. Независимо от того, сколько дополнительных файлов нужно этому ПО для работы. Строго говоря, подход Докера соответствует подходу заказчиков — наплевать что там внутри, пусть программисты извращаются как хотят, если им так удобнее, если так лучше для дела. Но это должно работать.
Проблема на 80% является средствием использования разных кривых инструментов. NodeJS яркий пример. Там Hello World без десятка плагинов и тройки оберток сделать практически невозможно. Как следствие любой большой проект превращается к груду трудноподдерживаемого говна.

В итоге поддержка всего этого превращается просто в ад.

Просто скоро мы придем к тому, что появятся обертки над Докером, у которого со временем свои приколы вылезут и с версиями и с еще чем-то там. А первопричина проблем так и останется.
NodeJS яркий пример.

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

Проблема на 80% является средствием использования разных кривых инструментов.


Так уж сложилось, что программистами в этом мире являются и еще другие люди, кроме вас, идеального программиста.

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

А хаять других не помогает — ведь постоянно новые программисты появляются.
Просто скоро мы придем к тому, что появятся обертки над Докером, у которого со временем свои приколы вылезут и с версиями и с еще чем-то там. А первопричина проблем так и останется.


Ну а вы что предлагаете?
Расстреливать за «кривую программу»?

Кто кривизну будет определять?
Не боитесь, что в каких то условиях и ваша программа будет менее прямой, чем у большинства?

Едиобразия в версиях и пакетах можно добиться только если вы являетесь единоличным владельцем кода. У разных команд разработчиков может быть свое мнение какие библиотеки им нужны.


Поэтому либо разносить модули по разным серверам, либо завернуть их в докер на одном хосте и сэкономить на расходах на севера.

У разных команд разработчиков может быть свое мнение какие библиотеки им нужны.


Более того: это могут быть разные языки программирования
В «Часть 0.1 Сравнение с VM» строго говоря все сильно не правда. Докер нельзя назвать средством виртуализации ни в коей мере. Он является оберткой вокруг средств контейнеризации ( cgroups + namespaces ) конкретно linux kernel.
В последнее время MS тоже начал что то подобное впиливать в Windows. Но! Контейнеры для linux и windows не совместимы между собой ни в коей мере ( есть решения, запускающие контейнеры linux в других ОС, но они используют отдельные настоящие виртуальные машины с guest os linux в них ).
Подробнее о различиях виртуализации и контейнеризации можно посмотреть здесь:
www.youtube.com/watch?v=thcE53dogZk&t=1s&list=PLrCZzMib1e9rZohs_FJg8MK52Ey494z40&index=11
Согласен, это вводит в заблуждение. Я пытался более простым язком провести аналогию и видимо допроводился. Попробую поправить. Скорее здесь надо было заменить слово «виртуализации» на слово «изоляция».
Спасибо за статью! Хабр торт
Такой вопрос, можно ли докер контейнеру присваивать несколько IP адресов?
наверное это не совсем то, что вы хотите. вы можете настроить свою сеть для контейнера:
docs.docker.com/engine/userguide/networking

Но в пределах одного хоста, вероятно вы хотели следующее:
docker run -p 172.16.10.20:80:80 -p 192.168.10.20:443:443 .....

Что будет направлять пакеты, приходящие на конкретный адрес и порт хоста внутрь контейнера. А эти адреса уже нужно будет настроить на интерфейсах хоста. В этом случае вам сеть докера трогать не нужно.
Выходные данные не должны сохраняться внутри контейнера (можно, но это не docker-way).

О, а это утверждение я впервые встречаю! Только присматриваюсь к докеру, как раз и думал, что удобно и код проекта внутри контейнера хранить…
код проекта — библиотеки, бинарники — т.е. само рабочее мясо хранится в контейнере. а вот те данные, которые выполучаете на выходе — вот их как раз не нужно хранить внутри.
ну, например, база данных mysql: сам демон живет в контейнере, а база данных — снаружи.

Вы, возможно меня так поняли.
Автор, большое спасибо, пишите еще.
А как сделать такое, например у меня проект на C++;
Компиляция
Развертывание в контейнере
преднастройка (если надо)
Запуск( тесты)
максимально автоматически
возможно я помогу — docs.docker.com/engine/userguide/eng-image/multistage-build/#use-multi-stage-builds

Не так давно добавили multistage build — когда в докерфайл пишется несколько контейнеров, каждый из которых может брать артефакты из предыдущего.

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

Ну и плюс для подобных вещей используют CI инструменты — Jenkins, GitLabCI, и т. д.
jenkins. пишете различные стадии (stage) в jenkinsfile (groovy lang), и с помощью докера и скриптов этот вопрос решается.
и будет это выглядеть так:
git push -> hook -> jenkins master server -> jenkins builder (здесь выполняются ваши операции, билды, тесты, выгрузка в репозиторий..)
>Часть 4: Удобный запускатор ваших сервисов
А вы точно понимаете смысл опции --restart=always?
До сих пор, спустя много времени, не могу согласиться что докер прямо таки незаменимая вещь в разработке. А еще не разу не видел железобетонного примера use-case, когда можно сказать «вот это да! без этого совершенно никак». Такое ощущение, что люди не понимают что делают, а просто гонятся за технологией без причины. Вы знаете, у нас много разработчиков, которые пишут микросервисы. Микросервисов около 30 видов, экземпляров еще больше, и они крутятся, не поверите, просто не железе, даже без виртуализации. Мы научились с этим жить и переход на докер до сих пор не очень понятен. Написаны сборки и деплой, которые собирают сервисы, выкатывают это на stage, prod. Есть мониторинг который следит за жизнью сервисов. Оговорка — микросервисы на golang. Возможно, поэтому не страшно что какая то либа будет отличаться на машине разрабочика и продакшене. Не могу сказать что у нас хайлоад, но 20 тысяч пользователей онлайн набирается. Очевидно, что бы мог нам принести докер тоже понятно: более удобный способ хранения сервисов, их деплой и роллбэк (было бы просто меньше ansible), управление ресурсами (с swarm, nomad, etc), чуть удобней собирать логи. И кажется — это все. При этом добавляется головная боль, когда проявляются особенности докера. У нас часть сборок (composer, npm) делается в докере, поэтому о глюках знаем не по наслышке. А так же особенности работы с файловой системой, прокидывание портов и в целом работа с сетью, авторегистрация. Бывают контейнеры просто зависают и причину выявить проблематично. Поэтому каждый раз, когда читаю восторженную статью про докер для одного-двух микросервисов, хочется задать вопрос — вам шашечки или ехать? Иногда докер дает не так много полезного, а вот принести может много проблем. И все же мы рассматриваем варианты перехода на докер + оркестрацию, во имя удобства деплоя и гибкости управления ресурсами.
За статью спасибо, автор молодец.
Особенность Докера пожалуй в том, что его польза неочевидна, если его не использовать или использовать только для решения каких-то узких задач. Вся красота раскрывается если вам приходится работать с неопределённого размера распределённой командой, которая использует разнообразный зоопарк решений. Попытки автоматизировать это всё с Ansible/Salt/… выльются в кровавые слёзы. Нужно просто разделять назначения инструментов. Ansible — прекрасная вещь, но я точно не захотел бы управлять чем-либо вроде проектов на nodejs с её помощью.
верно, — «Of course, you can do a better job if you have more tools in your toolbox than if you have fewer, but it is much more important to have a handful of tools that you know when not to use, than to know everything about everything and risk using too much solution.» (Kent Beck)

P.S.: автор действительно молодец.
Спасибо за статью, очень интересно.
Я правильно понимаю, что если у меня к примеру есть NodeJS приложение, то я могу его задокерезировать, запустить несколько таких контейнеров и получу возможность распаралеливания обработки запросов по ядрам уже не на уровне приложения а на уровне инфраструктуры? Никаких заморочек с кластеризацией приложения? Подразумевается, что приложения в контейнерах stateless.
И гипотетический кейс: есть к примеру 32 физических сервера. 30 для запуска контейнеров (stateless сервисы), 2 для БД основная и реплика для отказоустойчивости (stateful). Контейнеры что-то делают, взаимодействуют между собой, а потом пишут результат в базу. Это же Docker way? Как в такой инфраструктуре минимизировать администрирование хостовой ОС? Или просто берём Ansible, CoreOS и вперёд?
Посмотрите на Kubernetes + Helm
32 физических сервера. 30 для запуска контейнеров
Вообще, да, почему нет. Но, чтобы не держать все яйца в одной корзине, можно раскидать разных контейнеров по 2-3 на физический сервер, я думаю.
Посмотрите его pid — он равен единице.

Можно проще: echo $$
Но тогда не получится демонстрации с command not found :)


Финт ушами. аттачимся к уже запущенному контейнеру с помощью команды exec

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

docker attach — подключиться к процессу Y контейнера Z.

здесь преследуются разные цели. в случае с attach подключается к существующему процессу, в случае exec — процесс создается рядом. Т.е. например в 99% это шелл для отладки
давно собирался пройтись по такому кейсу и понять чем так хорош докер…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории