Протоколы отказоустойчивости шлюза: проблема единой точки отказа default gateway и принцип работы виртуального IP-адреса.
Какую проблему решают протоколы FHRP?
Чем HSRP отличается от VRRP?
Почему в IPv4 проблема отказа шлюза особенно критична?
Какой FHRP-протокол поддерживает балансировку нагрузки между шлюзами?
Как концепция FHRP обеспечивает прозрачность переключения для клиентов?
Наконец, после того, как мы с вами разобрали, как работает Spanning Tree, как работает агрегация, мы смогли построить красивую, надёжную, отказоустойчивую сеть, которая основана на стандарте Ethernet. Дальше возникает вопрос, а что с этой сетью делать? Скорее всего, мы её строили для того, чтобы у нас работала какая-то внутренняя сеть в пределах нашего предприятия. И если вся наша сеть расположена в одном VLAN, то у нас всё хорошо, всё надёжно работает, всё отказоустойчиво. Но если у нас есть несколько VLAN, между которыми требуется выполнять маршрутизацию, или необходимо осуществлять выход в интернет, а именно это, скорее всего, будет нужно, если у вас достаточно большая сеть, то вам потребуется обеспечить стык между маршрутизацией и коммутацией, между коммутируемой сетью на основе Ethernet и маршрутизируемой сетью на основе IP. Этот процесс мы сейчас с вами и рассмотрим. Что делать, если нам необходимо стыковать IP и Ethernet?
В чём смысл? Если у нас есть какой-то узел, у этого узла для работы IP назначается IP-адрес, назначается маска, назначаются DNS-сервер, какие-то настройки, которые нужны для того, чтобы работал IP. И среди прочего назначается так называемый шлюз по умолчанию. И если у нас есть какая-то сеть, то шлюз по умолчанию для каждого конкретного узла будет только один. Вы можете гипотетически сделать с помощью, например, протокола DHCP настройку нескольких разных шлюзов, но при этом работать всё равно будет только один. Если вы в DHCP скажете, давайте использовать в качестве шлюза 10.0.0.1, 10.0.0.2 и так далее, то всё равно по факту он выберет сначала первый IP-адрес и будет использовать постоянно только его. Он его зарезолвит с помощью ARP, получит его MAC-адрес, и дальше будет отправлять все пакеты на этот самый MAC-адрес до тех пор, пока этот MAC не протухнет в кэше ARP.
После чего он снова его продлит, зарезолвит с помощью ARP и снова будет пользоваться дальше постоянно им. Если вдруг в какой-то момент обладатель этого IP-адреса 10.0.0.1 выйдет из строя, трафик через него ходить не будет, потому что в Ethernet у нас никакой обратной связи нет. Если трафик не может пройти до MAC-адреса 1, это проблема отправителя этого кадра, но отправитель про падение конечного получателя никак не узнает. Конечно же, если вы назначили несколько IP-адресов, вы можете дождаться, пока MAC-адрес 1 протухнет в кэше ARP, снова его зарезолвить, понять, что он не резолвится, и по списку пойти дальше, попытаться зарезолвить 10.0.0.2 в какой-то другой MAC-адрес и дальше пользоваться в качестве шлюза по умолчанию именно им. Потому что на самом деле мы не пользуемся IP-адресами шлюзов. Мы их резолвим в MAC-адреса, и дальше трафик до тех узлов, которые не находятся с нами в одном канале, до каких-то других сетей, мы посылаем через канальный адрес шлюза.
И получается, что до тех пор, пока в кэше ARP у нас MAC-адрес шлюза живой, мы никоим образом не можем узнать, что он больше не живой. В IPv4 штатных механизмов отказоустойчивости, кроме такого достаточно костыльного механизма, основанного на работе ARP, нет. И если у вас шлюз выходит из строя, то вы ничего с этим сделать не сможете. До тех пор, пока у вас прописан IP-адрес 10.0.0.1, вы будете посылать трафик на MAC-адрес, который, вы верите, соответствует узлу 10.0.0.1. Что будет, если вы попытаетесь сказать: окей, мы можем поставить два, например, multilayer switch, два одинаково хороших роутера в сеть. Но в любом случае проблема будет с тем, что вы не можете на них назначить одинаковый IP-адрес. Если вы скажете, что у нас будет 10.0.0.1 и на втором свитче тоже, то пока они оба будут жить одновременно, ARP-ами они будут отвечать оба своими MAC-адресами.
Один будет говорить, у меня MAC-адрес один, другой говорит, у меня MAC-адрес другой. В кэше ARP у нас всё равно будет оставаться только один MAC-адрес. И получится, что в такой ситуации всё равно мы будем пользоваться только одним MAC-ом до тех пор, пока он не протухнет. И если вдруг у нас в кэше ARP срок жизни записи достаточно длинный, например, 4 часа, то в течение 4 часов после последнего резолва вы даже не пытаетесь продлять эту запись в кэше ARP. Вы будете весь трафик посылать на MAC-адрес обладателя сбойного узла, сбойного сервиса. И параллельно будут между собой эти двое ругаться, будут говорить, у нас конфликт. Ничего хорошего не будет, если вы попытаетесь назначить один и тот же IP-адрес на два разных узла. Что будет, если вы попытаетесь MAC-адрес назначить одинаковый? MAC-1 здесь у нас и MAC-адрес-1 здесь.
У нас будет этот switch сходить с ума. Он будет говорить, у меня MAC-flapping, у меня один и тот же MAC-адрес то здесь виден, то здесь, то снова здесь, то снова здесь. И он будет заваливать вас сообщениями в консоль, что один и тот же MAC-адрес виден за двумя разными портами. Периодически кадры из-под этого MAC приходят на двух разных портах. И кадры, которые будут отправляться на этот MAC-адрес, они будут постоянно идти на один какой-то порт. Но сначала на один, потом на другой, потом снова на один, потом снова на другой. В этой ситуации вы будете всё равно испытывать проблемы, потому что если вдруг вы захотите здесь включить, допустим, NAT, то у вас часть пакетов будет проходить через NAT здесь, часть пакетов будет проходить через NAT здесь. В этом случае трансляции, которые необходимо синхронизировать на этих двух узлах, вы синхронизировать никак не сможете. Поэтому у вас какие-то пакеты, которые вы отправляете от обычного абонента наружу, которые пройдут через один роутер, они будут отправляться с одного и того же порта, с порта 1, 2, 3, 4. Но здесь они будут транслироваться в порт 2, 3, 4, 5,
а здесь они будут транслироваться в порт 3, 4, 5, 6. Узлы имеют право при выполнении трансляции сетевых адресов с перегрузкой, то есть PAT, изменять порты источника. Они вполне могут менять порты источника. Поэтому на внешний узел, который будет получать такие пакеты, будут приходить в рамках одной и той же сессии пакеты с различающимися портами. Естественно, ему это не понравится, он будет постоянно RST-ами кидать, что вы мне такое присылаете. Короче говоря, что бы вы ни пытались сделать, проблема с отказоустойчивостью шлюза по умолчанию есть. Штатными средствами она решается очень тяжело, либо не решается вовсе. Что можно сделать в такой ситуации? Можно сказать: мы не можем назначить на два роутера одинаковые IP-адреса, у нас будет конфликт IP-адресов. Мы не можем назначить одинаковые MAC-адреса, у нас будет конфликт MAC-адресов. Но мы можем, используя некий служебный протокол,
договориться о том, кто использует определённый IP-адрес, определённый MAC-адрес в данный конкретный момент. Мы можем придумать роль виртуального роутера, на который назначить виртуальный IP-адрес 10.0.0.1, который будет шлюзом, на который можно назначить MAC-адрес, который будет использоваться в качестве шлюза. И нужно будет договориться, кто конкретно отвечает ARP-запросами на вопрос, у кого из вас IP-адрес 10.0.0.1. В этом случае два или больше роутеров, которые мы объединяем в одну группу, они будут договариваться, кто конкретно обслуживает запросы на этот IP-адрес, на этот MAC в конкретный момент времени. Подобное поведение будет свойственно протоколам, которые имеют общее название FHRP, First Hop Redundancy Protocol. Это семейство протоколов, которые решают задачу, как нескольким роутерам обслуживать пользователей в одной сети и обеспечить отказоустойчивость шлюза по умолчанию. Два роутера между собой договариваются,
кто конкретно из них обладатель этого виртуального IP-адреса, виртуального MAC-а. Если вдруг какой-то один роутер выходит из строя, никаких проблем, трафик начинает обслуживаться вторым. Этих самых протоколов FHRP несколько штук. Есть стандартный протокол VRRP, Virtual Router Redundancy Protocol. Он не цисковский, но он очень похож на фирменный цисковский протокол HSRP, Hot Standby Router Protocol. Это действительно протоколы, сходные до смешения, они очень похожи друг на друга. И поэтому Cisco, которая в своё время успела запатентовать свой протокол, она постоянно не то чтобы предъявляет претензии, но намекает на то, что может предъявить их в любой момент тому, кто попытается этот самый VRRP реализовать. Поэтому VRRP не поддерживается абсолютно всеми вендорами, потому что некоторые вендоры боятся ссориться с Cisco. Некоторые вендоры поддерживают его,
некоторые, опасаясь, не поддерживают. HSRP, как уже говорилось, фирменный цисковский протокол. И GLBP тоже фирменный цисковский протокол, но если HSRP протокол лицензируемый, то есть любой желающий может у себя реализовать HSRP, если захочет, только он должен заплатить Cisco, то GLBP — это фирменный цискоспецифичный протокол, его даже за деньги никакой другой вендор у себя реализовать не сможет. GLBP — очень интересный протокол, обладает рядом очень интересных особенностей, но в силу то ли жадности Cisco, то ли слишком специфичной схемы работы, его по факту в продакшене встретить можно очень редко. Бывают и другие протоколы. Кроме VRRP, HSRP, GLBP, например, есть экстримовский протокол ESRP. Есть аваевский протокол, который на самом деле ещё и про транки тоже, и про FHRP, и про всё на свете — RSMLT.
Короче говоря, здесь бардак. Каждый вендор делает что-то своё для того, чтобы решить эту задачу. Естественно, индустрии такой подход не очень нравится, когда у нас есть 14 разных протоколов, которые решают одну и ту же задачу. И у каждого из них есть какие-то свои преимущества и свои недостатки. Поэтому в какой-то момент индустрия попыталась скоординироваться и придумала протокол, который был бы стандартным, который был бы избавлен от патентных проблем, использовал бы механизмы, не похожие на всё то, что существует. И придумали протокол, который называется CARP, Common Address Redundancy Protocol. Но в этот момент стало немножко не по себе тем, кто сказал: ребят, у нас есть RFC на VRRP, стандартный протокол. У нас есть RFC на HSRP, тоже формально стандартный протокол, пусть и за деньги доступный. Мы не хотим ещё добавлять дополнительных стандартных протоколов, которые решают ту же самую задачу. У нас есть стек стандартных протоколов, и чем он более компактный, тем лучше.
Незачем плодить сущности без необходимости. Поэтому, несмотря на то, что протокол CARP во всём хорош, он не стандартизирован именно в силу того, что уже были протоколы, которые решают такую задачу и которые были стандартизированы. Поэтому никакого стандартного механизма для решения задачи отказоустойчивости шлюза по умолчанию по факту нет. Вы всегда будете ограничены по факту только решениями, которые доступны от вашего любимого вендора. С некоторой ненулевой вероятностью, если вы работаете с вендором, например, Cisco, вам будут доступны VRRP, HSRP, GLBP. Если вы работаете с каким-то другим вендором, вам могут быть доступны какие-то другие комбинации этих протоколов. Нет какого-то единого универсального протокола, который поддерживался бы всеми, типа как 802.1Q или LACP. Такого нет. Давайте посмотрим на то, как будут устроены все эти протоколы в отдельности. Начнём мы с HSRP,
как образцово-показательного цисковского протокола, с которого, можно сказать, всё началось. Продолжим мы VRRP, который его брат-близнец. И наконец чуть-чуть проговорим про GLBP.