Обновление контроллеров Cisco APIC.  Что же может пойти не так?

от автора

По моему опыту, все обновления Cisco ACI, начиная с мажорной версии 4 и далее, ставили только одну серьезную задачу — найти достаточно чая, чтобы пить его на протяжении обновления фабрики. Кроме шуток, процесс построен очень удачно, и справиться с ним может даже сотрудник с junior-подготовкой, естественно, если заранее ознакомится с Release notes и рекомендациями вендора. Но в этот раз все пошло не по плану.

На обновление фабрики у нас ушло несколько бессонных суток, в течение которых мы пережили частичный выход из строя кластера, выход из строя RAID контроллера одного из серверов и, потенциально, полный wipe топологии… Но все закончилось хорошо, мы обновили фабрику, решили проблему заказчика, а самое главное – получили по островку седых волос бесценный опыт. 

Меня зовут Сергей Балдаков, в компании К2Тех наша команда  занимается комплексной технической поддержкой мультивендорной инфраструктуры. В том числе производителей, ушедших из России. Надеюсь, наш опыт поможет инженерам, которые обслуживают оборудование без поддержки вендора и позволит избежать граблей, которые мы с лихвой насобирали в этой истории. 

Часто слышу от коллег и заказчиков, что Cisco ACI для многих является сложным из-за его архитектуры и иного подхода к абстракции сетевой топологии по сравнению с классическими решениями для дата-центров.  Действительно, на раннем этапе, когда продукт только делал первые шаги от простого  управления по API к полноценной модели API-driven, возникло  множество вопросов и  к функционалу, и к реализации некоторых процессов.  Сейчас, по моему мнению, Cisco ACI  сильно опережает существующие решения на рынке и позволяет значительно снижать OpEX на содержание сети дата-центра.  

Итак, нам прилетела на первый взгляд довольно рутинная задача по обновлению фабрики Cisco ACI. Процесс не затрагивал мажорную версию (5.2.3g — 5.3.2с), а также не требовалось обновление Multisite оркестратора для этого обновления. Несмотря на то, что работы по обновлению коммутаторов при соблюдении рекомендаций производителя и отсутствии orphan-портов на коммутаторах проходят без прерывания сервисов, заказчик решил провести их в ночное окно (как в воду глядел). 

Коротко о построении самого процесса

Логика обновления Cisco ACI следующая: 

Сначала обновляется группа APIC контроллеров, которая управляет работой данной фабрики и отвечает за ее control plane. Затем –  коммутаторы, как правило, в два этапа:  сначала нечетные, затем четные . Такой порядок позволяет избежать случая, когда оба коммутатора, составляющие VPC-пару, уходят в перезагрузку.

Этот процесс не быстрый, но при должной подготовке и выполнении инструкции вендора проходит хоть и медленно, но беспроблемно.

В нашем случае работы были поделены на 4 этапа:

— 0бновление APIC на Site1;

— обновление коммутаторов на Site1; 

— обновление APIC на Site2; 

— обновление коммутаторов на Site2.

Работы по первым двум пунктам прошли без проблем, и Site1 обновился ожидаемо без эксцессов. А дальше началось интересное. 

Не видишь APIC ? А он есть! 

Образы предзагружены на контроллеры, Release notes прочитаны, pre-upgrade script выполнен, чай налит. Action.

Первый звоночек прозвенел, когда после обновления APIC1 на втором сайте контроллер  загрузился, однако не отобразился как полноценный член кластера. Соответственно, остальные члены кластера не спешили продолжать обновление, так как не видели первый контроллер в состоянии Fully Fit. В итоге кластер завис вот в таком состоянии: 

При этом сам контроллер даже не отображался в списках.

Где бессильно GUI, всегда на выручку приходит CLI. Я зашел на контроллер APIC1 и попытался понять, что же с ним не так. Выяснилось, что он загрузился, запустил службы, однако контроллер  не видел inband vlan. Вернее, он не был на нем создан.

Как должен выглядеть нормальный APIC:  

DC2-APIC-02# ifconfig | grep bond0.

bond0: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST>  mtu 1500

bond0.245: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1496

bond0.4093: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1496

Как выглядел APIC у меня: 

DC2-APIC-01# ifconfig | grep bond0.

bond0: flags=5187<UP,BROADCAST,RUNNING,MASTER,MULTICAST>  mtu 1500

bond0.4093: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

Что вызвало вопрос: по какой причине APIC1 отказался поднимать inband vlan и быть частью существующего кластера? Первая мысль, которая пришла в голову — сравнить, как кластер видят «здоровый» контроллер и контроллер, который не подключается к нему.

Вот вывод со «здорового» контроллера

DC2-APIC-02# avread Cluster: ------------------------------------------------------------------------- fabricDomainName        ACI_Fabric_2 discoveryMode           PERMISSIVE clusterSize             3 version                 apic-5.3(2c) drrMode                 OFF operSize                3  APICs: -------------------------------------------------------------------------                     APIC 1                  APIC 2                  APIC 3 version                                   5.2(3g)                 5.2(3g) address           0.0.0.0                 X.X.0.2                X.X.0.3 oobAddress        X.X.240.18/26           X.X.240.19/26        X.X.240.212/26 routableAddress   0.0.0.0                 0.0.0.0                 0.0.0.0 tepAddress        0.0.0.0                 X.X.0.0/16             X.X.0.0/16 podId             0                       1                       1 chassisId          -.-                    762d6e7a-.-f7a8b0d2     1a9bca22-.-ab6c1ff8 cntrlSbst_serial  (ERASED,)               (APPROVED,WZPXXXXXXX2)  (APPROVED,WZPXXXXXXX3) active            NO (zeroTime)           YES                     YES flags             c--s                    cra-                    cra- health            0                       255                     255  STANDBY APICs: -------------------------------------------------------------------------                     APIC 4                  APIC 21 version           5.2(3g) address           X.X.0.4                0.0.0.0 oobAddress        X.X.240.218/26       X.X.240.218/26 routableAddress   0.0.0.0                 0.0.0.0 tepAddress        X.X.0.0/16             0.0.0.0 podId             1                       0 chassisId         1c3a0692-.-dbe660aa      -.- cntrlSbst_serial  (APPROVED,WZPXXXXXXX4)  (ERASED,) active            YES                     NO flags             cra-                    ---- health            online                  1

А вот как видит кластер контроллер обновленный:

DC2-APIC-01# avread Appliance Director is not running locally hence below av information could be stale! Cluster: ------------------------------------------------------------------------- operSize                1 clusterSize             3 fabricDomainName        ACI_Fabric_2 version                 5.3(2c) discoveryMode           PERMISSIVE drrMode                 OFF kafkaMode               OFF  APICs: -------------------------------------------------------------------------                     APIC 1 version           5.3(2c) address           X.X.0.1 oobAddress        X.X.240.18/26 routableAddress   0.0.0.0 tepAddress        X.X.0.0/16 podId             1 chassisId         688ad2ae-.-bae24bee cntrlSbst_serial  (APPROVED,123456789) active            YES flags             cra- health            1

Больше всего смутил тот факт, что в группе контроллеров, на которых работала фабрика в тот момент, версия кластера уже была сменена на apic-5.3(2c), при этом контроллеры в нем находились версии 5.2(3g).

А так же серийник контроллера APIC1, который жил сам по себе в отрыве от кластера. Не смотря на то, что в данном кейсе серийные номера изменены, в выводе действительно была последовательность от 1 до 9 в поле серийного номера. Что явно намекало на некорректную работу.

После продолжительных обсуждений было принято следующее решение:  версию кластера, который сейчас управляет фабрикой – это APIC2 и APIC3, – установить равной — 5.2(3g) в соответствии с текущими действующими прошивками контроллера, благо для этого не нужны root права доступа. 

Процедура изменения версии контроллера в базе объектов делается стандартными инструментами APIC:

DC2-APIC-02# bash DC2-APIC-02> cd /mit/uni/controller/ctrlrfwpol DC2-APIC-02> moset version '5.2(3g)' DC2-APIC-02> moconfig commit

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

В этот момент состояние кластера было следующим при проверке из GUI: 

Версия кластера изменилась успешно, однако проблему это не решило, тем не менее натолкнуло на мысль. В выводах APIC2 и APIC3 заметил разницу в параметре cntrlSbst serial, один сервер считал, что серийник в кластере удален, что соответствует действительности, второй –  что серийник не определен, что в нашем случае неверно. К тому же это хорошо билось с тем фактом, что серийник ноды APIC1, которая жила сама по себе,  отображается в виде 123456789.

DC2-APIC-02# avread Cluster: ------------------------------------------------------------------------- fabricDomainName        ACI_Fabric_2 discoveryMode           PERMISSIVE clusterSize             3 version                 apic-5.2(3g) drrMode                 OFF operSize                3  APICs: -------------------------------------------------------------------------                     APIC 1                  APIC 2                  APIC 3 version                                   5.2(3g)                 5.2(3g) address           0.0.0.0                 X.X.0.2                X.X.0.3 oobAddress        X.X.240.18/26       X.X.240.19/26        X.X.240.212/26 routableAddress   0.0.0.0                 0.0.0.0                 0.0.0.0 tepAddress        0.0.0.0                 X.X.0.0/16             X.X.0.0/16 podId             0                       1                       1 chassisId          -.-                    762d6e7a-.-f7a8b0d2     1a9bca22-.-ab6c1ff8 cntrlSbst_serial  (ERASED,)               (APPROVED,WZPXXXXXXX2)  (APPROVED,WZPXXXXXXX3) active            NO (zeroTime)           YES                     YES flags             c--s                    cra-                    cra- health            0                       255                     255
DC3-APIC-01# avread Cluster: ------------------------------------------------------------------------- fabricDomainName        ACI_Fabric_2 discoveryMode           PERMISSIVE clusterSize             3 version                 apic-5.2(3g) drrMode                 OFF operSize                3  APICs: -------------------------------------------------------------------------                     APIC 1                  APIC 2                  APIC 3 version                                   5.2(3g)                 5.2(3g) address           0.0.0.0                 X.X.0.2                X.X.0.3 oobAddress        X.X.240.18/26       X.X.240.19/26        X.X.240.212/26 routableAddress   0.0.0.0                 0.0.0.0                 0.0.0.0 tepAddress        0.0.0.0                 X.X.0.0/16             X.X.0.0/16 podId             0                       1                       1 chassisId          -.-                    762d6e7a-.-f7a8b0d2     1a9bca22-.-ab6c1ff8 cntrlSbst_serial  (UNDEFINED,)            (APPROVED,WZPXXXXXXX2)  (APPROVED,WZPXXXXXXX3) active            NO (zeroTime)           YES                     YES flags             ---s                    cra-                    cra- health            1                       255                     255

Решили проверить, в каком состоянии находятся ноды в представлении Managed objects через запрос moquery

DC2-APIC-02# moquery -c infraWiNode Total Objects shown: 6  # infra.WiNode id             : 1 addr           : 0.0.0.0 adminSt        : out-of-service annotation     : apicMode       : active chassis        : childAction    : cntrlSbstState : erased dn             : topology/pod-1/node-2/av/node-1 extMngdBy      : failoverStatus : completed health         : never-known lcOwn          : local mbSn           : modTs          : 2024-10-16T18:37:03.637+03:00 monPolDn       : uni/fabric/monfab-default mutnTs         : zerotime name           : nameAlias      : nodeName       : DC2-APIC-01 operSt         : unregistered podId          : 0 rn             : node-1 routableIpAddr : 0.0.0.0 status         : targetMbSn     : WZPXXXXXXX4 uid            : 0 userdom        : all   DC3-APIC-01# moquery -c infraWiNode Total Objects shown: 6  # infra.WiNode id             : 1 addr           : 0.0.0.0 adminSt        : out-of-service annotation     : apicMode       : active chassis        : childAction    : cntrlSbstState : undefined dn             : topology/pod-1/node-3/av/node-1 extMngdBy      : failoverStatus : completed health         : never-known lcOwn          : local mbSn           : modTs          : 2024-10-16T18:36:25.828+03:00 monPolDn       : uni/fabric/monfab-default mutnTs         : zerotime name           : nameAlias      : nodeName       : DC2-APIC-01 operSt         : unregistered podId          : 0 rn             : node-1 routableIpAddr : 0.0.0.0 status         : targetMbSn     : WZPXXXXXXX4 uid            : 0 userdom        : all

И тут стала понятной проблема, из-за которой  сервер не принимался самим кластером.   По неизвестной причине (выяснить её в последствии так и не удалось, поскольку приоритетом было восстановление работоспособности, и диагностические данные потерлись при дальнейших работах) в поле targetMbSN прописался серийник standby контроллера, который все это время находился в этом же кластере. Соответственно, текущие ноды никак не могли принять в кластер контроллер, серийный номер которого не соответствует  указанному в инфраструктурном MO.

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

Что предстояло сделать? Во-первых, разобраться, как удалить залипший серийник из MO APIC2 и APIC3. Во-вторых, для надежности сделать Reimage контроллера APIC1, чтобы откатить его на версию  5.2(3g) и вернуть кластер в состояние «до обновления» – стандартной процедуры отката в данном случае не предусмотрено, только полный Reimage контроллера.

Unforeseen Consequences 

После нескольких попыток поискать встроенные способы осуществить процедуру корректировки MO было решено  попробовать воспользоваться широкими возможностями API Cisco ACI и использовать CURL.

В итоге у нас получилась следующая последовательность для контроллеров 2 и 3: 

DC2-APIC-02# bash DC2-APIC-02> echo '<infraWiNode id="1" targetMbSn="" status="modified"/>' > node1.xml DC2-APIC-02> icurl -gX POST http://localhost:7777/api/node/mo/topology/pod-1/node-2/av.xml -d @node1.xml
DC2-APIC-02# bash DC2-APIC-02> echo '<infraWiNode id="1" targetMbSn="" status="modified"/>' > node1.xml DC2-APIC-02> icurl -gX POST http://localhost:7777/api/node/mo/topology/pod-1/node-3/av.xml -d @node1.xml

Также был успешно выполнен Reimage APIC1, который принес неутешительные результаты – RAID контроллер “приуныл” от всего этого и вышел из чата после перезагрузки сервера. Судя по криво прошедшему обновлению, предпосылки к этому уже были, хоть и без явных алертов.

А на этот случай у нас есть багор (с)

Хорошо, что заказчик не пренебрег рекомендациями вендора и использовал в своей инфраструктуре standby APIC контроллер. Таким образом мы смогли сэкономить время и не отправлять подменный контроллер из ЗИП. Быстро переобувшись, мы сделали Decomission standby APIC сервера, провели Clean Wipe и настроили его в качестве APIC1 с теми же системными настройками. А заказчик тем временем передал нашей  логистической службе неисправный APIC  для доставки его из дата-центра к нам в лабораторию для диагностики . Мы сделали Decomission standby APIC сервера. Провели Clean Wipe и перенастроили его в качестве APIC1 с теми же системными настройками. Ирония в том, что при таком сценарии  могли бы вовсе не менять серийный номер этого APIC ранее.

Кластер собрался, мы получили замечательную картинку: 

Однако, как выяснилось, я недооценивал инженеров Cisco, разрабатывающих Redundancy системы обновления контроллеров.

Спустя 5 минут после всеобщего ликования и радости от того, что практически бессонные сутки позади, пришла отбивка от системы мониторига заказчика о том, что недоступен APIC2.

Зайдя в GUI, я увидел неприглядную картину:  APIC2 – Unavailible, а Health state двух живых находится в состоянии Data layer partitialy diverged. Здесь скриншот, к сожалению, не сохранился поскольку напряжение всех тканей тела, способных к сокращению, достигло пиковых значений и было уже не до истории.

В этот момент я почувствовал себя примерно как этот велосипедист на картинке и приготовился писать заявление на увольнение по собственному, так как потеря трех APIC серверов грозила полной потерей фабрики из 40 с лишним коммутаторов.

 

После минутного ступора мозг начал лихорадочно анализировать происходящее, и тут пришло понимание того, что скрипт обновления все время наших манипуляций спал, и не отваливался по таймауту, а терпеливо ждал, когда же у него появится первый контроллер и он наконец-то сможет продолжить заниматься обновлением. Что, собственно, и произошло: как только скрипт увидел нормальный здоровый первый контроллер, он начал обновлять второй и затем третий. И его мало волновало, что версия кластера в MO была изменена на 5.2(3g).

Спустя примерно 40 минут, и обновление APIC2 и APIC3 мы стали наблюдать следующую неприглядную картину. Кластер с версией 5.2(3g) имел два контроллера с более высокой версией, и один со старой. При этом они в GUI периодически перемаргивались сообщениями о том, что Data layer patitially diverged. Это говорило о том, что APIC никак не могут нормально раскидать полностью шарды между собой.

DC2-APIC-02# avread Cluster: ------------------------------------------------------------------------- fabricDomainName        ACI_Fabric_2 discoveryMode           PERMISSIVE clusterSize             3 version                 apic-5.2(3g) drrMode                 OFF operSize                3  APICs: -------------------------------------------------------------------------                     APIC 1                  APIC 2                  APIC 3 version           5.2(3g)                 5.3(2с)                 5.3(2с) address           X.X.0.1                X.X.0.2                X.X.0.3 oobAddress        X.X.240.218/26         X.X.240.19/26        X.X.240.212/26 routableAddress   0.0.0.0                 0.0.0.0                 0.0.0.0 tepAddress        X.X.0.0/16             X.X.0.0/16             X.X.0.0/16 podId             1                       1                       1 chassisId         6a5264dc-.-61f22fc9     762d6e7a-.-f7a8b0d2     1a9bca22-.-ab6c1ff8 cntrlSbst_serial  (APPROVED,WZPXXXXXXX4) (APPROVED,WZPXXXXXXX2)  (APPROVED,WZPXXXXXXX3) active            YES                     YES                     YES flags             cra-                    cra-                    cra- health            255                      255                     255  STANDBY APICs: -------------------------------------------------------------------------                     APIC 4                  APIC 21 version            address           0.0.0.0                 0.0.0.0 oobAddress        X.X.240.218/26       X.X.240.218/26 routableAddress   0.0.0.0                 0.0.0.0 tepAddress        0.0.0.0                 0.0.0.0 podId             1                       0 chassisId         -.-                     -.- cntrlSbst_serial  (ERASED,)       (ERASED,) active            NO                      NO flags             ----                    ----

Свет в конце тоннеля 

После наших приключений ранее дальнейшая задача уже не казалась невыполнимой.

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

Схема представлялась следующей: 

— делаем decomission APIC1;

— принудительно меняем версию кластера на APIC2 и APIC3, как уже делали ранее в данном кейсе;

— отключаем порты в сторону APIC1 (скорее предосторожность, чтобы он не инициировал попытки Discovery фабрики по LLDP;

— сбрасываем APIC1 и заводим его как абсолютно левый контроллер под левым именем, не подключая к фабрике;

— обновляем APIC1 на целевую версию – 5.3(2c);

— сбрасываем ещё раз;

— настраиваем как корректный APIC1;

— включаем порты на Leaf коммутаторе в его сторону;

— делаем comission;

— PROFIT!

Причем, что интересно, он прекрасно обновился через GUI как кластер из одного контроллера. После того как мы выполнили обозначенные выше пункты плана, наконец-то мы получили нормальный кластер.

Ниже представлен вывод полностью здорового кластера контроллеров, с уже восстановленным Standby. Проблемный же сервер привезли в лабораторию. В нем была выявлена аппаратная неисправность RAID контроллера, после чего его заменили и вернули сервер в работу в качестве Standby в этой же фабрике.

DC2-APIC-01# avread  Cluster:  -------------------------------------------------------------------------  operSize                3  clusterSize             3  fabricDomainName        ACI_Fabric_2  version                 apic-5.3(2c)  discoveryMode           PERMISSIVE  drrMode                 OFF  kafkaMode               ON     APICs:  -------------------------------------------------------------------------                      APIC 1                  APIC 2                  APIC 3  version           5.3(2c)                 5.3(2c)                 5.3(2c)  address           X.X.0.1                X.X.0.2                X.X.0.3  oobAddress        X.X.240.218/26          X.X.240.19/26        X.X.240.212/26  routableAddress   0.0.0.0                 0.0.0.0                 0.0.0.0  tepAddress        X.X.0.0/16             X.X.0.0/16             X.X.0.0/16  podId             1                       1                       1  chassisId         6a5264dc-.-61f22fc9     762d6e7a-.-f7a8b0d2     1a9bca22-.-ab6c1ff8  cntrlSbst_serial  (APPROVED,WZPXXXXXXX4)  (APPROVED,WZPXXXXXXX2)  (APPROVED,WZPXXXXXXX3)  active            YES                     YES                     YES  flags             cra-                    cra-                    cra-  health            255                     255                     255     STANDBY APICs:  -------------------------------------------------------------------------                      APIC 4                  APIC 21  version           5.3(2c)  address           X.X.0.4                0.0.0.0  oobAddress        X.X.240.18/26        0.0.0.0  routableAddress   0.0.0.0                 0.0.0.0  tepAddress        X.X.0.0/16             0.0.0.0  podId             1                       0  chassisId         d6d5dce4-.-8bd9fd99      -.-  cntrlSbst_serial  (APPROVED,WZPXXXXXXX1)  (UNDEFINED,)  active            YES                     NO  flags             cra-                    ----  health            online                  0

Выводы

Что оказалось важным? Всегда при обновлении нужно быть готовым к тому, что что-то пойдет не по плану. Например, выйдет из строя RAID контроллер. Естественно, все предусмотреть невозможно, но моральная готовность тоже важна. В данном случае нас очень выручило наличие standby контроллера у заказчика уже на площадке. Мы сэкономили время на логистику и не пришлось тратить несколько часов на доставку сервера из нашего ЗИП.

Что я  сделал бы по-другому:

  1. Не стал бы всеми силами пытаться восстановить APIC1 до изначального состояния. Скорее всего, правильным решением было бы сразу использовать APIC-standby как замену, и потом уже разбираться с APIC1, на месте/в лабе.

  2. Теперь я знаю, что есть специальная команда, которая позволяет прервать скрипт обновления фабрики, так как у него нет естественного тайм-аута.

  3. Больше не буду заранее заваривать чай).

Если тема вам интересна, пишите в комментариях, о чем бы ещё хотели узнать. У нас есть много увлекательных историй про фабрики ACI. И не только про них. Будем рады поделиться именно техническим опытом поддержки решений, который успели накопить за время поддержки железа как совместно с вендором, так и самостоятельно.


ссылка на оригинал статьи https://habr.com/ru/articles/921638/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *