Производственная компания на Авиамоторной, 44 рабочих места. Почтовый сервер поставили в 2014 году и с тех пор не трогали. В марте 2021 меня позвали «обновить сразу на актуальную» — за один вечер. Вечер превратился в пять окон работ и 31 час. Показываю реальную цепочку версий, что ломается на каждом шаге и где именно я ошибся в оценке.
Матрица апгрейд-путей Zimbra: почему нельзя прыгать через версию
«Он же работает, просто обновите его до свежей»
Почтовый сервер, который никто не трогал шесть лет, выглядит как удача. Ничего не падало, никто не жаловался, счетов за обслуживание не было. Ровно до того дня, когда кто-то произносит слово «обновить».
Дальше почти всегда происходит одно и то же. Владелец спрашивает: сколько займёт? Подрядчик смотрит на две версии — текущую и актуальную — и называет цифру исходя из разницы между ними. Обе стороны считают, что речь про одно действие. А между этими двумя версиями лежит не одно действие, а пять-семь, и каждое ломается по-своему.
Если ваш сервер стоит на старой ветке и его давно не обновляли, единственный честный ответ на вопрос «сколько» звучит так: сначала надо построить маршрут. Прямой линии между вашей версией и актуальной может не быть вовсе.
Есть и вторая сторона вопроса, о которой владельцы обычно не думают. Шесть лет без обновлений — это не только устаревшая версия. Это ещё и шесть лет накопленных ручных правок в конфигурации, о которых никто не помнит, и каждая из них всплывёт ровно в тот момент, когда инсталлятор начнёт перебирать настройки.
Разбираю на конкретном маршруте, который мы прошли до конца.
Март 2021, производство на Авиамоторной: ветка 6.0.4
Клиент — производство: цех, склад и конструкторское бюро на территории старой промзоны у Авиамоторной. 44 рабочих места, 52 ящика. Почтовый сервер поставил в 2014 году подрядчик, который потом исчез, и с тех пор сервер просто работал. Ветка была устаревшей уже на момент установки — актуальной тогда была восьмёрка, — почему подрядчик развернул шестёрку, никто не помнит и спросить не у кого.
- ветка 6.0.4, Open Source, на CentOS 6;
- store — 610 ГБ, база — 14 ГБ, самый большой ящик — 71 ГБ у главного конструктора;
- пароль от учётной записи каталога никто не знал, документации не было вообще;
- сертификат самоподписанный, истёк в 2017 году — люди привыкли нажимать «всё равно перейти».
Задачу поставили так: «обновите до актуальной, желательно в один вечер, чтобы никто не заметил». Я оценил в два окна работ по шесть часов. Это была моя ошибка, и я к ней ещё вернусь.
Первое, что я сделал, — попробовал понять, куда вообще можно прыгнуть с 6.0.4. Ответ оказался неприятным: напрямую — никуда. Ни на 8.8.15, ни на что-либо ещё из живых на тот момент веток.
Почему прыжок через версию не проходит
Инсталлятор Zimbra умеет обновляться, но обновление — это не установка новых файлов. Это миграция схемы каталога, миграция схемы базы, пересборка конфигов служб и перенос локальных настроек. Сценарии миграции пишутся от версии к версии, соседней или близкой.
Когда вы просите инсталлятор перескочить через несколько веток сразу, он либо честно отказывается, либо — что хуже — берётся и доходит до середины. Второй вариант оставляет сервер в состоянии, из которого назад дороги нет: схема каталога уже частично мигрирована, старая версия её не понимает, новая не доделала.
Как я строю маршрут практически. Между двумя соседними ступенями допускается не более одной смены мажорной ветки, а внутри ветки надо дойти до последнего доступного патча, прежде чем шагать дальше: инсталлятор проверяет состояние исходной системы и на полуобновлённой ветке ведёт себя непредсказуемо. Отсюда и берутся семь ступеней там, где в голове заказчика одна. Шестёрка на семёрку — смена ветки. Семёрка на восьмёрку — смена ветки. Дальше 8.0 → 8.5 → 8.6 → 8.7 → 8.8 — четыре шага внутри одной восьмёрки, и каждый из них в своё время менял либо схему каталога, либо формат сгенерированных конфигов, либо и то и другое сразу.
Отсюда правило, которое я формулирую клиентам одной фразой: маршрут строится по ступеням, и каждая ступень — отдельное окно работ с точкой отката. Не «вечер обновления», а пять вечеров, между которыми сервер живёт и работает.
Проверить свою стартовую точку можно одной командой:
su - zimbra -c 'zmcontrol -v'
cat /opt/zimbra/.install_history | tail -20Второй файл интереснее первого. Он хранит историю установок и обновлений этого сервера — когда ставили, что ставили, какие версии проходили. На сервере в промзоне последняя запись была датирована 2014 годом.
Матрица: семь ступеней вместо одного вечера
Маршрут, который мы прошли, выглядел так. Я привожу его целиком, включая время каждой ступени — плановое и фактическое.
| Ступень | Что делали | План | Факт |
|---|---|---|---|
| 6.0.4 → 7.x | подъём с самой старой ветки, миграция схемы каталога | 3 ч | 7 ч 20 мин |
| 7.x → 8.0.8 | смена ветки, лог-таблицы базы | 3 ч | 4 ч 10 мин |
| 8.0.8 → 8.5.1 | промежуточный шаг, без сюрпризов | 2 ч | 1 ч 50 мин |
| 8.5.1 → 8.6.0 | здесь встали: postfix и mailbox не стартуют вместе | 2 ч | 6 ч 05 мин |
| 8.6.0 → 8.7.9 | ровный шаг | 2 ч | 2 ч 15 мин |
| 8.7.9 → 8.8.12 | JVM не стартует из-за двух устаревших опций | 2 ч | 5 ч 40 мин |
| 8.8.12 → 8.8.15 | финальный шаг ветки | 1 ч | 3 ч 40 мин |
Итого 31 час против запланированных 15. Разложено на пять окон: два выходных подряд плюс один будний вечер.
В деньгах по нашей ставке 4 000 ₽ в час это 60 000 ₽ по плану и 124 000 ₽ по факту. Клиент заплатил по факту, и без скандала — но только потому, что после второй ступени я пришёл и сказал: вилка поехала, вот новая оценка, решайте, идём дальше или останавливаемся на семёрке. Пересогласовали смету до начала третьей ступени. Если бы я принёс эти 124 тысячи в конце, разговор был бы другим.
Перед каждой ступенью — снимок виртуалки и выгрузка каталога. Это не перестраховка: на четвёртой ступени мы откатывались, и без снимка вечер закончился бы совсем иначе.
# перед каждым шагом, обязательно
su - zimbra -c 'zmcontrol stop'
# выгрузку каталога гоняем от root: в /backup пользователь zimbra писать не может
/opt/zimbra/libexec/zmslapcat /backup/pre-8.6.0
# снимок виртуальной машины — средствами гипервизора
su - zimbra -c 'zmcontrol start'Три узла, которые ломаются на каждой ступени
Разные версии, разные ошибки, но три места повторялись почти на каждом шаге. Их стоит держать в голове заранее.
Лог-таблицы базы. При смене версии таблицы журналов остаются от предыдущей и мешают запуску. Проявляется как отказ службы базы после обновления, лечится удалением и пересозданием — но искать причину, если не знаешь, где смотреть, можно полвечера.
Пароли каталога и базы. Самое неприятное. Служебные пароли хранятся в локальной конфигурации и должны совпадать с тем, что реально прописано в самих службах. При обновлении через несколько веток они расходятся, и вы получаете сервер, который не может сам к себе подключиться.
su - zimbra
zmlocalconfig -s zimbra_ldap_password
zmlocalconfig -s mysql_root_password zimbra_mysql_password
# синхронизация пароля каталога, если разошёлся
zmldappasswd -a <новый_пароль>Хранилище ключей mailboxd. Сертификаты и keystore при обновлении перетряхиваются, и если сертификат просрочен или цепочка неполная, служба просто не поднимается. У клиента сертификат истёк в 2017-м — на второй ступени это и выстрелило.
su - zimbra
zmcertmgr viewdeployedcrt
# на время апгрейда — временный самоподписанный, чтобы не мешал
zmcertmgr createca -new
zmcertmgr createcrt -new -days 365
zmcertmgr deploycrt self
zmcertmgr deploycaДве оговорки к этому блоку, обе стоили мне времени. Первая: createca поднимает только собственный удостоверяющий центр, сам сертификат после него надо ещё выпустить — createcrt -new. Без этого шага deploycrt self разворачивать нечего, и утилита честно об этом скажет, а вы будете смотреть на неё и думать, что сломался апгрейд.
Вторая касается именно длинного маршрута через старые ветки. До 8.6 включительно zmcertmgr запускался от root — так его описывали все инструкции тех лет, и на первых ступенях нашего маршрута он работал именно так. Начиная с 8.7 поведение сменили: от root утилита отвечает ERROR: no longer runs as root! и не делает ничего, работать она согласна только из-под пользователя zimbra. То есть на ступенях 6 и 7 вы делаете одно, на ступенях 8.7 и выше — другое, а найденная в поиске инструкция будет права ровно наполовину и не скажет, на какую именно.
Порядок, к которому я в итоге пришёл: перед стартом ступени привести сертификат в валидное состояние — хоть самоподписанным, — и только потом обновляться. Коммерческий сертификат ставится обратно в самом конце, одним движением на финальной версии.
Ступень 8.6.0: postfix и mailbox не стартуют вместе
Здесь мы встали на шесть часов вместо двух. Обновление прошло, инсталлятор отчитался успехом, а дальше картина такая: запускается либо почтовый транспорт, либо служба ящиков. Обе одновременно — нет.
zmcontrol status
antispam Running
ldap Running
logger Running
mailbox Stopped
mta Running
...
zmmailboxdctl start
Starting mailboxd...failed.Причина оказалась в конфигах транспорта, которые генерируются автоматически из шаблонов. При смене версии шаблоны меняются, а сгенерированные ранее конфиги остаются, и получается смесь старого с новым, в которой службы конфликтуют за настройки.
Лечится пересборкой конфигов с нуля — не правкой руками, а именно перегенерацией. И тут же вторая половина правила: если предыдущий админ что-то дописывал прямо в сгенерированный конфиг, перегенерация это сотрёт. Такие правки надо заранее перенести в соответствующий шаблон с суффиксом .in, иначе вы будете лечить одно и то же на каждой ступени.
su - zimbra
zmcontrol stop
# служба конфигурации пересобирает конфиги транспорта из шаблонов *.in
zmconfigdctl restart
zmcontrol start
zmcontrol statusА теперь моя ошибка на этой ступени. Первые полтора часа я искал проблему в памяти — сервер был нагружен, служба ящиков падала, версия «не хватает кучи» напрашивалась сама. Я поднял размер кучи, перезапустил, посмотрел на результат. Ничего не изменилось. Полтора часа на версию, которую можно было отбросить за пять минут: если бы дело было в памяти, в журнале лежала бы ошибка нехватки кучи. Её там не было. Я просто не посмотрел.
Ступень 8.8.12: две строки, из-за которых не стартует JVM
Предпоследний шаг дал ошибку, которая выглядит страшнее, чем есть. Служба ящиков не поднимается вообще, в журнале — жалобы на параметры виртуальной машины Java:
Java HotSpot(TM) 64-Bit Server VM warning:
Option UseConcMarkSweepGC was deprecated in version 9.0
Unrecognized VM option 'PrintGCDateStamps'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.Смысл простой: в локальной конфигурации остались опции запуска Java, которые новая версия среды исполнения уже не понимает. Одна помечена устаревшей, вторая не распознаётся вовсе — и процесс не создаётся.
Лечится удалением этих опций из строки запуска:
su - zimbra
zmlocalconfig -s mailboxd_java_options
# убрать -XX:+UseConcMarkSweepGC и -XX:+PrintGCDateStamps
zmlocalconfig -e mailboxd_java_options="-server -Djava.awt.headless=true \
-Dfile.encoding=UTF-8 -XX:+UseG1GC"
zmmailboxdctl restartПять минут работы, если знаешь. У нас ушло почти три часа, потому что журнал службы ящиков в этот момент не пишется — процесс не создаётся, писать некому. Ошибку видно только в выводе запуска, и надо догадаться туда посмотреть.
Опции, оставшиеся с 2014 года, пережили пять обновлений подряд и выстрелили на шестом. Это, пожалуй, лучшая иллюстрация к тому, почему прыгать через версии нельзя: каждая ступень тащит за собой хвост предыдущих.
Проверьте у себя за 2 минуты
Четыре команды на боевом сервере, ничего не меняют.
su - zimbra -c 'zmcontrol -v'
cat /opt/zimbra/.install_history | tail -20
cat /etc/os-release | head -3
su - zimbra -c 'zmlocalconfig -s mailboxd_java_options'| Что получилось | Что это значит |
|---|---|
| Версия начинается с 6 или 7 | До актуальной ветки — пять-семь ступеней. Один вечер тут не работает ни при каком раскладе. |
| Версия 8.8.15 | Общая поддержка этой ветки закончилась 31 декабря 2023 года. Обновлений безопасности с тех пор нет. |
| В истории установок последняя запись старше трёх лет | Все накопленные с тех пор настройки поедут разом. Планируйте отдельные окна, а не один вечер. |
В опциях Java есть UseConcMarkSweepGC или PrintGCDateStamps | На следующем крупном шаге служба ящиков не поднимется. Правится заранее, за пять минут, на живом сервере. |
| ОС — CentOS 6 или 7 | Обновлять почту на мёртвой ОС — половина работы. Маршрут придётся строить сразу с переездом на другой сервер. |
Отдельно посмотрите на дату истечения сертификата: zmcertmgr viewdeployedcrt. Просроченный сертификат ломает старт службы на любой ступени, и это ровно то место, где вечер превращается в ночь.
Чем кончилось, где я ошибся и что происходит сегодня
Финал: сервер доехал до 8.8.15, отработали 31 час за пять окон, простой для пользователей суммарно составил 9 часов и весь пришёлся на выходные. Один ящик — 71 ГБ у главного конструктора — потребовал отдельной переиндексации, ещё два часа сверху.
Моя ошибка в оценке была системной, а не арифметической. Я посчитал время как «объём работ на одну ступень, умножить на число ступеней». А надо считать иначе: каждая ступень тащит хвост всех предыдущих, и вероятность встрять растёт от шага к шагу. Первые три прошли почти по плану. Четвёртая и шестая съели весь запас.
Цену бездействия мы с директором посчитали тогда же, на обороте той же сметы, и она оказалась убедительнее всех моих аргументов. Сутки без почты для производства на 44 рабочих места — это остановка согласования отгрузок и заявок снабжения: 44 человека, 8 часов, 700 ₽ фонда оплаты на человеко-час — 246 400 ₽ за один такой день, и это без сорванных отгрузок и без штрафов по договорам.
А теперь второй столбец. Машина 2014 года, гарантии нет, CentOS 6 обновлений не получает, дистрибутивы 6.0.4 в 2021-м ещё надо было найти. Если бы этот сервер умер до апгрейда, восстановление выглядело бы так: поднять виртуалку, разыскать дистрибутив мёртвой ветки, поставить её, залить 610 ГБ из копии, разобраться, почему не сходятся пароли служб. Я оцениваю такую работу в 40–56 часов, то есть 160 000–224 000 ₽, плюс двое-трое суток, пока почты нет вовсе. Складываем — и апгрейд за 124 тысячи перестаёт выглядеть дорогим.
Теперь я оцениваю такие маршруты с коэффициентом два и говорю клиенту прямо: половина ступеней пройдёт быстрее плана, одна-две — вдвое дольше, какие именно — заранее неизвестно. Пока никто на такую формулировку не обиделся.
Что изменилось с того марта. Ветка 8.8.15 Open Source закончила общую поддержку 31 декабря 2023 года — обновлений безопасности для неё больше нет. Вендор предлагает переходить на поддерживаемые ветки, но на форумах регулярно всплывают темы вроде «обновление до 10 невозможно»: в части конфигураций прямой путь просто не проходит. То есть маршрут из промежуточных версий никуда не делся, он только удлинился.
И упирается он теперь не в версию, а в кассу. Десятка — Daffodil — существует только как Network Edition: свободной ветки у неё нет вообще, а инсталлятор без лицензионного ключа апгрейд просто не начинает, это записано в документации вендора прямым текстом. Лицензия годовая и считается по числу ящиков. То есть лестница, по которой мы бесплатно поднялись на семь ступеней, заканчивается на 8.8.15 и девятке: следующая ступень платная, и покупать её российскому юрлицу отдельный сюжет.
Поэтому сегодня я задаю клиенту вопрос, которого не задавал в 2021-м: а мы точно хотим остаться на этом продукте? Иногда цепочка из семи ступеней стоит дороже, чем переезд на другую платформу, и считать это надо до начала работ, а не после четвёртой ступени.
Если хотите понять свой маршрут — пришлите вывод четырёх команд из блока проверки. За день отвечу, сколько у вас реально ступеней до поддерживаемой версии, где на этом пути обычно встают и во что это выльется по времени. Если окажется, что переезд дешевле апгрейда, я так и напишу.
Частые вопросы
Можно ли обойти цепочку, поставив новый сервер и перенеся на него почту?
Часто это и есть правильный ответ, особенно когда операционная система под сервером тоже устарела. Логика такая: вы ставите свежую версию на новую машину с нормальной ОС, создаёте домены и учётки, переносите пароли и заливаете почту через IMAP. Цепочка промежуточных версий при этом не нужна вообще — вы не обновляете старый сервер, вы строите новый. Минусы тоже есть: переносить придётся вручную, часть настроек не переедет, а на больших объёмах заливка занимает дни. У производства на Авиамоторной с 610 ГБ и мёртвой CentOS 6 я сегодня, скорее всего, выбрал бы именно этот путь. В 2021-м мы пошли по ступеням, и я не считаю это ошибкой — просто вариант был не единственный.
Сколько времени закладывать на апгрейд через несколько версий?
Моя формула после этого случая: считаете время на каждую ступень отдельно, складываете и умножаете на два. У нас план был 15 часов, факт — 31. Половина ступеней прошла быстрее плана, две съели весь запас. Заранее угадать, какие именно, нельзя: это зависит от того, что накопилось в конфигурации за годы. Ещё важное — не пытайтесь пройти маршрут подряд, одним заходом. Между ступенями сервер должен пожить хотя бы сутки под реальной нагрузкой, иначе вы не заметите проблему, которая проявляется только на людях, и потащите её дальше.
Что делать, если пароль от служебной учётной записи каталога никто не знает?
Он хранится в локальной конфигурации сервера, и посмотреть его можно командой zmlocalconfig с ключом -s. Это первое, что я делаю на незнакомом сервере, ещё до любых работ. Проблема начинается, когда значение в конфигурации и то, что реально прописано в самом каталоге, разошлись — такое случается как раз при обновлениях через несколько веток. Симптом характерный: сервер не может подключиться сам к себе, службы не видят настроек. Синхронизируется штатной командой zmldappasswd, но делать это надо на остановленных службах и обязательно после снимка машины. Восстанавливать каталог, испорченный неудачной сменой пароля, гораздо дороже.
Обязательно ли обновлять операционную систему вместе с почтой?
Не одновременно, но и не откладывать. Свежие версии Zimbra просто не ставятся на старые дистрибутивы — там другие версии системных библиотек, и инсталлятор это проверяет. Если у вас CentOS 6 или 7, маршрут придётся строить сразу с переездом: старая ОС ограничивает потолок, до которого вы можете дойти на этом железе. Порядок я предпочитаю такой: сначала довести почту до максимальной версии, которая живёт на текущей ОС, потом перенести на новую машину с новой ОС той же версией, и только потом обновляться дальше. Три этапа вместо одного, зато на каждом есть куда откатиться.
Как понять, что откат ещё возможен, а когда точка невозврата пройдена?
Точка невозврата — это момент, когда инсталлятор начал миграцию схемы каталога. До неё откат возможен простым возвратом снимка машины. После — снимок вернёт вам старую версию продукта поверх уже мигрированных данных, и это состояние хуже, чем обе версии по отдельности. Практическое правило: снимок делается перед каждой ступенью, и рядом обязательно кладётся выгрузка каталога в текстовый LDIF. Первый спасает от неудачного шага, вторая — от ситуации, когда снимок не помог. Оба вместе занимают минут двадцать на ступень. За семь ступеней это два с половиной часа, которые я считаю самыми полезными во всём маршруте.
Оставить комментарий