[Перевод] Кластер Docker Swarm за 30 секунд
В этом июне в качестве лейтмотива конференции DockerCon мы увидели демо, в котором 3-узловой Swarm-кластер был создан за 30 секунд, используя набор инструментов для кластеризации Swarm, интегрированную в Docker Engine 1.12.
Впечатляет, но, естественно, мне нужно было попробовать сделать это самому, чтобы увидеть своими глазами, если демо остановится.
Создание узлов в вашем Swarm
docker-machine create -d virtualbox node1
docker-machine create -d virtualbox node2
docker-machine create -d virtualbox node3
docker-machine ssh node1 # или 2, или 3
Я нашел самый простой путь, для начала работы со Swarm (Роем) — использовать docker-machine для создания хостов с установленным на них Docker Engine. Я использовал драйвер virtualbox«а, но вы можете использовать любой драйвер, который вы хотите, например, amazonec2.
Инициализация вашего менеджера
docker swarm init --advertise-addr [advertise ip]:2377
Присоедините ваших воркеров (workers)
Скопируйте команду, отображенную для вашего первого узла из ваших работников, чтобы присоединить его к кластеру
docker swarm join --token [token] [manager ip]:[manager port]
Теперь у вас есть Swarm-кластер!
Давайте что-нибудь развернем (deploy)
Чтобы запустить приложение, мы используем служебную команду Docker«а create. С помощью флага --replicas вы можете очень просто масштабировать сервис.
Первоначально, мы хотим создать сеть верхнего уровня (оверлейную сеть), чтобы развернуть наше приложение.
docker network create -d overlay mynetwork
До Docker Engine 1.12 оверлейные сети требовали внешнего хранилища ключ/значение. Но с созданием распределенного хранилища в Docker 1.12 это больше не требуется.
Давайте развернем простое приложение Apache на публичном порту 5001. Я использую специальный образ Apache, найденный мной на DockerHub, который печатает ID контейнера, обслуживающего запрос. Позже это будет использовано для демонстрации балансировки нагрузки.
docker service create --name web --network mynetwork --replicas 3 -p 5001:80 francois/apache-hostname
Вы можете использовать следующие команды, чтобы проверить ваш новый сервис:
docker service ls
docker service tasks web
Сетка маршрутизации
Добавления сетки маршрутизации и децентрализованной архитектуры в Docker 1.12 позволяет любым узлам-работникам в кластере маршрутизировать (направлять) трафик к другим узлам.
В нашем веб-сервисе, выше, мы открыли кластерный (cluster-wide) порт 5001. Вы можете послать запрос на любой узел на порт 5001, и сетка маршрутизации направит запрос на тот узел, который запустил контейнер.
curl [ip]:5001
Балансирование нагрузки
Всегда, когда создается новая служба, виртуальный IP создается вместе с этой службой. IPVS владеет (осуществляет) балансировкой нагрузки, высокопроизводительным уровнем 4 балансирования нагрузки, который встроен в ядро Linux.
Чтобы показать это, запустим curl несколько раз, для демонстрации изменение ID контейнера.
Балансировка нагрузки при помощи Docker 1.12 является контейнер-осведомленной (container-aware). Хост-осведомленная (host-aware) балансировочная система, такая как nginx или haproxy, удаляет или добавляет контейнеры требуемой конфигурации обновления балансирования нагрузки и перезапуска этих сервисов. Существует полезная библиотека, называемая Interlock, которая прослушивает Docker Events API и обновляет конфигурацию/осуществляет перезапуск сервиса «на лету». Но этот инструмент больше требуется после нового добавления балансирования нагрузки в Docker 1.12.
Это не может быть так просто…
Эта картинка из Nigel Poulton очень хорошо обобщает различия между старым Swarm и новым Swarm.
Перевод картинки:
Старый путь (много шагов и команд не показано)
- Создать ключи
- Перезапустить демоны manager1 и node1 с TLS-флагами на 2376
- Запустить распределенный сервис Consul (контейнер)
- Запустить клиент Consul на node1 (не показано, но он успешно присоединился к серверу Consul)
- Начать управление Swarm (контейнер) на 2376 и карты 3376:2376
5.1. Скопировать ключи в контейнер Swarm менеджера с помощью объема и специальных ключей и порт для менеджера команд Swarm
5.2. Успешно получить роль лидера - Начать присоединять к Swarm контейнер на node1
6.1. Не монтируйте ключи внутрь контейнера и задайте команду присоединения как неподдерживаемую опцию - Сконфигурируйте клиент при помощи DOCKER_HOST (указывающий на Swarm)
7.1. …
Новый путь
С Docker 1.12 вы также как и раньше можете инсталлировать внешние распределенные службы (consul, etcd, zookeeper), или отдельную службу планирования. Настройка TLS сквозная из коробки, нет «незащищенного режима». У меня не существует никаких сомнений, что новый Docker Swarm является самым быстрым путем для получения запущенного и работающего docker-native кластера, готового быть развернутым в продакеш.
А что насчет большого масштабирования? Спасибо усилиям «капитана» Docker«a Chanwit Kaewkasi и DockerSwarm2000, они показали нам, что вы можете создать кластер из 2384 узлов и 96287 контейнеров.
Режим Swarm является самым оптимальным
Включать режим Swarm совершенно необязательно. Вы можете думать о режиме Swarm, как о наборе скрытых процедур, которые запускаются всего лишь командой
docker swarm init
Swarm в Docker«е 1.12 также поддерживает согласования, плавающие обновления (rolling updates) образа, глобальные сервисы и сервисы по расписанию, базирующиеся на ограничениях.
Отказ узла в Docker Swarm
Также хочу затронуть тему отказа узлов в Docker Swarm.
Команды, относящиеся к сервисам Docker Engine 1.12, являются декларативными. Например, если вы задаете команду «Я хочу 3 реплики данного сервиса», то кластер будет поддерживать это состояние.
В случае отказа узла, контейнеры которого были задействованы, swarm обнаружит, что желаемое состояние не совпадает с действительным, и автоматически исправит ситуацию путем перераспределения контейнеров на другие доступные узлы.
Чтобы это продемонстрировать, давайте зададим новый сервис с тремя репликами.
docker service create --name web --replicas 3 francois/apache-hostname
Запустите, чтобы проверить работу сервиса
docker service tasks web
Сейчас у нас есть по одному контейнеру на каждом из узлов. Давайте выведем из строя узел 3, чтобы посмотреть на регулирование swarm в действии.
# Run this on node3
docker swarm leave
Теперь желаемое состояние не совпадает с действительным. У нас есть только 2 действующих контейнера, тогда как мы обозначили 3 контейнера, когда запускали сервис.
Использование докер сервиса дает вам возможность увидеть, что количество реплик уменьшилось до двух, а затем снова вернулось к трем
docker service tasks web
покажет вам новый контейнер, назначенный на другом узле вашего кластера.
Этот пример показывает только регулирование контейнеров на рабочих узлах. Совершенно другой процесс происходит, когда из строя выходит менеджер, особенно, если это лидер raft группы для решения задач консенсуса.
Глобальные сервисы
Глобальные сервисы полезны, когда вы хотите создать контейнер на каждом узле вашего кластера. Подумайте о ведении протокола или мониторинге.
docker service create --mode=global --name prometheus prom/prometheus
Помните, я говорил, что сервисы являются декларативными? Когда вы добавляете новый узел к вашему кластеру, swarm определяет, что желаемое состояние не совпадает с действительным, и запускает экземпляр глобального контейнера на этом узле.
Ограничения
Для демонстрации ограничений я использовал докер машину, чтобы ускорить новую машину с помощью engine label.
docker-machine create -d virtualbox --engine-label com.example.storage="ssd" sw3
Затем я добавил ее в swarm.
docker swarm join --token [token] [manager ip]:[manager port]
Далее я создал сервис, ссылающийся на это ограничение.
docker service create --name web2 --replicas 3 --constraint 'engine.labels.com.example.storage == ssd' francois/apache-hostname
Помните, я говорил, что сервисы являются декларативными? ;) Это означает, что, когда мы масштабируем этот сервис, он запоминает наши ограничения и масштабирует только отвечающие условиям узлы.
John Zaccone
Docker Captain и Software Engineer в Ippon Technologies, который любит вбрасывать вещи на рынок побыстрее. Специализируется на agile, микросервисах, контейнерах, автоматизации, REST, devops.