Обновление JunOS на коммутаторах EX4500 в VirtualChassis — что может пойти не так? Часть 1

в 17:58, , рубрики: Juniper EX, ит-инфраструктура, Сетевые технологии, метки:

Поискав на Хабре, не нашел статью, освещающей данную тему в необходимом объеме, отсюда данный пост. Будет две части, так как для пробной статьи объема многовато.

Так как я здесь новичок, разрешите представиться: меня зовут Юра и на данный момент я работаю сетевым инженером в компании сервис-провайдере. За плечами преподавание в Сетевой Академии Cisco, достаточно плотное знакомство с нижней/средней линейкой их устройств и последние четыре года – с устройствами Juniper. Долгое время не мог собраться с мыслями по поводу данного поста, но в итоге жажда эпистолярного признания и желание помочь коллегам взяли вверх.

В качестве вступления могу сказать, что принцип обновления и приведенные выкладки справедливы для большинства (если не всех) устройств Juniper. В моем случае это два коммутатора EX4500, работающих в VirtualChassis (виртуальное шасси/VC). Сама технология VirtualChassis мною рассмотрена не будет, так как это раздует пост до неприличных размеров. Кроме этого, тема была рассмотрена ранее на Хабре здесь. Отмечу лишь, что она отдаленно напоминает VSS от Cisco: несколько физических устройств объединяются в одно логическое с общей панелью управления, конфигурацией, протоколами, таблицами и т.д. Не буду сильно занудствовать и размышлять о достоинствах/недостатках, реализации и прочих внутренних тонкостях – приведенное сравнение здесь больше как опорная метка, различия между VC и VSS большие, равно как и между Cisco IOS и JunOS.

Мой пациент – два физических коммутатора EX4500, объединенные в упомянутый VC (то есть, одно логическое устройство) и стоящие в ядре сети. Выше в сети стоят два независимых BGP маршрутизатора, каждый из которых подключен к своему физическому EX4500 («member» в виртуальном шасси) одним линком и высылает дефолтный маршрут, суммируя Full View таблицу. Ниже в сети – парк серверов с виртуалками и физическими серверами, которые используют VC как шлюз по-умолчанию. Исходная версия JunOS 11.1R3.5, аптайм – с установки, около 800 дней.

Само обновление и его необходимость витала задолго до моего появления в компании (отсюда и достаточно древняя версия), однако то ли никто не решался, учитывая важность железки, то ли времени на это не было, то ли «работает – не трожь», но это уже не важно. Срок поддержки этой версии подходил к концу и обновление надо было делать. Так как это ядро сети сервис-провайдера, среди клиентов которого множество критичных к недостижимости клиентов, требования по даунтайму достаточно жесткие. Кроме прочего сюда добавляется внутренний трафик (например, бекапы), который проходит через ядро. Забегая немного наперед скажу, что без доли удачи, я провалил бы эти требования. С другой стороны, без доли неудачи, этого поста не было бы.

Итак, согласно информации от производителя, обновление системы можно произвести следующими способами:

  1. Обычное обновление
  2. Nonstop Software Upgrade (NSSU)
  3. In-service Software Upgrade (ISSU)

Начиная с конца — ISSU. Идея состоит вот том, что сначала операционка обновляется на основном RoutingEngine (RE), а все управление и трафик коммутируется на standby RoutingEngine (RE). Затем происходит переключение между движками и обновление резервного RE. Протоколы и таблицы для этого должны быть синхронизированы между движками – это достигается с помошью технологий Graceful Routing Engine Switchover (GRES) и Nonstop Bridging/Routing (NSB/NSR).

Данный вид обновления подходит для устройств с двойным физическим RoutingEngine (aka ControlPlane, здесь можно посмотреть информацию об архитектуре и RoutingEngin’ах) и/или устройств, на которых JunOS виртуализирован, например некоторые маршрутизаторы MX или коммутаторы QFX5100 и EX4600, однако только работающих в stand-alone режиме. То есть в моем случае пролет по обеим статьям.

NSSU подходит для устройств с одним физическим RE, объединенным в VC или VCF (VirtualChassis Fabric, упрощенно говоря — следующее поколение VC). В данном случае роль standby RoutingEngine играет RE на другом устройстве. Эта процедура обновляет систему на виртуальном шасси, перегружая по одному устройству-члену за раз, что позволяет минимизировать даунтайм при условии, что используются аггрегированые каналы, терминируемые на разных членах VC и подходит для любых поддерживаемых конфигураций VC/VCF. Наличие GRES и NSB/NSR здесь носит рекомендательный характер и позволяет снизить даунтайм. Звучит это здорово, но с двумя оговорками – минимальная версия JunOS 12.1 и настоятельная рекомендация не использовать его от Juniper TAC. Целевая версия системы в моем случае – 12.3, старшая рекомендованая производителем на тот момент. Она как раз дает возможность NSSU, а так же NSB/NSR – это позволяет менять основной RE в шасси на лету без потерь пакетов, а так же обновлять систему без даунтайма для пользователей.

В конечном счете, учитывая мои реалии остался только один способ – «обычное» обновление. Под обычным здесь подразумевается обновление с одновременной перезагрузкой всех устройств VC, соответственно примерно 5-15 минут неработоспособности сети. Оценочное время взято из мануалов производителя, в моем случае оно составило примерно 4 минуты. Процедура такого обновления (без проблем) так же рассмотрена здесь. Если вам надоело читать и вы не боитесь возможных проблем при обновлении, рекомендую посетить.

Так как я потратил достаточно долгое время на подготовку, рискну привести полные выкладки, даже учитывая, что не все они были применимы в моей ситуации. К тому же вероятен случай, что именно вам они пригодятся.

Прежде всего, производитель (и теперь уже и я) рекомендует проверить и обновить версию JunOS loader и разметку внутреннего хранилища. В моем конкретном случае делать это было не обязательно, но позже я покажу, почему это может быть важно.

Если вы обновляете устройства с версии 10.4R2 или более ранней до 10.4R3 или более поздней, вам в дополнение к собственно обновлению операционки, нужно будет обновить загрузчик, специфичный для каждой платформы. Обновление загрузчика так же переформатирует внутреннее хранилище и создаст второй раздел для хранения операционной системы. В итоге на устройтве будет два раздела с операционной системой – один активный и один запасной, а так же два раздела для прочих файлов (логи, домашняя директория и т.п). В каких ситуациях необходимо обновлять загрузчик? Первое: если вывод команды show chassis firmware не содержит информацию о версии загрузчика после слов «U-boot», перед скобками:

user@switch> show chassis firmware
Part                     Type       Version
FPC 0                    uboot      U-Boot  (May 19 2010 - 05:03:13)
                         loader     FreeBSD/PowerPC U-Boot bootstrap loader 2.2

Обратите внимание, что данная команда, равно как и многие последующие выводит информацию о каждом отдельном устройстве-члене VC. Каждое устройство идентифицируется по номеру FPC (0, 1, 2 и т.д. в зачисимости от числа устройств). В этом случае устройство было одно, так как в продакшене не нашлось достаточно старых устройств и я взял одно из лабы.

Второе: если внутреннее хранилище содержит только три раздела (именуемых slice) в выводе команды show system storage:

Вывод команды
user@switch> show system storage
fpc0:
— Filesystem Size Used Avail Capacity Mounted on
/dev/da0s1a 184M 120M 50M 71% /
devfs 1.0K 1.0K 0B 100% /dev
/dev/md0 35M 35M 0B 100% /packages/mnt/jbas e
/dev/md1 18M 18M 0B 100% /packages/mnt/jcry pto-ex-10.3R1.9
/dev/md2 6.4M 6.4M 0B 100% /packages/mnt/jdoc s-ex-10.3R1.9
/dev/md3 145M 145M 0B 100% /packages/mnt/jker nel-ex-10.3R1.9
/dev/md4 22M 22M 0B 100% /packages/mnt/jpfe -ex42x-10.3R1.9
/dev/md5 46M 46M 0B 100% /packages/mnt/jrou te-ex-10.3R1.9
/dev/md6 27M 27M 0B 100% /packages/mnt/jswi tch-ex-10.3R1.9
/dev/md7 21M 21M 0B 100% /packages/mnt/jweb -ex-10.3R1.9
/dev/md8 126M 10.0K 116M 0% /tmp
/dev/da0s1f 123M 1.3M 112M 1% /var
/dev/da0s3d 314M 146K 289M 0% /var/tmp
/dev/da0s3e 55M 78K 51M 0% /config
/dev/md9 118M 12M 96M 11% /var/rundb
procfs 4.0K 4.0K 0B 100% /proc
/var/jail/etc 123M 1.3M 112M 1% /packages/mnt/jweb -ex-10.3R1.9/jail/var/etc
/var/jail/run 123M 1.3M 112M 1% /packages/mnt/jweb -ex-10.3R1.9/jail/var/run
/var/jail/tmp 123M 1.3M 112M 1% /packages/mnt/jweb -ex-10.3R1.9/jail/var/tmp
/var/tmp 314M 146K 289M 0% /packages/mnt/jweb -ex-10.3R1.9/jail/var/tmp/uploads
devfs 1.0K 1.0K 0B 100% /packages/mnt/jweb -ex-10.3R1.9/jail/dev
{master:0}

Здесь нас интересует устройство /dev/da0 и факт присутствия только трех разделов dev/da0s1X и dev/da0s3X. Куда подевался dev/da0s2X не спрашивайте – ответа я не нашел. Так или иначе, четвертого слайса здесь нет. Если есть, он будет называться /dev/da0s4d.

Еще один способ проверить необходипость переразбиения – выполнить команду show system storage partitions. В случае, если команда возвращает ошибку, потребуется обновление.
Если есть необходимость обновлять загрузчик и переразбивать хранилище (что рекомендуется делать при любых сомнениях в необходимости) помните, что это означает форматирование, и, как следствие, удаление всей информации. Соответственно, необходимо сохранить всю важную информацию, а лучше все содержимое внутренней флешки. Сам процесс обновление загрузчика банален и повторяет таковой для JunOS:

user@switch> request system software add /var/tmp/ jloader-XXX.tgz
user@switch> request system reboot

Обновление загрузчика и системы рекомендуется делать одновременно – это позволит перезагружать устройство только один раз. С одним исключением. Если вы обновляете старую систему разметки (3 раздела) до новой (4 раздела) и одновременно обновляете JunOS, обновленная версия запишется в оба загрузочных раздела (основной и резервный). Это может быть нежелательно в ситуациях, когда вы не знаете как поведет себя обновленная система в продакшене. В таком случае необходимо будет обновлять загрузчик и систему отдельно и перегружать устройства два раза. В лабе с одним EX4200 обновление лоадера+системы у меня заняло 13 минут, для более новых/быстрых устройств, возможно, меньше.

Теперь вернемся к основной теме.

Как уже было сказано, мне не требовалось обновление загрузчика и я начал с сохранения (бекапы наше все!) всех файлов через SFTP, текстового конфига, снепшотов на внутреннее хранилище, и на внешнюю флешку:

user@switch> request system snapshot media internal member 0
user@switch> request system snapshot media internal member 0 slice alternate 
user@switch> request system snapshot media internal member 1
user@switch> request system snapshot media internal member 1 slice alternate 
user@switch> request system snapshot partition media external

Несмотря на то, что Juniper рекомендует использовать сертифицированные флешки, подходит практически любая с объемом 2ГБ и менее, отформатированая в FAT c MBR. В приведенном скрипте первые 4 строки создают снепшот запущеной операционки и конфигурации в активный и резервный (slice alternate) разделы на обоих устройствах в VC. Если устройств больше, повторить для каждого «member N». Вместо member N можно так же воспользоваться ключем "all-members", но я предпочитаю определенность. Сам снепшот позволяет позднее откатиться к старой версии системы и/или загрузиться из резервного раздела, а так же внешней флешки на случай, если возникнут проблемы.

Важно! Перед тем, как делать снепшот, проверьте текущую запущеную версию системы (show version) и содержимое основного и резервного раздела (show system snapshot media internal) на соответствие версий. Загвоздка в том, что команда «request system snapshot media internal member N» копирует текущую запущеную (ну или running) версию в основной раздел, а команда «request system snapshot media internal member N slice alternate» копирует из основного раздела в резервный. У меня в основном разделе по какой-то причине лежала более древняя версия, чем в резервном. Гиковатость и предосторожность здесь только к добру.

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

Перед обновлением желательно скопировать новую версию системы во внутреннее хранилище, если вы не обновляетесь со внешнего диска/FTP/HTTP сервера. Juniper рекомендует помещать образ системы в /var/temp. Я бы НЕ рекомендовал делать это, так как в процессе обновления содержимое /var удаляется и при возникновении неприятностей (как у меня), потребуется перезаливать образ заново. Стоит ли говорить, что данная задержка при критичности системы менее чем желательна. Воспользуйтесь лучше заранее созданой директорией в корне, а после обновления почистите хранилище с помощью «file delete /directory/filename».

Далее собственно обновление с перезагрузкой:

user@switch> request system software add /var/tmp/jinstall-XXX.tgz validate
user@switch> request system reboot

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

К чему собственно этот длинный пост и куча объяснений с предостережениями? После 4 минут перезагрузки и обновления я вижу, что светодиоды интерфейсов загорелись только на втором устройстве (member1). Для меня это уже не плохо, так как все LACP линки подключены к обоим устройствам и (удача, здравствуй!) именно это устройство подключено к основному интернет-каналу, клиенты снова он-лайн. Единственный не-LACP линк подключен к member0 и соединяет парк машин с бекап-сервером. Для меня он не критичен, так как все бекапы были остановлены.

На этом месте счастливый администратор оканчивает свою работу, хлебает остатки кофе и со спокойной душой идет домой, улыбаясь ночному городу. В моем случае приведенный материал составляет 1/3 всей статьи. Если данная тематика заинтересует пользователей, с удовольствием продолжу — дальше только интересное!

Автор: yand_ua

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js