[Перевод] 10 мифов о Docker, которые пугают разработчиков


31161d6302104e89a0f3340eb275b4ee.jpg

Источник: 'Nova typis transacta navigatio' (Linz: s.n., 1621), p.12 (British Library, G.7237).


Часто во время разговоров о Docker я слышу мнения, с которыми не совсем согласен.


«Docker по своей сути предназначен для крупных компаний»

«под OSx у него экспериментальная поддержка, под Windows работает еле-еле»

«Я не уверен, что смогу быстро развернуть его локально»

… и еще много всякого.

В этих утверждениях есть доля истины (см. ниже мифы 3 и 5), но она мала, и по большей части реальная картина получается искаженной.


А есть еще и наполненные жаргоном статьи о том, как при использовании немалого количества фреймворков обрабатывать 10к миллионов запросов в секунду. И это с помощью всего лишь 30к контейнеров при автоматизации 5к микросервисов, размещенных на шести сотнях облачных виртуальных машин…


Что ж, нетрудно догадаться, почему Docker окружен таким количеством мифов.


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


Давайте поговорим о самых распространенных мифах — тех, с которыми я сталкивался и в которые верил, — и попробуем найти в них истину, а также решения, если таковые имеются.


Миф № 10: С Docker я не смогу заниматься разработкой…


потому что я не могу редактировать Dockerfile


Для разработки мне нужны специальные инструменты и настройки окружения. При этом мне вполне справедливо указали, что редактировать используемый в промышленной эксплуатации Dockerfile нельзя.


Боевой Docker-образ должен быть сконфигурирован только для нужд промышленной эксплуатации и не более.


Как же быть? Если я не могу добавить в Dockerfile мои инструменты и настройки, как мне тогда вообще разрабатывать в Docker?


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


Решение


Вместо копирования Dockerfile, которое может привести к дополнительным трудностям, лучше использовать функциональность Docker по созданию одних образов на основе других.


Я и так создаю production-образ со своим приложением на основе другого образа (что-то типа «node:6»). Так почему бы мне не сделать «dev.dockerfile», который будет создавать нужный образ на его основе?


Dockerfile
FROM node:6

# ... production configuration

Production Build
$ docker build -t myapp .

dev.dockerfile
FROM myapp

# ... development configuration

Development Build
$ docker build -t myapp:dev -f dev.dockerfile .

Теперь я могу модифицировать dev.dockerfile по своему усмотрению, зная, что в нем используется точно такая же конфигурация, как и в production-образе.


Хотите увидеть, как это делается?


Посмотрите эпизод Creating a Development Container, который является частью Guide to Building Node.js Apps in Docker.


Миф № 9: Я ничего не вижу в этом контейнере


потому что я вообще не могу посмотреть внутрь контейнера!


Docker — это виртуализация приложений (контейнеризация), здесь нет полноценных виртуальных машин.


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


Мне нужны логи (помимо консольного вывода моего приложения), отладочные сообщения и общая уверенность в том, что все изменения образа отработали корректно.


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


Решение


Хотя Docker-контейнер и не является полноценной виртуальной машиной, под его капотом работает дистрибутив Linux.


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


В общем случае есть два способа это сделать.


Способ № 1: Подключиться к командной оболочке работающего контейнера

Если контейнер уже запущен, для получения полного доступа к нему я могу выполнить команду «docker exec».


$ docker exec -it mycontainer /bin/sh

Это дает доступ к содержимому контейнера, аналогичный тому, что я получаю при входе в систему под управлением обычного дистрибутива Linux.


Способ № 2: Запустить оболочку в качестве команды контейнера

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


$ docker run -it myapp /bin/sh

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


Хотите увидеть, как это работает?


Посмотрите эпизоды из Guide to Learning Docker и Guide to Building Node.js Apps in Docker.


  • Docker Exec Commands in a Container
  • Start an App w/ a Debugger Attached

Миф № 8: Мне придется писать код внутри Docker-контейнера


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


Когда я в первый раз увидел Docker-контейнер, в котором выполнялся мой Node.js-код, меня очень заинтересовали и обрадовали его возможности.


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


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


Может быть, нужно подключаться к командной оболочке контейнера и кодить в vim? Возможно, при этом придется использовать не ту версию, которая мне нужна.


Допустим, это работает. А если мне нужна IDE или редактор получше?


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


Решение


В контейнерах Docker с помощью опции «volume mount» можно монтировать директории из хост-системы.


$ docker run -v /dev/my-app:/var/app myapp

С этой командой »/var/app» будет указывать на локальную директорию »/dev/my-app». Изменения, внесенные на хост системе в »/dev/my-app»(конечно же, с помощью моего любимого редактора), будут сразу видны в контейнере.


Хотите увидеть, как это работает?


Посмотрите эпизод editing code in a container, который является частью Guide to Building Node.js Apps in Docker.


Миф № 7: Мне придется использовать консольный отладчик…


а я хочу тот, который есть в моей IDE


Мы уже можем редактировать код внутри контейнера и подключаться к его командной оболочке. До отладки остался один шаг.


Я должен запускать отладчик внутри контейнера, так?


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


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


Решение


Короткий ответ: «удаленная отладка».


Развернутый ответ очень сильно зависит от языка и рабочего окружения.


С Node.js, например, я могу использовать удаленную отладку по TCP/IP (порт 5858). Чтобы настроить отладку кода внутри Docker-контейнера, мне нужно открыть соответствующий порт в образе, создаваемом с помощью «dev.dockerfile».


dev.dockerfile
# ...

EXPOSE 5858

# ...

Теперь я могу подключиться к командной оболочке контейнера и запустить сервис отладки Node.js, а затем использовать его с моим любимым отладчиком.


Хотите увидеть отладку находящегося в контейнере Node.js-кода в Visual Studio?


Посмотрите эпизод debugging in a container with Visual Studio Code, который является частью Guide to Building Node.js apps in Docker.


Миф № 6: Мне придется каждый раз запускать «docker run»


и я не смогу запомнить все опции «docker run»…


Без сомнения, у Docker огромное количество опций командной строки. Листание его справки напоминает чтение ветхого тома по мифологии исчезнувшей цивилизации.


Когда наступает время запустить (run) контейнер, я, что не удивительно, частенько путаюсь и даже начинаю злиться, поскольку с первого раза не могу подобрать нужные опции.


Более того, каждый запуск «docker run» создает из образа новый экземпляр контейнера.


Это замечательно, если мне нужен новый контейнер.


Но когда я захочу запустить ранее созданный контейнер, результат выполнения «docker run» мне совсем не понравится.


Решение


Нет нужды выполнять «docker run» каждый раз, когда нужен контейнер.


Вместо этого контейнеры можно останавливать (stop) и запускать (start).


Этим также достигается сохранение состояния контейнера между запусками. Если в нем были изменены какие-то файлы, эти изменения сохранятся после остановки и повторного запуска.


Хотите увидеть, как это работает?


На WatchMeCode есть много эпизодов Guide to Learning Docker и Guide to Building Node.js Apps in Docker, в которых используется эта техника.


Но если идея для вас в новинку, рекомендую посмотреть basic image and container management, в котором рассказывается об остановке и запуске одного экземпляра контейнера.


Миф № 5: Docker под macOS и Windows толком не работает…


а я как раз использую Mac / Windows


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


В прошлом Docker под Mac и Windows требовал использования полноценной виртуальной машины с утилитой «docker-machine» и дополнительным программным обеспечением для обмена данными с виртуальным окружением.


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


Решение


К счастью, разработчики Docker прекрасно понимают необходимость поддержки не только Linux в качестве базовой ОС.


Во второй половине 2016 года были выпущены официальные релизы Docker для Mac и Windows.


Теперь установка Docker на эти платформы не составляет труда. Регулярно выпускаются обновления, а функциональность находится практически на уровне версии под Linux, и я не помню, когда в последний раз мне нужна была опция, недоступная в Docker под Mac или Windows.


Хотите установить Docker на Mac или Windows?


На WatchMeCode можно найти бесплатные эпизоды по установке на обе платформы (а также на Ubuntu Linux!)


  • Installing Docker for Mac
  • Installing Docker for Windows
  • Installing Docker on Ubuntu Linux

Миф № 4: С Docker можно работать только в командной строке


а мне удобнее GUI


Поскольку Docker родом из мира Linux, не удивительно, что командная строка — это основной его интерфейс.


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


Решение


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


В Docker для Mac и Windows есть базовые средства интеграции с Kitematic, например, GUI для управления образами и контейнерами на локальной машине.


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


Хотите увидеть Kitematic в действии?


Посмотрите эпизод о Kitematic в Guide to Learning Docker.


Миф № 3: Я не могу развернуть в контейнере базу данных.


Будут проблемы с масштабированием… и я потеряю свои данные!


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


Более того, системы управления базами данных имеют свои особенности при масштабировании: вертикально (более мощный сервер) и горизонтально (больше серверов).


Docker, похоже, специализируется на горизонтальном масштабировании: когда нужно увеличить мощность, создается больше контейнеров. С другой стороны, большинство СУБД требуют специфических настроек при масштабировании.


Да, все так. Боевую базу в Docker лучше не разворачивать.


Тем не менее мой первый удачный опыт работы с Docker был связан именно с базой данных.


Oracle, если быть точным.


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


А через 30 минут после того, как я узнал, что существует образ Oracle XE для Docker, у меня была рабочая база.


В моем окружении для разработки.


Решение


Docker может быть не лучшим решением для размещения боевой БД, но для разработчиков он может творить чудеса.


У меня работали MongoDB, MySQL, Oracle, Redis, а также другие системы, требующие сохранения состояния между перезапусками, и меня все устраивало.


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


Аналогично истории с редактированием кода: подключение томов предоставляет удобный инструмент для хранения данных на локальной машине и их использования в контейнере.


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


Миф № 2: Я не смогу использовать Docker в своем проекте


потому что Docker — это «все или ничего»


Когда я впервые увидел Docker, то подумал: или разрабатывать, дебажить, деплоить и «девопсить» все с Docker (и двумя сотнями дополнительных инструментов и фреймворков, чтобы оно все работало автоматически), или не использовать Docker совсем.


Случай с Oracle XE доказал обратное.


Любой инструмент или технологию, на первый взгляд требующие подхода «все или ничего», не будет лишним переоценить. В крайне редких случаях «все или ничего» на самом деле оказывается правдой. А если все-таки оказывается, возможно, вкладываться в такой продукт не стоит.


Решение


Docker, как и большинство инструментов разработчика, можно начинать использовать постепенно.


Начните с малого.


Запустите в контейнере базу данных разработки.


Затем создайте в контейнере библиотеку и выясните, как она работает.


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


Переходите к более серьезным проектам, уже вовлекающим небольшую команду специалистов.


Не нужно бросаться в омут с головой.


Миф № 1: Я не смогу получить пользу от Docker… Вообще…


потому что Docker — это «enterprise» и «devops»


Этот был самый серьезный ментальный барьер, который мне нужно было преодолеть после знакомства с Docker.


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


И совсем не удивительно, что я так думал.


В блогах и на конференциях то и дело возникает шумиха типа «Такая-то корпорация автоматизировала 10 000 000 микросервисов с помощью Docker и Kubernetes» и т. д. и т. п.


Docker может быть отличным инструментом для «enterprise» и «devops», но и обычный разработчик — как вы и я — может использовать его преимущества.


Решение


Попробуйте Docker.


Опять же, начните с малого.


У меня запущена одна виртуальная машина с 12 Гб ОЗУ, на которой размещены 3 веб-проекта для одного из клиентов. По нынешним меркам это весьма скромный сервер. Но я рассматриваю Docker — чистый Docker сам по себе — как способ использовать этот сервер более эффективно.


У меня есть второй клиент, у которого частично заняты пять разработчиков (все вместе не отрабатывающие 40 часов в неделю). Эта небольшая команда также использует Docker для автоматизации процессов сборки и развертывания.


В настоящее время большинство своих open source-библиотек я пишу на Node.js под Docker.


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


Помните:


Не обращайте внимания на шумиху и не верьте мифам


Docker-мифология появилась благодаря веским причинам. Но она не помогает разработчикам.


Если вы, прочитав эту статью, все еще сомневаетесь, прошу вас выделить немного времени и попробовать пересмотреть свое отношение к Docker.


Если у вас есть вопросы по поводу того, каким образом разработчик может эффективно использовать Docker, свяжитесь со мной. Буду рад постараться вам помочь.


При желании изучить основы Docker и методы разработки приложений с его использованием можно начать с просмотра Guide to Learning Docker (с нуля) и Guide to Building Node.js Apps in Docker на WatchMeCode.

Комментарии (5)

  • 14 марта 2017 в 08:51 (комментарий был изменён)

    0

    Шумиха, мифы — слова из журнала домохозяйек о том как не боятся и начать вязать.
    Разработчик зайдет, прочтет документацию и сам для себя решит — подходит для него инструмент или нет. А заголовок я бы поменял на »10 советов при работе с Docker»
    • 14 марта 2017 в 09:22

      +1

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

  • 14 марта 2017 в 09:31

    +1

    Так почему бы мне не сделать «dev.dockerfile», который будет создавать нужный образ на его основе

    Потому что это прямо противоречит смыслу создания докер-образов.
    Теперь я могу модифицировать dev.dockerfile по своему усмотрению, зная, что в нем используется точно такая же конфигурация, как и в production-образе.

    Зачем тогда это всё, если у вас дев и прод одинаковые?

    Какие-то надуманные проблемы, с решением копипастой из документации.

  • 14 марта 2017 в 10:01

    +3

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


    • права в томах, примонтированных на хост — по умолчанию приложения в докере работают от рута либо от чётко заданного пользователя, заставить чтобы запускались по docker run и ко от текущего пользователя хоста весьма нетривиальная задача, особенно через docker-compose, а без этого или контейнер валится с permission denied, либо обнаруживаешь, что не можешь в IDE файл посмотреть или git checkout сделать
    • проброс текущего окружения в контейнер — прежде всего DNS и файлов в ~/.ssh
    • использование окружения контейнера на хосте — прежде всего DNS и изменяющихся файлов типа логов
    • проблемы с томами, которые шарятся между контейнерами, например docroot между контейнерами nginx и php-fpm — тома нужны для шаринга, но их природа (заполнение из «ведущего» контейнера только при первичном создании) мешает активной разработке, если файлы в томах создаются/изменяются/удаляются с хоста
    • очень слабый контроль над созданием образа (docker build) — прежде всего не примонтировать тома с хоста во время сборки
    • конфликты портов на хосте

    Ну, а самое интересное начинается когда худо-бедно порешаешь это всё, запустишь приложение локально в десятке контейнеров, отладишь (постоянно чертыхаясь, что то не удалил том после исправления одной опечатки, то удалил на автомате то, что не нужно, и теперь жди когда «кэши прогреются») и тебе говорят «молодец, деплой на продакшен», на котором докером и не пахнет. Вот тут и начинаешь понимать, что основные прелести докера раскрываются только в относительно крупных компаниях, которые могут себе позволить CD на продакшен (читай — могут себе позволить специалиста, основной задачей которого будет автоматизация CD и прочий devops), неважно либо в виде докера на продакшене (за года полтора работі с ним так и не решил даже для себя, готов ли он к продакшену в условиях где почти все сервисы критичны для работы, но при этом не дублируются), либо в виде какой-то иной трансляции части разработческого окружения на него.

  • 14 марта 2017 в 10:47

    0

    Для тех, кто хочет контейнеризацию без лишних напрягов для себя или в небольшую команду, рекомендую ознакомиться с LXC. Это _не кроссплатформенное_ решение (OSX/Windows отпадают), но с контейнерами LXC можно просто работать как с обычными виртуальными машинами. Для dev/staging окружения вообще идеально, на продакшн всё же приятнее иметь низкоуровневую виртуализацию, но можно и там с контейнерами работать.

    А так да, докер без DevOps-инженеров — это боль и страдания.

© Habrahabr.ru