CUBE High Availability с использованием HSRP
Допустим, у вас есть необходимость подключить свой кластер CUCM к провайдеру телефонных услуг с помощью SIP-транка. Как известно, для этого нам необходим IP-IP шлюз - Cisco Unified Border Element (CUBE). Да еще не просто подключить, а обеспечить высоко доступность данного подключения с использованием box-to-box избыточности. Что человеческим языком означает: есть 2 CUBE (один основной, второй резервный), 1 SIP провайдер – нужно сделать так, чтоб во время нормальной работы сети все звонки выходили через основной CUBE, а в случае его сбоя (или его интерфейсов) – через резервный. Все это должно происходить автоматически и с сохранением текущих активных звонков.
Решить данную задачу мы можем с использованием Hot Standby Routing Protocol (HSRP).
Что необходимо:
1. Два идентичных Cisco ISR G2s c лицензией UC Technology Package (SL-29-UC-K9 or SL-39-UC-K9), 1GDRAM памяти и Cisco IOS Software release 15.1.2T или позже.
Cisco IOS Software release 15.1.2T поддерживает сохранение активных SIP-SIP звонков во время HSRP switchover, но не поддерживает сохранение сигнализации. Поддержка сохранения сигнализации появилась в Cisco IOS Software release 15.2.3T.
2. Оба маршрутизатора физически должны быть расположены в одной Ethernet LAN.
3. Конфигурация функционала CUBE должна быть идентична на обоих маршрутизаторах.
4. Один маршрутизатор явно должен быть определен как HSRP Active, второй – как HSRP Standby
Для реализации CUBE box-to-box избыточности, как уже было указано, необходимо два идентичных CiscoISR G2: один определяется как активный, второй как резервный. HSRP настраивается на физических или субинтерфейсах маршрутизаторов, формируя HSRP группу.
В случае выхода из строя активного маршрутизатора, резервный берет на себя все его обязанности, в том числе продолжает пересылать те же RTP пакеты, маршрутизацией которых занимался активный маршрутизатор до сбоя.
В чистом виде протокол HSRP занимается мониторингом интерфейсов, а вот мониторингом сессий занимается Statefull Switchover (SSO), именно эта технология позволяет активному и резервному маршрутизаторам обмениваться информацией о сессиях. Это и дает возможность сохранять передачу медиа потока активного звонка во время HSRP switchover. Звонки же, которые находятся в переходном состоянии (еще не установлены или в процессе изменения за счет использования функций hold, transfer и т.п. ) во время failover обрываются. Так же терпят неудачу звонки, которые используют ресурсы DSP (транскодирование, например).
В чистом виде протокол HSRP занимается мониторингом интерфейсов, а вот мониторингом сессий занимается Statefull Switchover (SSO), именно эта технология позволяет активному и резервному маршрутизаторам обмениваться информацией о сессиях. Это и дает возможность сохранять передачу медиа потока активного звонка во время HSRP switchover. Звонки же, которые находятся в переходном состоянии (еще не установлены или в процессе изменения за счет использования функций hold, transfer и т.п. ) во время failover обрываются. Так же терпят неудачу звонки, которые используют ресурсы DSP (транскодирование, например).
Схема нашего подключения выглядит так:
Ну что же, поехали!
voice service voip
mode border-element
allow-connections sip to sip
Первое, что нужно сделать – это настроить HSRP.
Исходя из нашей схемы, у нас будет 2 HSRP группы. В первую группу, возьмем для нее номер 0, будут входить внешние интерфейсы маршрутизаторов (GigabitEthernet0/0 на обоих), а во вторую (под номером 1) – внутренние (GigabitEthernet0/1 на обоих). Эти группы независимы друг от друга, то есть маршрутизатор может быть одновременно активным в одной и резервным в другой группе.
Тогда решаем, кто и где будет главным. Здесь нужно помнить, что активный маршрутизатор занимается пересылкой трафика и отвечает на запросы, отправленные на виртуальный HSRP IP адрес. Резервный только слушает и мониторит работоспособность активного. Исходя из этого, для корректной маршрутизации наших звонков, один маршрутизатор должен быть активным в обоих HSRP группах.
Выбираем главным CUBE-1, с него и начинаем
CUBE-1:
interface GigabitEthernet0/0 – наш внешний интерфейс
ip address 10.10.25.14 255.255.255.0
standby version 2
standby 0 ip 10.10.25.1
standby 0 priority 110
CUBE-2:
interface GigabitEthernet0/1 – наш внутренний интерфейс
ip address 10.10.24.14 255.255.255.0
standby version 2
standby 1 ip 10.10.24.1
!Активируем HSRP, задаем номер HSRP группы 1 и виртуальный IP адрес.
После этих команд HSRP уже включился и начал отправлять hello пакеты на поиски других участников группы и для участия в выборах. Вспоминаем, что на выборах побеждает участник с большим приоритетом. Хм, но приоритет мы не задавали. Но он есть, правда у все одинаковый – 100. В таком случае побеждает маршрутизатор с большим IP адресом. Но на это не стоит надеяться, а задать приоритет явно.
standby 1 priority 110
!Задаем приоритет маршрутизатора в указанной группе. Диапазон 0-255.
standby 1 name SB
!Задаем имя нашей группе. Нужно для SSO. Дальше рассмотрим зачем
ip address 10.10.24.14 255.255.255.0
standby version 2
standby 1 ip 10.10.24.1
!Активируем HSRP, задаем номер HSRP группы 1 и виртуальный IP адрес.
После этих команд HSRP уже включился и начал отправлять hello пакеты на поиски других участников группы и для участия в выборах. Вспоминаем, что на выборах побеждает участник с большим приоритетом. Хм, но приоритет мы не задавали. Но он есть, правда у все одинаковый – 100. В таком случае побеждает маршрутизатор с большим IP адресом. Но на это не стоит надеяться, а задать приоритет явно.
standby 1 priority 110
!Задаем приоритет маршрутизатора в указанной группе. Диапазон 0-255.
standby 1 name SB
!Задаем имя нашей группе. Нужно для SSO. Дальше рассмотрим зачем
interface GigabitEthernet0/0 – наш внешний интерфейс
ip address 10.10.25.14 255.255.255.0
standby version 2
standby 0 ip 10.10.25.1
standby 0 priority 110
Переходим к резервному
interface GigabitEthernet0/1 – наш внутренний интерфейс
ip address 10.10.24.13 255.255.255.0
standby version 2
standby 1 ip 10.10.24.1
standby 1 priority 100
standby 1 name SB
interface GigabitEthernet0/0 – наш внешний интерфейс
ip address 10.10.25.13 255.255.255.0
standby version 2
standby 0 ip 10.10.25.1
standby 0 priority 100
ip address 10.10.24.13 255.255.255.0
standby version 2
standby 1 ip 10.10.24.1
standby 1 priority 100
standby 1 name SB
interface GigabitEthernet0/0 – наш внешний интерфейс
ip address 10.10.25.13 255.255.255.0
standby version 2
standby 0 ip 10.10.25.1
standby 0 priority 100
После этого получаем первые результаты
CUBE-1#sh standby brief
P indicates configured to preempt.
|
Interface Grp Pri P State Active Standby Virtual IP
Gi0/1 1 110 Active local 10.10.24.13 10.10.24.1
Gi0/0 0 110 Active local 10.10.25.13 10.10.25.1
P indicates configured to preempt.
|
Interface Grp Pri P State Active Standby Virtual IP
Gi0/1 1 110 Active local 10.10.24.13 10.10.24.1
Gi0/0 0 110 Active local 10.10.25.13 10.10.25.1
Давайте теперь посмотрим, что будет, если один из интерфейсов на активном маршрутизаторе выйдет из строя.
Допустим, Gi0/0 отвалился. В таком случае в группе 0 роль активного переходит к CUBE-2. Но в группе 1 ничего не меняется, CUBE-1 остается активным. И что станется с нашими звонками? В такой ситуации не то что текущие звонки не сохраняются, а и новые не устанавливаются.
Тогда нам нужно как-то заставить поменяться ролями маршрутизаторы в 0 группе в зависимости от положения дел в группе 1.
Тут мы можем сделать такое: сказать CUBE-1, если его интерфейс Gi0/0 уходит в down, уменьшить приоритет маршрутизатора в группе 1 на 11.
CUBE-1:
interface GigabitEthernet0/1
standby 1 track 1 decrement 11
!Определяем уменьшение приоритета маршрутизатора на 11 если трек 1 возвращает результат false
track 1 interface GigabitEthernet0/0 line-protocol
!Отслеживаем состояние интерфейса GigabitEthernet0/0. Если этот интерфейс по какой-то причине упадет, track 1 получит значение false.
interface GigabitEthernet0/1
standby 1 track 1 decrement 11
!Определяем уменьшение приоритета маршрутизатора на 11 если трек 1 возвращает результат false
track 1 interface GigabitEthernet0/0 line-protocol
!Отслеживаем состояние интерфейса GigabitEthernet0/0. Если этот интерфейс по какой-то причине упадет, track 1 получит значение false.
И того, если интерфейс Gi0/0 падает – приоритет CUBE-1 в группе 1 уменьшается с 110 до 99, что меньше приоритета CUBE-2 в этой же группе (100). Значит, CUBE-2 теперь должен стать активным. Может, конечно, и должен, но не станет.
Вспоминаем еще одну характеристику протокола HSRP. Если в группе уже выбран активный маршрутизатор, то он не отдаст свою роль до тех пор, пока находится в рабочем состоянии. Даже если появится участник с большим приоритетом. Это дефолтное поведение.
Нам такое не подходит. Поэтому, воспользуемся правом изменить дефолтные установки. И в этом нам поможет следующая команда:
interface GigabitEthernet0/1
standby 1 preempt
Вот только теперь мы получим то, что хотели. Если на CUBE-1 выйдет из строя интерфейс Gi0/0, он потеряет роль активного в обеих группах. Такое же необходимо сделать и для интерфейса Gi0/1.
Вспоминаем еще одну характеристику протокола HSRP. Если в группе уже выбран активный маршрутизатор, то он не отдаст свою роль до тех пор, пока находится в рабочем состоянии. Даже если появится участник с большим приоритетом. Это дефолтное поведение.
Нам такое не подходит. Поэтому, воспользуемся правом изменить дефолтные установки. И в этом нам поможет следующая команда:
interface GigabitEthernet0/1
standby 1 preempt
Вот только теперь мы получим то, что хотели. Если на CUBE-1 выйдет из строя интерфейс Gi0/0, он потеряет роль активного в обеих группах. Такое же необходимо сделать и для интерфейса Gi0/1.
standby 0 track 2 decrement 11
standby 0 preempt
track 2 interface GigabitEthernet0/1 line-protocol
Не забываем про резервный
CUBE-2:
interface GigabitEthernet0/0
standby 0 track 2 decrement 11
standby 0 preempt
interface GigabitEthernet0/1
standby 1 track 1 decrement 11
standby 0 preempt
track 1 interface GigabitEthernet0/0 line-protocol
track 2 interface GigabitEthernet0/1 line-protocol
Cisco рекомендует не ставить hello таймер слишком маленьким (не меньше 1 сек), чтоб не грузить процессор. А hold таймер должен быть не менее 3*hello (возьмем 4), чтобы предотвратить флапание HSRP состояний. Так же таймеры должны быть обязательно одинаковыми на всех маршрутизаторах одной HSRP группы.
Спорить не будем
CUBE-1:
interface GigabitEthernet0/0
standby 0 timers 1 4
!hello 1 сек, hold 4 сек
interface GigabitEthernet0/1
standby 1 timers 1 4
CUBE-2:
interface GigabitEthernet0/0
standby 0 timers 1 4
interface GigabitEthernet0/1
standby 1 timers 1 4
interface GigabitEthernet0/0
standby 0 timers 1 4
!hello 1 сек, hold 4 сек
interface GigabitEthernet0/1
standby 1 timers 1 4
CUBE-2:
interface GigabitEthernet0/0
standby 0 timers 1 4
interface GigabitEthernet0/1
standby 1 timers 1 4
Делам так
CUBE-1:
interface GigabitEthernet0/0
standby delay minimum 30 reload 300
!Задаем задержку (в секундах) инициализации HSRP на интерфейсе после того как интерфейс включился (minimum, в сек) и после перезагрузки маршрутизатора (reload, в сек).
standby 0 preempt minimum 30 reload 300
!То же, только для preempt
interface GigabitEthernet0/1
standby delay minimum 30 reload 300
standby 1 preempt minimum 30 reload 300
interface GigabitEthernet0/0
standby delay minimum 30 reload 300
!Задаем задержку (в секундах) инициализации HSRP на интерфейсе после того как интерфейс включился (minimum, в сек) и после перезагрузки маршрутизатора (reload, в сек).
standby 0 preempt minimum 30 reload 300
!То же, только для preempt
interface GigabitEthernet0/1
standby delay minimum 30 reload 300
standby 1 preempt minimum 30 reload 300
С HSRP это все для нашей задачи.
Более подробно о настройке HSRP можно почитать здесь
Так как теперь у нас работает HSRP, указываем нашим CUBE использовать как адрес источника для SIP сообщений виртуальные адреса
dial-peer voice 100 voip
description to-SIP
voice-class sip bind control source-interface GigabitEthernet0/0
voice-class sip bind media source-interface GigabitEthernet0/0
!
dial-peer voice 200 voip
description to-CUCM
voice-class sip bind control source-interface GigabitEthernet0/1
voice-class sip bind media source-interface GigabitEthernet0/1
description to-SIP
voice-class sip bind control source-interface GigabitEthernet0/0
voice-class sip bind media source-interface GigabitEthernet0/0
!
dial-peer voice 200 voip
description to-CUCM
voice-class sip bind control source-interface GigabitEthernet0/1
voice-class sip bind media source-interface GigabitEthernet0/1
Теперь отказоустойчивость работает корректно. Если активный CUBE (или один из его интерфейсов) выйдет из строя, резервный подхватит его работу. Но если в момент switchover будут активные звонки, то они, к сожалению, сорвутся. Во избежание этого, настраиваем отказоустойчивость с сохранением состояния наших звонков (SSO).
Для начала нужно указать нашим CUBE, что у них теперь работает резервирование, и хорошо было бы им отслеживать и обмениваться информацией о звонках. Это для того, чтоб в момент Switchover резервный шлюз мог подхватить передачу RTP потоков текущих звонков.
Для начала нужно указать нашим CUBE, что у них теперь работает резервирование, и хорошо было бы им отслеживать и обмениваться информацией о звонках. Это для того, чтоб в момент Switchover резервный шлюз мог подхватить передачу RTP потоков текущих звонков.
redundancy
Дальше переходим к конфигурации собственно SSO. Так как информацией о сессиях обмениваются активный и резервный маршрутизаторы, здесь необходимо указать группу HSRP откуда их брать.
CUBE-1(config)# redundancy inter-device
!Включаем SSO
CUBE-1(config-red-interdevice)# scheme standby SB
!Указываем HSRP группу, которую мы раньше создавали
Для связи между активным и резервным маршрутизаторами необходимо настроить линию связи и транспорт (Inter Process Communication (IPC)).
!Используем эту команду для входа в режим конфигурации линии связи между активным и резервным устройствами.
CUBE-1(config-ipczone)#association 1
!Ассоциируем два наших устройства друг с другом. ID этого процесса должен быть одинаковым на обоих маршрутизаторах.
Замечание: в документации указано, что диапазон разрешенных association ID – 1..255, но…
CUBE-1 (config-ipczone)#association ?
<1-255> Association ID
CUBE-1 (config-ipczone)#association 3
% IPC association id 3 is not supported. Id 1 is only supported
CUBE-1(config-ipc-protocol-sctp)#no sh
!Включаем все это дело
CUBE-1(config-ipczone-assoc)#protocol sctp
!Входим в режим конфигурации Stream Control Transmission Protocol (SCTP), который будет использоваться для передачи SSO сообщений. Задаем его параметры
CUBE-1(config-ipc-protocol-sctp)#local-port 5000
!Локальный SCTP порт. Конкретного значения порта здесь нет, главное чтоб он был одинаковым на обоих наших устройствах.
CUBE-1(config-ipc-local-sctp)#local-ip 10.10.24.14
!локальный адрес для коммуникации с резервным устройством
CUBE-1(config-ipc-local-sctp)#exit
!В этом месте обязательно нужно выйти
CUBE-1(config-ipc-protocol-sctp)#remote-port 5000
!SCTP порт резервного маршрутизатора
CUBE-1(config-ipc-remote-sctp)#remote-ip 10.10.24.13
!его адрес
CUBE-1(config-ipc-remote-sctp)#end
В рекомендациях указано, что для этой коммуникации лучше использовать выделенный отдельный физический линк, который не используется для передачи данных.
На резервном все аналогично, только IP меняем:
CUBE-2(config)# redundancy inter-device
CUBE-2(config-red-interdevice)# scheme standby SB
На резервном все аналогично, только IP меняем:
CUBE-2(config)# redundancy inter-device
CUBE-2(config-red-interdevice)# scheme standby SB
CUBE-2(config-red-interdevice)# exit
CUBE-2(config)#ipc zone default
CUBE-2(config-ipczone)#association 1
CUBE-2(config-ipc-protocol-sctp)#no sh
CUBE-2(config-ipczone-assoc)#protocol sctp
CUBE-2(config-ipc-protocol-sctp)#local-port 5000
CUBE-2(config-ipc-local-sctp)#local-ip 10.10.24.13
CUBE-2(config-ipc-local-sctp)#exit
CUBE-2(config-ipc-protocol-sctp)#remote-port 5000
CUBE-2(config-ipc-remote-sctp)#remote-ip 10.10.24.14
CUBE-2(config-ipc-remote-sctp)#end
CUBE-2(config-ipczone)#association 1
CUBE-2(config-ipc-protocol-sctp)#no sh
CUBE-2(config-ipczone-assoc)#protocol sctp
CUBE-2(config-ipc-protocol-sctp)#local-port 5000
CUBE-2(config-ipc-local-sctp)#local-ip 10.10.24.13
CUBE-2(config-ipc-local-sctp)#exit
CUBE-2(config-ipc-protocol-sctp)#remote-port 5000
CUBE-2(config-ipc-remote-sctp)#remote-ip 10.10.24.14
CUBE-2(config-ipc-remote-sctp)#end
CUBE-1#show redundancy inter-device
Redundancy inter-device state: RF_INTERDEV_STATE_INIT
Pending Scheme: Standby (Will not take effect until next reload)
Pending Groupname: b2bha
Scheme: <NOT CONFIGURED>
Peer present: UNKNOWN
Security: Not configured
Redundancy inter-device state: RF_INTERDEV_STATE_INIT
Pending Scheme: Standby (Will not take effect until next reload)
Pending Groupname: b2bha
Scheme: <NOT CONFIGURED>
Peer present: UNKNOWN
Security: Not configured
После перезагрузки:
CUBE-1#show redundancy inter-device
Redundancy inter-device state: RF_INTERDEV_STATE_ACT
Scheme: Standby
Groupname: b2bha Group State: Active
Peer present: RF_INTERDEV_PEER_COMM
Security: Not configured
Во время failover звонки могут некорректно завершаться, что приводит к, так называемым, зависшим сессиям. Для того, чтобы их очистить мы можем использовать Media Inactivity Timer. Если Активный/Резервный маршрутизатор не получает RTP пакетов для определенного звонка в течении указанного времени, сессия этого звонка сбрасывается.
!Эта команда настраивает средний интервал между последовательными передачами отчетов RTCP для данного голосового сеанса, в милисекундах.
gateway
media-inactivity-criteria rtcp
!Указываем, что как параметр определения висит звонок или нет, выбираем RTCP отчеты. Этот вариант более надежен, по сравнению с детектированием RTP пакетов, так как во время звонка бывают моменты когда одна сторона (или даже обе) не передают RTP пакетов.
timer receive-rtcp 10
!Множитель для интервала времени, заданного в ip rtcp report interval
1. Если звонок уже установлен и происходит switchover, передача RTP пакетов этого звонка переходит на резервный CUBE практически незаметно для абонентов. Заметна лишь только небольшая пауза.
2. Этот же звонок (который перешел на резервный CUBE во время switchover) можно без проблем поставить на удержание, сделать ему трансфер и т.п. Сигнализация сохраняется, так как я использую IOS 15.4
3. Если звонок еще не установился (еще не взяли трубку с другой стороны), то во время switchover он оборвется.
CUBE-1#show redundancy states
my state = 13 -ACTIVE
peer state = 8 -STANDBY HOT
Mode = Duplex
Unit ID = 0
…
CUBE-2#sh redundancy states
my state = 8 -STANDBY HOT
peer state = 13 -ACTIVE
Mode = Duplex
Unit ID = 0
…
P indicates configured to preempt.
|
Interface Grp Pri P State Active Standby Virtual IP
Gi0/1 1 110 P Active local 10.10.24.13 10.10.24.1
Gi0/0 0 110 P Active local 10.10.25.13 10.10.25.1
CUBE-2#sh standby brief
P indicates configured to preempt.
|
Interface Grp Pri P State Active Standby Virtual IP
Gi0/1 1 110 P Standby 10.10.24.14 local 10.10.24.1
Gi0/0 0 110 P Standby 10.10.25.14 local 10.10.25.1
Теперь давайте протестируем.
1. Идем на активный CUBE, смотрим что у нас сейчас один звонок установлен через него
CUBE-1#sh voip rtp connections
VoIP RTP active connections :
No. CallId dstCallId LocalRTP RmtRTP LocalIP RemoteIP
1 1011 1012 16384 22824 172.18.46.68 172.18.46.65
2 1012 1011 16386 23118 172.18.46.82 172.18.46.84
Found 2 active RTP connections
Смотрим, что на резервном
CUBE-2#sh voip rtp connections
VoIP RTP active connections :
No. CallId dstCallId LocalRTP RmtRTP LocalIP RemoteIP
1 1011 1012 16384 22824 172.18.46.68 172.18.46.65
2 1012 1011 16386 23118 172.18.46.82 172.18.46.84
Found 2 active RTP connections
Данные о RTP сессии синхронизируются
2. Выключаем один из интерфейсов на активном маршрутизаторе или перезагружаем его. И смотрим, что там на резервном
CUBE-2#sh voip rtp connections
VoIP RTP active connections :
No. CallId dstCallId LocalRTP RmtRTP LocalIP RemoteIP
1 1011 1012 16384 22824 172.18.46.68 172.18.46.65
2 1012 1011 16386 23118 172.18.46.82 172.18.46.84
Found 2 active RTP connections
Сессия сохранилась, все как ожидали.
CUBE-1(config)#int g0/0
CUBE-1(config-if)#shutdown
*Oct 3 09:28:47.535: %HSRP-5-STATECHANGE: GigabitEthernet0/0 Grp 0 state Active -> Init
*Oct 3 09:28:48.603: %HSRP-5-STATECHANGE: GigabitEthernet0/1 Grp 1 state Active -> Speak
*Oct 3 09:28:48.603: %RF-5-RF_RELOAD: Self reload. Reason: Not in correct state for becoming Standby
*Oct 3 09:28:48.603: %RF_INTERDEV-4-RELOAD: % RF induced self-reload. my state = ACTIVE peer state = STANDBY HOT
Он перезагружается, хотя мы просто выключили интерфейс! Но в случае использования SSO, изменение роли устройства (активный/резервный) сопровождается его перезагрузкой. Вот так это работает. Из разряда – это не баг, это фича )).
Комментариев нет:
Отправить комментарий