Как развернуть полноценный кластер Redis? Часть 2
Всем привет, это заключительная часть статьи, где подробно описывается развёртывание Redis-кластера.
Итак, изначально было принято решение описать каждый сервис отдельно для удобного их размещения на нодах кластера. Docker-compose.yml будет выглядеть следующим образом:
redis-master: image: username/redis-master:0.1 ports: - mode: host protocol: tcp published: 6379 target: 6379 deploy: replicas: 1 endpoint_mode: dnsrr placement: constraints: - node.labels.redis-master == true networks: redis-net: aliases: - redis-master
В данном примере описан сервис redis-master. В секции ports мы описываем какой режим сети использовать (в нашем случае host позволяет напрямую использовать сеть ноды кластера), какие порты контейнера мы выносим из контейнера.
Более подробно о типе сетей в Docker swarm вы можете ознакомиться по данной ссылке. Aliases — на всякий случай ещё раз указываем сетевой алиас нашего сервиса. Networks — указываем, к какой сети будет присоединен наш сервис, в данном случае к redis-net. Placement constraints позволяет нам ограничить размещение нашего сервиса, в данном случае мы используем ограничение по тегам, которые выставили ранее.
Секция, описывающая redis-slave, выглядит следующим образом:
redis-slave-1: image: mrgreyves/redis-slave:0.1 ports: - mode: host protocol: tcp published: 6379 target: 6379 deploy: replicas: 1 endpoint_mode: dnsrr placement: constraints: - node.labels.redis-slave-1 == true depends_on: - redis-master networks: - redis-net
Основные отличия в описании redis-slave заключаются в директиве
Секция, описывающая redis-sentinel:
redis-sentinel-1: image: mrgreyves/redis-sentinel:0.6 ports: - mode: host protocol: tcp published: 5000 target: 5000 deploy: replicas: 1 endpoint_mode: dnsrr placement: constraints: - node.labels.redis-sentinel-1 == true depends_on: - redis-master networks: redis-net:
Все директивы мы уже разобрали немного ранее. И вот, настал тот торжественный момент, когда мы с вами можем запустить наш кластер. Для это воспользуемся следующей командой:
docker stack deploy --compose-file=docker-compose-v2.yml redis
--compose-file= — указываем, какой именно файл использовать. Redis — название нашего стака.
Также хочу отметить, что образы, которые мы создавали ранее, мы запушили в публичный репозиторий на docker hub. Если же вы используете приватный, необходимо использовать дополнительную опцию
Для проверки нашего стака используем команду:
docker stack services redis
Если всё прошло хорошо, то вывод будет следующим:
Убедимся, что redis-master действительно master. Для это подключаемся любым клиентом к ноде, на которой он запущен, и воспользуемся командой INFO. Нас интересует секция Replication, если в ней указано role:master, то всё прошло хорошо.
Далее подключаемся к следующей ноде и воспользуемся аналогичной командой. Если мы видим, что role:slave, то значит, что у нас всё хорошо.
А теперь начинается самая интересная часть: мы будем ломать наш кластер и сделаем это слегка в софтовом режиме, а именно: просто удалим сервис redis-master. Для этого в docker-compose.yml просто меняем количество реплик на 0 и деплоимся.
Логи redis sentinel будут следующими:
1:X 02 Feb 10:50:58.299 * +slave slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.291 # +sdown master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.363 # +odown master mymaster 10.0.3.16 6379 #quorum 2/2 1:X 02 Feb 12:03:50.363 # +new-epoch 1 1:X 02 Feb 12:03:50.363 # +try-failover master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.367 # +vote-for-leader 37e8f4093969307733548e1948c184a1a69c2552 1 1:X 02 Feb 12:03:50.374 # 289730ac61e05b7edc005c348088625db26d3983 voted for 37e8f4093969307733548e1948c184a1a69c2552 1 1:X 02 Feb 12:03:50.381 # 6428c92d37154089ce67a33123f3fd0b86afe4e6 voted for 37e8f4093969307733548e1948c184a1a69c2552 1 1:X 02 Feb 12:03:50.422 # +elected-leader master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.422 # +failover-state-select-slave master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.485 # +selected-slave slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.485 * +failover-state-send-slaveof-noone slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:50.549 * +failover-state-wait-promotion slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:51.440 # +promoted-slave slave 10.0.3.17:6379 10.0.3.17 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:51.440 # +failover-state-reconf-slaves master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:51.512 * +slave-reconf-sent slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:52.447 * +slave-reconf-inprog slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:52.447 * +slave-reconf-done slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:52.510 # -odown master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:52.510 # +failover-end master mymaster 10.0.3.16 6379 1:X 02 Feb 12:03:52.511 # +switch-master mymaster 10.0.3.16 6379 10.0.3.17 6379 1:X 02 Feb 12:03:52.511 * +slave slave 10.0.3.18:6379 10.0.3.18 6379 @ mymaster 10.0.3.17 6379 1:X 02 Feb 12:03:52.511 * +slave slave 10.0.3.16:6379 10.0.3.16 6379 @ mymaster 10.0.3.17 6379 1:X 02 Feb 12:03:55.563 # +sdown slave 10.0.3.16:6379 10.0.3.16 6379 @ mymaster 10.0.3.17 6379
Из них мы видим, что зафиксировано падение мастера:
+sdown master mymaster 10.0.3.16 6379
И начался выбор нового мастера, который впоследствии стал успешно выбран:
+elected-leader master mymaster 10.0.3.16 6379
После этого мы подключаемся к соседней ноде и командой INFO проверяем его роль. Если роль — master, значит переключение произошло успешно.
Полезная заметка? Напишите в комментариях!