Узнайте, как Docker меняет наш код

С тех пор, как Docker был запущен в начале 2013 года, у него возникли отношения любви-ненависти с программистами и системными администраторами. Хотя некоторые «опытные» разработчики, о которых я говорил, сильно не любят контейнеризацию в целом (подробнее об этом позже), есть причина, по которой многие крупные компании, включая eBay, Twitter, Spotify и Lyft, по сообщениям, приняли Docker в свои производственная среда.

Так что именно делает Докер?

Вы когда-нибудь работали с VMware, VirtualBox, Parallels или любым другим программным обеспечением для виртуализации? Что ж, Docker почти такой же (хотя и без причудливого графического интерфейса), где он создает виртуальную машину с выбранной вами операционной системой, объединенной только с вашим веб-приложением и его зависимостями.

Но разве виртуальные машины не медленные?

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

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

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

Если вам нужно запустить систему, в которой вам абсолютно необходима полная изоляция с гарантированными ресурсами (например, игровой сервер), то, вероятно, вам подойдет виртуальная машина на базе KVM или OpenVZ. Но если вы просто хотите изолировать отдельные процессы друг от друга и запускать их группу на хосте разумного размера без ущерба для банка, тогда Docker для вас.

Если вы хотите узнать больше об аспектах производительности при запуске контейнерной системы, вот отличный исследовательский документ от IBM: Обновленное сравнение производительности виртуальных машин и контейнеров Linux (2014 г., Фелтер и др.) это делает хорошее сравнение виртуальных машин и контейнеров.

Разве я не могу просто загрузить свое приложение прямо на несколько облачных серверов?

Что ж, вы можете, если вас не волнуют такие вещи, как инфраструктура, согласованность среды, масштабируемость или доступность.

Представьте на мгновение следующий сценарий: вы управляете дюжиной служб Java и развертываете их на отдельных серверах под управлением Ubuntu с Java 8 для сред разработки, контроля качества, промежуточной и производственной среды. Даже если вы не сделали свои приложения высокодоступными, вам необходимо управлять минимум 48 серверами (12 служб x 4 среды).

А теперь представьте, что ваша команда возглавляет политику изменения организации, требующую от вас обновления среды выполнения до Java 11. Это 48 серверов, на которые вам нужно войти и обновить вручную. Даже с использованием таких инструментов, как Chef или Puppet, это большая работа.

Вот более простое решение

Docker позволяет создать моментальный снимок необходимой операционной системы и установить на нее только необходимые зависимости. Одна сторона этого, которая мне нравится, заключается в том, что вы можете справиться со всеми "раздутыми программами" или с их отсутствием. Вы можете использовать минимальную установку Linux (я рекомендую Alpine Linux, хотя для целей этой статьи я продолжу с Ubuntu) и установить на нее только Java 8.

Когда придет время обновлять, просто отредактируйте Dockerfile своего Java-образа, чтобы использовать Java 11, соберите и отправьте в репозиторий контейнеров (например, Docker Hub или Amazon ECR), после чего все, что вам нужно сделать, это изменить тег базового образа контейнеров приложений. чтобы создать ссылку на новый снимок и повторно развернуть его.

Ниже приведен образец контейнера Docker, созданный на основе минимальной операционной системы Ubuntu 18.04.

Я бы создал и отправил этот образ в учетную запись Docker Hub damian с помощью тега oracle-jdk-ubuntu-18.04:1.8.0_191, а затем использовал бы его для создания еще одного контейнера для запуска моих служб:

# Instructs Docker to build this container on top of this snapshot
FROM damian/oracle-jdk-ubuntu-18.04:1.8.0_191
# Copys the application JAR to the container
COPY build/hello-world.jar hello-world.jar
# Executes this command when the container starts
CMD java -jar hello-world.jar

Теперь, если мне нужно обновить свои службы до Java 11, все, что мне нужно сделать, это опубликовать новую версию моего снимка состояния Java с установленной совместимой JRE и обновить тег в объявлении FROM в контейнере службы, указав контейнеру использовать новый базовый образ. Вуаля, при следующем развертывании у вас будут все ваши сервисы в актуальном состоянии с последними обновлениями Ubuntu и Java.

Но как это поможет мне во время разработки?

Хороший вопрос.

Недавно я начал использовать Docker в модульных тестах. Представьте, что у вас есть тысячи тестовых примеров (и если вы это сделаете, поверьте мне, я чувствую вашу боль), которые подключаются к базе данных, где каждый тестовый класс нуждается в свежей копии базы данных и чьи отдельные тестовые примеры будут выполнять операции CRUD с данные. Обычно можно сбрасывать базу данных после каждого теста, используя что-то вроде Flyway от Redgate, но это означает, что ваши тесты должны выполняться последовательно и занимать много времени (я видел комплекты модульных тестов, которые занимали до 20 минут для завершения из-за этого).

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

Еще одно место, где я использую Docker, - это кодирование на Golang (чьи конфигурации и управление зависимостями я считаю беспорядочными) - вместо того, чтобы напрямую устанавливать Go на мою машину разработки, я следую методу, аналогичному методу Константина Даруткина, поддерживая файл Dockerfile. с моей установкой Go + зависимостями, настроенными на перезагрузку моего проекта в реальном времени, когда я вношу изменения в исходный файл.

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

Подводить итоги…

Если вы - стартап, не определились с тем, что будет работать с вашим новым технологическим стеком, или устоявшийся поставщик услуг, который думает о контейнерных средах Prod и NonProd, но боитесь плыть по «непроверенным» водам (ухмылка), подумайте на мгновение о следующем.

Последовательность

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

Отладка

Вы можете легко изолировать и устранить проблемы со средой в вашей команде, не зная настройки их машин. Хорошим примером этого является случай, когда нам однажды пришлось исправить некоторые проблемы с синхронизацией времени на наших серверах, перейдя с ntpd на Chrony - и все, что мы сделали, это обновили наш базовый образ, и наши разработчики не были в этом мудры.

Автоматизация

Большинство инструментов CI / CD, включая Jenkins, CircleCI, TravisCI и т. Д., Теперь полностью интегрированы с Docker, что упрощает распространение ваших изменений из среды в среду.

Облачная поддержка

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

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

Решение этой чудовищной задачи доступно в самоуправляемых инструментах облачной оркестрации, таких как Docker Swarm и Kubernetes, а также в инструментах, управляемых поставщиками, таких как Elastic Container Service AWS и Google Kubernetes Engine, которые отслеживают и управлять кластеризацией и планированием контейнеров.

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

Подпишитесь на нас в Twitter 🐦 и Facebook 👥 и Instagram 📷 и присоединяйтесь к нашим Facebook и Linkedin Группы 💬 .

Чтобы присоединиться к нашему чату команды Slack в сообществе 🗣️ прочтите наши еженедельные темы о Фавнах 🗞️, и присоединитесь к сообществу 📣 нажмите здесь⬇

Если этот пост был полезен, пожалуйста, несколько раз нажмите кнопку хлопка 👏 ниже, чтобы выразить поддержку автору! ⬇