Что это такое.
Docker очень похож на очередную виртуальную машину: можно взять образ Ubuntu с каким-нибудь hello-world внутри, набрать docker run ubuntu hello-world, и «привет-мир» запустится, искренне полагая, что живёт в убунте, а вокруг — никого.
Но на самом деле Docker — не виртуальная машина, не менеджер виртуальных машин, и даже не гипервизор. Docker — это платформа для создания, запуска и управления контейнерами, которые, хотя и выглядят как маленькие виртуальные машинки, на самом деле работают как высокий забор с колючей проволокой. Приложению наружу не выйти, но и незваных гостей оттуда не дождёшься — то, что нужно для продакшен серверов. Из-за того, что контейнерам не нужно заниматься эмуляцией железа и носить в себе гостевую OS, они работают со скоростью, которая виртуальным машинам и не снилась.
Как его можно использовать.
- Docker — прекрасная песочница. Если я соберусь выучить Erlang, то его не обязательно устанавливать на живую машину. Можно запустить контейнер, установить всё там, порезвиться, и через неделю выбросить контейнер целиком.
- Это удобный способ доставки приложений на сервера. У приложений обычно есть зависимости, которые приходится настраивать от сервера к серверу. Можно установить и приложение, и его зависимости в контейнер, и доставлять всё сразу.
- Это способ решать конфликты зависимостей приложений на одном сервере. Например, кому-то нужен Node.js 4, а кому-то — Node.js 6. Проблему, конечно, можно решить и так, но если все сидят по контейнерам, то её нет в принципе.
- С Docker приятно обновлять приложения (и зависимости). Нужно просто доставить новый контейнер.
- С ним можно экономить. Сервер с моим блогом редко использует больше 5% CPU. Но я плачу за все 100%. Если положить блог в контейнер и сказать тому, что больше 5% CPU использовать нельзя, то остальные 95% можно забить другими контейнерами. 19 других блогов, например. У всех свои квоты на ресурсы, и никто никому не мешает. Сервер используется на полную, и нет нужды заводить дополнительные машины.
Примеры.
0. Установка.
Чтобы запускать примеры на Docker, его сначала нужно установить. Docker ставится на Mac/Windows/Linux (нативно — только на Linux). Как это сделать — написано в официальной документации.
1. Простой Hello world
docker run hello-world
Команда запустит демо-контейнер с названием hello-world, в котором установлено /hello-приложение на автозапуске. Так как hello-world контейнера на локальной машине у меня не было, то Docker сначала его скачал с официального репозитория — аналога github, но для контейнеров.
2. Продвинутый Hello world
docker run ubuntu echo "hello world!"
Docker запустит контейнер ubuntu (в котором действительно ubuntu), а в ней — echo «hello world». Как только echo завершится, контейнер тоже выключится.
3. Запустить bash в Debian-контейнере и подключиться к нему терминалом:
docker run -ti debian /bin/bash
-ti параметры буквально значат tty interactive — интерактивный терминал. Внутри действительно Debian:
4. Запустить контейнер с Nginx и разрешить ему общаться со вселенной по 80-му порту:
docker run -d -p80:80 nginx
-d запустит контейнер в бэкграунде, а -p80:80 привяжет восьмидесятый порт контейнера к такому же порту хоста. Если набрать в браузере http://127.0.0.1, то контейнерный nginx ответит своей кривой ухмылкой:
Но на 127.0.0.1 он ответит только на Linux. Mac и Windows нативно Docker пока не поддерживают, поэтому под капотом он работает в виртуальной машине с linux, у которой свой IP и обращаться к nginx нужно по нему. В зависимости от того, как Docker устанавливался, IP можно узнать выполнив docker-machine ip , boot2docker ip , или даже ifconfig . В моём случае это 192.168.99.1
Когда контейнер с nginx станет не нужен, его хорошо бы выключить:
5. Создать свой образ.
У Docker-образов есть одна приятная особенность. Они — только для чтения. То есть можно зайти в ubuntu, запустить там rm -rf / (на самом деле rm -rf --no-preserve-root / ), посмотреть, как команда кромсает систему, выйти, запустить ubuntu снова — и она будет как новенькая.
На самом деле образ состоит из стопки read-only слоёв, и когда мы его запускаем, Docker просто добавляет сверху слой для записи (тем самым превращая образ в контейнер), и все непотребства творятся в нём. Выглядит это примерно так:
Но иногда изменения сохранить нужно. Для этого измененный верхний read-write слой можно найти ( docker ps -a ) и сохранить в новый образ ( docker commit <ID> name:tag ):
Можно собрать новый контейнер и из Dockerfile, но это повод для отдельной статьи.
Не заключение.
Docker — большой. Некоторые его части я затронул, какие-то = сильно упростил, но ещё больше даже не упомянул. Но, при всей его масштабности, Docker — простой. Базовый набор знаний можно легко получить за вечер. И чтобы начать им пользоваться, не обязательно писать огромные распределенные приложения для банков. В качестве домашней песочницы он тоже работает на ура.
При всей простоте, Docker добавляет уровень сложности к администрированию. Всё выглядит элементарно на одно-двухконтейнерных примерах. На практике увязать надо поболее. Простота конечного результата связана с дополнительной работой на этапе проектирования взаимосвязей всех контейнеров. Как-то незаметно развитие технологий ведёт к тому, что для размещения 2-3 сайтов на VPS надо спроектировать микроЦОД 🙂
Да, тут спорить не буду. И, как оказалось, сложности идут по всем фронтам. Сложно разделить приложение на куски, чтобы раскидать по контейнерам. Сложно эти контейнеры массово поднять и настроить. Сложно убедиться, что они всё еще вменяемо живые. Для всего есть инструменты, но они мелкие, их нужно учить, и тоже как-то конфигурировать.
Видимо, задачи, ради которых идут на такие жертвы, монолитной архитектурой больше не решить 🙂