Pacemaker HA: сетевые соединения и динамическое размещение ресурсов кластера

    Ноды кластера очень сильно зависят от их физического соединения. Как показывает практика, большинство случаев отработки failove-миграций ресурсов происходит по вине именно сетевых соединений. Поэтому от того, как у вас осуществляется соединение между нодами и настроены размещения ресурсов, зависит очень многое.

    Для примера, я буду рассматривать кластер состоящий из двух нод. Одна нода будет в состоянии Active, а другая в состоянии Hot Spare. Наш кластер будет обслуживать внутреннюю приватную сеть и содержать следующие ресурсы кластера: Mysql сервер и Mysql VIP. На двух нодах Mysql сервер будет запущен c репликацией Master-Master. Однако вся работа будет производиться только с одним экземпляром через виртуальный ip адрес. Такая схема позволяет получить максимально быстрый failover. Опустим выбор именно данной конфигурации её плюсы и минусы — нас сейчас интересует доступность этих ресурсов в случае падения сетевых линков.


    рис. 1 Схема класстера

    Главное на что следует обратить внимание при проектировании любого кластера это избыточность сетевого соединения между нодами кластера. Другими словами должны быть как минимум два крос-соединения между нашими нодами. Их можно объединить посредствам бондинга в один интерфейс либо просто использовать два разных интерфейса в конфигурации heartbeat или corosynс. При проектировании нового кластера я бы рекомендовал использовать corosync, не только потому что разработка heartbeat потихоньку сворачивается в сторону pacemaker и corosync, а потому, что он обладает более гибкими настройками для работы с несколькими интерфейсами и может использовать их параллельно или в режиме “действующий и запасной”.

    Не следование правилам резервирования или выделения отдельных сетевых интерфейсов может привести к ситуации расщепления разума (split brain). Что в принципе не сулит ничего хорошего. Также удостоверьтесь что используете разные сетевые карты, а то будет не много толку при аппаратном сбое.

    Т.к. у нас кластер состоит из двух нод — то мы имеем проблемы с кворум. А точнее его полное отсутствие, что опять же намекает на необходимость резервния соединения между нодами.
    На этом хватит теории переходим к практике.
    Выставляем поведение нод в случае отсутсвия кворума:

    	crm configure property no-quorum-policy="ignore" 
    

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

    	crm configure property symmetric-cluster="false"
    

    Несимметричный кластер не будет запускать ресурсы если у них явно не указаны значения стоимости их запуска на каждой из нод. К примеру, вот так мы можем задать значение 100 для некого ресурса P_RESOURCE для ноды first.local и значиение 10 — для ноды second.local.

    	location  L_RESOURCE_01 P_RESOURCE 100: first.local
    	location  L_RESOURCE_02 P_RESOURCE  10: second.local
    

    Данная конфигурация говорит нам, что ресурс запустится на ноде first.local — т.к. у него суммарная стоимость на этой ноде оказалась больше чем на ноде second.local.

    Я умышленно опускаю первичные настройки нод, настройку бондига (по желанию), установку pacemaker и corosync, настройку Master-Master реплиацию и т.д. Этого и так достаточно в интернетах и легко находится. В свою очередь я покажу как нужно правильно настраивать ресурсы кластера с учётом сетевой специфики.

    Условимся, что у нас приватная сеть: 192.168.56.0/24, Mysql VIP — 192.168.56.133 и две ноды в сети, которые мы будем использовать для оценки адекватности сетевого соединения: 192.168.56.1 и 192.168.56.100.

    Небольшое отступление: для правильной работы Mysql в связке с pacemaker нужно отключить его автоматический старт:

    	chkconfig mysql --list
    	mysql 0:off 1:off 2:off 3:off 4:off 5:off 6:off
    

    Т.к. Муsql сервер используется только в приватной сети — падение приватного коннекта на активной ноде должно приводить к миграции ресурса на другую ноду, где коннект присутсвует. Добьёмся такого поведения.

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

    	ocf:heartbeat:pingd (Deprecated)
    	ocf:pacemaker:pingd (Deprecated)
    	ocf:pacemaker:ping
    

    Два из которых являются устаревшими.

    На основе этих ресурсов мы можем управлять размещением ресурсов на нодах. Делается это при помощи параметра location.

    Для примера, сначала, опишем конфигурацию pacemaker кластера показанную на рисунке (рис. 1):

    	crm configure
    	primitive P_MYSQL lsb:mysql
    	primitive P_MYSQL_IP ocf:heartbeat:IPaddr2 params \ 
    		ip="192.168.56.133" nic="eth0"
    	clone CL_MYSQL P_MYSQL clone-max="2" clone-node-max="1" \
     		globally-unique="false"
    

    Данная конфигурация описывает кластер из двух нод с двумя Mysql мастерами (клонированными). Работа с базой ведётся через VIP адрес.
    Для случае несемметричного кластера нам необходимо явно задать значения для location:

    	location L_MYSQL_01 CL_MYSQL 100: first.local
    	location L_MYSQL_02 CL_MYSQL 100: second.local
    

    Данная запись говорит нам о том, что ресурc типа “clone” стоит запускать на двух нодах кластера.

    Теперь тоже самое для VIP:

    	location L_MYSQL_IP_01 P_MYSQL_IP 100: first.local
    	location L_MYSQL_IP_02 P_MYSQL_IP  10: second.local
    

    Здесь мы отдаём предпочтение на запуск VIP на ноде first.local
    И завершаем настройку:

    	commit
    

    Если теперь проверить как работает failover — то при запуске VIP стартует на first.local при её падении (kill -9 corosync) — он переезжает на second.local. Однако при возвращении ноды first.local — он возвращается обратно. Это связано с тем, что значение score для first.local болше чем на secon.local (100 > 10). Чтобы предотвратить такие переезды на высоконагруженном кластере, которые могут привести к нежелательным простоям, мы должны задать параметр “липкости” (resource-stickiness):

    	crm configure property rsc_defaults resource-stickiness="110"
    

    Теперь повторяя ту же операцию мы имеем значение score: 110+10=120 против 100, что предотвращает переезд.

    Кластер работает и позволяет в случае неполадок с железом/питанием переключаться автоматически на резервную ноду.
    Теперь настроем мониторинг внутренней сети. Будем пинговать 192.168.56.1 и 192.168.56.100:

    	crm configure
    	primitive P_INTRANET ocf:pacemaker:ping \
    		params host_list="192.168.56.1 192.168.56.100"  \
    		multiplier="111" name="ping_intranet" \ 
    		op monitor interval="5s" timeout="20s"
    	clone CL_INTRANET P_INTRANET globally-unique="false"
    	location L_INTRANET_01 CL_INTRANET 100: first.local
    	location L_INTRANET_02 CL_INTRANET 100: second.local
    	commit
    

    Данная конфигурация пингует два хоста. Каждый хост оценивается в 111 очков. Суммарное значение для каждой ноды хранится в переменной ping_intranet. Эти значения можно и нужно использовать при определении места расположения ресурса. Теперь укажем VIP чтобы он использовал эти очки в решении, где ему находиться:

    	crm configure
    	location L_MYSQL_IP_PING_INTRANET P_MYSQL_IP  rule \
    		ping_intranet: defined intranet
    	commit
    

    Эти дополнительные очки сумируются с пердыдущими заданными нами. И исходя из итоговой суммы определяется положение ресурса.
    Мониторинг состояния кластера с указанием значении score производиться двумя утилитами: ptest и crm_mon:
    • ptest -sL — показывает текущие значение размещения для кажой ноды.
    • crm_mon -A — показывает состояние переменной ping_intranet для каждой из нод.
    Итого мы имеем следующие расчёты для разных ситуаций:



    Для того, чтобы перевести кластер в исходное положение необходимо перенести ресурс на ноду first.local:

    	crm resource move P_MYSQL_IP first.local
    

    После этого ресур получает location с 1000000 очками (это INF для pacemaker) и переезжает на first.local. Очень важно дальше сделать unmove этого ресурса, который вернёт очки locatoin на место, но не поменяет расположение ресурса, т.к. у него и так будет больше очков (см. начальную ситуацию):

    	crm resource unmove P_MYSQL_IP 
    

    Что ещё можно делать с location и ping


    Можно проверять запущен ли ресурс ping’a и проверять его значение:

    	location L_RESOURCE P_RESOURCE rule -inf: not_defined ping_intranet or ping_intranet lte 0
    

    Данный location запрещает размещать ресурс P_RESOURCE на ноде, где пинг меньше либо равен 0 (lte — less then or equal) или не запущен ресурс пинга.

    Можно также совместить это правило с именем ноды:

    	location L_RESOURCE P_RESOURCE rule -inf: #host eq first.local and ping_intranet lte 0
    

    Говорит нам что если это нода first.local и пинг =< 0, то этот ресурс здесь не может находиться.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 14

      +1
      К вопросу о борьбе с сплитбрейном в кластерах 1+1, я как раз об этом сейчас много думаю.

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

      Логика такая: если мы теряем линк с кластером на «нашей» половинке кабеля, то мы теряем и линк с клиентами. Если мы потеряли линк на «их» половинке, то ситуация строго зеркальная — они не имеют линка с клиентами, а мы продолжаем их обслуживать.

      Понятно, что трафик по такому линку гонять не надо, но для подстраховки вынимания кабеля — самое то.
        +1
        Не совсем понял схему подключения. Но ваше решение исключает крос-кабель, не так ли? На мой взгляд, в кластере 1+1, крос кабель очень важен и прост. А в таких системах, чем проще сделал — тем легче и быстрее чинить ;)
          +1
          Не, не так.

          терминология: клиентский порт — тот порт, через который идут клиентские запросы. кластерный порт — то, через что идёт репликация.

          Делается бонд между кластерным портом (который кроссом соединяется) и туннелем в клиентском порте. Если кто-то вынет кластерный провод, трафик пойдёт через туннель в клиентском порте.

          Если кто-то вынет клиентский провод, кластер останется жить.

          Если кто-то вынет оба провода, то мы имеем гарантию, что клиент не придёт на сплитбрейновый сервер (т.к. клиентский порт отключен). Когда воткнут клиентский порт, то ПО тут же обнаружит сплитбрейн и отвалится.
            +1
            Интересная идея. Нада будет погонять её на тестовом стенде.
              0
              Ага. Пока у меня это тоже теоретические изыскания.

              Меня очень пугает состояние, когда у нас есть primary/primary drbd с порванным кластреным линком. Что оно там на диске натворит, страшно подумать.
        +1
        location L_RESOURCE_02 P_RESOURCE 10: second.local
        Данная конфигурация говорит нам, что ресурс запустится на ноде first.local — т.к. у него суммарная стоимость на этой ноде оказалась больше чем на ноде second.local.
        — вот этот момент не совсем понятен
        зачем указывать второй локейшн если у нас только один вип айпи?

        >Мы должны проверять состояния хостов в приватной сети. Для этого мы будем использовать ресурс кластера ping.

        так этим же занимается corosync/heartbeat
        можно этот момент (про ping) подробней

          +1
          зачем указывать второй локейшн если у нас только один вип айпи?

          Второй location указан для того, чтобы в случае отказа ноды first.local он мигрировал на second.local. Т.к. не задав значение score для second.local при условии не-симметричного кластера (symmetric-cluster=«false») он на ней просто никогда не запустится. Если кластер симметричный (по умолчанию так и есть), то указывать не нужно. Однако я бы не советовал делать так — мы теряем предсказуемость оценки размещения.

          так этим же занимается corosync/heartbeat

          corosync/heartbeat — занимаются тем, что мониторят состояние жизни нод, если говорить грубо. И для этого им выделяется, как правило, отдельный прямой (крос) линк.
          В статье описывается размещения ресурсов привязанных к отличным от этих интерфейсов. К примеру на кластере может быть много сетевых интерфейсов — внутрення сеть, внешняя, DMZ. И мнрожество ресурсов привязанных только к одной из них. В таком случае падения какого-то линка не должна приводить к мигарции всех ресурсов класстера, а переносить только один. Тем самым уменьшая врямя простоя.
            0
            а STONITH используете?
            что будет если линки между нодами пропадут и каждая из них будет думать, что другая нода мертва?
            или оно как-то у вас иначе решается?
              0
              Использовать STONITH в двухнодном кластере при пропаже линков — бесмысленно. Ноды просто убъют друг друга. Мы получим, так называемый deathmatch,: одна убивает другую — другая перезагружается и убивает первую и тд. Т.к. не понятно какая из нод «правильная» и нету кворума.
              В свою очердь STONITH нужен для убийства ноды с зависшим ресурсом. Однако тут много тонкостей с таймаутами мониторинга и остановки ресурсов. Можно убить ноду, которая просто замешкалась с отмонтирование файловой системы, ожидая, когда её просто освободит процесс. Это вообще отдельная большая тема.
                0
                а что тогда происходит при потере связи?
                получается, кластерный ресурс взлетит на обеих нодах
                  0
                  Как я писал нужно дублировать соединения, выносить их отдельно. Также как вариант — добавить третью ноду, которая будет находиться в состоянии standby и будет участвовать только для кворума. К примеру, в роли такой ноды, может вуступать роутер либо любой другой сервер в вашей сети.
                    0
                    Пожалуйста, расскажите подробнее про вариант?
          0
          Отличная статья, спасибо. Когда-то боролся с репликацией MySQL при использовании в кластере, но давно это было, и MySQL еще не имела таких развитых средств, как сейчас, и пришлось использовать DRDB. Теперь с этим проще, хотя DRDB тоже не потерял своей актуальности.
            0
            с DRBD мы получаеи уверенность в том, что данные на обоих машинах консинстентны (использование типа С), однако мы получаем не Hot Spare. Т.к. нужно время на старт сервиса Mysql, который, при таком старте, будет проверять таблицы базы.
            Решение с мастер-мастер репликацией обладает своими недостатками, кроме вероятности потерять часть транзацкций, к примеру, — не правильно разогретый кэш.

          Only users with full accounts can post comments. Log in, please.