Статьи

Масштабирование до бесконечности с помощью Docker Swarm, Docker Compose and Consul (Часть 4/4) — Масштабирование отдельных сервисов

Эта серия разделена на следующие статьи.

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

В этой статье мы рассмотрим, как масштабировать отдельные сервисы.

Настроить

Для тех из вас, кто остановил виртуальные машины, которые мы создали в предыдущей статье ( vagrant halt ) или отключили свои ноутбуки, вот как быстро добраться до того же состояния, в котором мы были раньше. Остальные могут пропустить эту главу.

1
2
3
4
5
vagrant up
vagrant ssh swarm-master
ansible-playbook /vagrant/ansible/infra.yml -i /vagrant/ansible/hosts/prod
ansible-playbook /vagrant/ansible/books-service.yml -i /vagrant/ansible/hosts/prod
export DOCKER_HOST=tcp://0.0.0.0:2375

Мы можем проверить, все ли в порядке, выполнив следующее.

1
2
docker ps
curl http://10.100.199.200/api/v1/books | jq .

Первая команда должна перечислить, среди прочего, контейнеры booksservice_ [COLOR] _1 и booksservice_db_1. Второй должен получить ответ JSON с тремя книгами, которые мы вставили ранее.

С этим в стороне, мы можем продолжать, где мы оставили.

Услуги масштабирования

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

1
2
3
4
docker ps | grep booksservice
cd /data/compose/config/books-service
docker-compose scale blue=2
docker ps | grep booksservice

Если вы используете зеленый цвет , измените приведенную выше команду на docker-compose scale blue=2 .

Последняя команда docker ps указала, что запущены два экземпляра нашего сервиса; booksservice_blue_1 и booksservice_blue_2 .

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

1
2
ansible-playbook /vagrant/ansible/books-service.yml -i /vagrant/ansible/hosts/prod --extra-vars "service_instances=3"
docker ps | grep booksservice

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

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

Так же просто, мы можем сократить до двух услуг.

1
2
ansible-playbook /vagrant/ansible/books-service.yml -i /vagrant/ansible/hosts/prod --extra-vars "service_instances=2"
docker ps | grep booksservice

Все это было бы бессмысленно, если бы наша конфигурация nginx не поддерживала это. Несмотря на то, что у нас есть несколько экземпляров одного и того же сервиса, nginx должен знать об этом и выполнять балансировку нагрузки для всех из них. Используемая нами пьеса Ansible уже обрабатывает этот сценарий.

Давайте посмотрим на конфигурацию nginx, связанную с сервисом books .

1
cat /data/nginx/includes/books-service.conf

Выход следующий.

1
2
3
location /api/v1/books {
  proxy_pass http://books-service/api/v1/books;
}

Это говорит nginx, что всякий раз, когда кто-то запрашивает адрес, начинающийся с / api / v1 / books , он должен быть передан по адресу http: // books-service / api / v1 / books . Давайте посмотрим на конфигурацию для адреса книжного сервиса (в конце концов, это не настоящий домен).

1
2
cat /data/nginx/upstreams/books-service.conf
docker ps | grep booksservice

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

1
2
3
4
upstream books-service {
    server  10.100.199.202:32770;
    server  10.100.199.203:32781;
}

Это говорит nginx балансировать запросы между этими двумя серверами и портами.

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

1
2
3
4
5
upstream books-service {
    {{range service "books-service-blue" "any" }}
    server {{.Address}}:{{.Port}};
    {{end}}
}

Он сообщает Консулу, чтобы он извлекал все экземпляры (диапазон) службы с именем books-service-blue, игнорируя их статус (любой). Для каждого из этих экземпляров следует указать IP (.Address) и порт (.Port). Мы создали шаблон для синих и зеленых версий. Когда мы запустили последнее развертывание, Ansible позаботился о создании этого шаблона (с правильным цветом), копировании его на сервер и запуске шаблона Consul, который, в свою очередь, перезагрузил nginx в конце процесса.

Текущая настройка не масштабирует MongoDB. Я оставлю это на ваше усмотрение. Процесс должен быть таким же, как и для самой службы с дополнительным предупреждением, что Mongo должен быть настроен на использование набора реплик с одним экземпляром, установленным в качестве основного, а остальные — как вторичными.

Конец (На данный момент)

Мы рассмотрели много вопросов в этих четырех статьях и оставили еще больше неисследованных возможностей. Например, мы могли бы размещать в одном кластере не только разные сервисы, но и копии одних и тех же сервисов для нескольких клиентов. Мы могли бы создать логику, которая развертывает службы не только на узлах с наименьшим количеством контейнеров, но и на тех, у которых достаточно ЦП или памяти. Мы могли бы добавить Kubernetes или Mesos к установке и иметь более мощные и точные способы планирования развертываний. У нас уже были установлены проверки процессора, памяти и HD в Консуле, но никаких действий не предпринимается, когда они достигают своих пороговых значений. Однако время ограничено, и не все можно исследовать одновременно.

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

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