Библиотека — FreeBSD — обновление системы: стратегии, инструменты, подводные камни [X]
Шифр
freebsd-updating
Разделы
freebsd tooling
Сверено
2 сентября — в этот день утверждения статьи сверялись с первоисточниками, а не правился текст
Объём
18 665 знаков · 26 разделов · чтения около 20 минут

FreeBSD — обновление системы: стратегии, инструменты, подводные камни


Обзор

Обновление FreeBSD принципиально отличается от Linux: base system и сторонний софт — это две независимые сущности, обновляемые разными инструментами. Base system (ядро, userland, системные утилиты) обновляется через freebsd-update(8), сторонний софт — через pkg(8). Эти процессы независимы и могут выполняться в любом порядке, хотя при major-upgrade порядок имеет значение. Начиная с 15.0-RELEASE это разделение перестало быть единственным вариантом: базовую систему можно ставить и обновлять пакетами через тот же pkg (pkgbase), но в ветке 15.x такой путь ещё имеет статус tech preview — подробности в разделе про pkgbase ниже.

Второй ключевой момент: FreeBSD различает три типа обновлений с принципиально разным уровнем риска — security/errata patches (14.2-RELEASE-p1 → p2), minor version upgrade (14.1 → 14.2) и major version upgrade (13.x → 14.x). Первые — рутина, последние — операция с точкой невозврата.

Третий момент: ZFS boot environments превращают любое обновление в безопасную операцию с гарантированным откатом. Без ZFS — обновление на порядок рискованнее.

Версионирование FreeBSD

FreeBSD использует схему MAJOR.MINOR-RELEASE-pPATCH: 14.2-RELEASE-p3 означает major 14, minor 2, patch level 3.

RELEASE — production-ready ветка. freebsd-update собирает бинарные обновления только для версий, которые Release Engineering выпускает в бинарном виде: ALPHA, BETA, RC и RELEASE. Для PRERELEASE, STABLE и CURRENT бинарных патчей нет — эти ветки обновляют из исходников или пакетами base (репозиторные ветки base_latest и base_weekly).

Жизненный цикл: начиная с FreeBSD 15 каждая стабильная ветка явно поддерживается 4 года с момента выхода её .0. Каждый minor-релиз поддерживается 3 месяца после выхода следующего minor-релиза той же major-ветки, а последний minor живёт до конца поддержки самой ветки. Практический вывод: не задерживаться на старых minor-версиях, но major-upgrade можно планировать спокойно.

Две major-ветки живут параллельно и выпускают minor-релизы вперемешку, поэтому номера версий больше не растут хронологически: 15.0 вышла 2 декабря 2025, 14.4 — 10 марта 2026, 15.1 — 16 июня 2026. На сентябрь 2026 Security Team поддерживает stable/15 (до 31 декабря 2029), 15.1, 15.0 (до 30 сентября 2026), stable/14 (до 30 ноября 2028) и 14.4 (до 31 декабря 2026); вся ветка 13 и релизы 14.0–14.3 уже сняты с поддержки.

Security advisories публикуются на freebsd.org/security/advisories/. pkg audit -F проверяет уязвимости в установленных пакетах.

Patch-level обновления (рутина)

Самый частый и безопасный тип — security patches и errata. Не меняют ABI, не ломают пакеты.

# Проверить текущую версию
freebsd-version                        # 14.2-RELEASE-p1
uname -r                               # может отличаться от freebsd-version после обновления без ребута

# Скачать и установить патчи
freebsd-update fetch
freebsd-update install

# Если обновлено ядро — нужна перезагрузка
# freebsd-update скажет об этом в выводе
# Проверить: если freebsd-version -k != freebsd-version -u — ребут нужен
shutdown -r now

На ZFS freebsd-update автоматически создаёт boot environment перед установкой патчей. Если что-то пошло не так — откат через bectl activate <previous-BE>.

Автоматизация

# /etc/crontab — проверять обновления ежедневно, уведомлять по почте
0 3 * * * root freebsd-update cron

freebsd-update cron скачивает обновления и отправляет email root'у, но не устанавливает автоматически. Установка — всегда ручная (freebsd-update install). Это сознательное решение: автоматическая установка патчей ядра с последующей перезагрузкой — плохая идея для production.

Обновление jail'ов

Каждый thick jail обновляется отдельно:

freebsd-update -b /usr/local/jails/web fetch install
service jail restart web

Thin jails (NullFS) — обновить шаблон, перезапустить jail'ы:

freebsd-update -b /usr/local/jails/templates/14.2-RELEASE-base fetch install
service jail restart

Minor version upgrade (14.1 → 14.2)

Обновление между minor-версиями одной major-ветки. ABI обычно не меняется, установленные пакеты продолжают работать. Тем не менее — это upgrade, не patch, и требует больше внимания.

Процедура

# 0. Создать boot environment (если ZFS)
bectl create before-14.2-upgrade

# 1. Убедиться, что текущая версия полностью пропатчена
freebsd-update fetch install

# 2. Запустить upgrade
freebsd-update -r 14.2-RELEASE upgrade

# freebsd-update покажет список изменённых файлов
# Для файлов в /etc может предложить merge — внимательно просмотреть

# 3. Первая установка (ядро)
freebsd-update install
shutdown -r now

# 4. Вторая установка (userland) — после перезагрузки
freebsd-update install

# 5. Обновить пакеты (обычно не обязательно, но рекомендуется)
pkg upgrade

# 6. Проверить
freebsd-version                    # должна показать 14.2-RELEASE
uname -r                           # тоже 14.2-RELEASE

Шаг 1 (patch before upgrade) — критически важен и часто пропускается. Были случаи, когда freebsd-update upgrade ломался на не полностью пропатченной системе.

Merge файлов в /etc — freebsd-update покажет diff и предложит выбрать версию. Для стандартных файлов обычно безопасно принять новую версию. Для модифицированных (sshd_config, rc.conf, pf.conf) — внимательно смотреть diff и мержить вручную.

Что может пойти не так

Конфликты в /etc — freebsd-update предлагает merge, но может ошибиться. Всегда проверять результат.

Сторонние пакеты, зависящие от конкретной версии base — редко, но бывает.

Кастомное ядро — freebsd-update требует наличия /boot/GENERIC. Если ядро кастомное, нужно обеспечить GENERIC перед upgrade.

Major version upgrade (13.x → 14.x)

Самая сложная операция. Меняется ABI — все сторонние пакеты необходимо переустановить. Три прохода freebsd-update install вместо двух.

Процедура

# 0. Boot environment (обязательно на ZFS!)
bectl create before-14.0-upgrade

# 1. Пропатчить текущую версию
freebsd-update fetch install
# Перезагрузиться если нужно

# 2. Запустить major upgrade
freebsd-update -r 14.0-RELEASE upgrade

# 3. Первая установка (ядро)
freebsd-update install
shutdown -r now

# 4. Вторая установка (userland + /etc merge)
freebsd-update install

# 5. Третья установка (удаление старых библиотек и файлов)
freebsd-update install

# 6. Принудительная переустановка ВСЕХ пакетов
pkg-static install -f pkg
pkg upgrade -f                     # -f = force, пересобирает против нового ABI

# Или радикальнее: удалить всё и поставить заново
pkg-static delete -af
pkg install <список-пакетов>

# 7. Перезагрузка
shutdown -r now

# 8. Проверка
freebsd-version
pkg check -d -a                    # проверить зависимости

Три прохода install — не опечатка. Первый устанавливает ядро, второй — userland и мержит конфиги, третий — удаляет старые библиотеки и объектные файлы. Если третий проход говорит "nothing to do" — это нормально для некоторых upgrade.

Критичные моменты major upgrade

ABI break: все пакеты, скомпилированные для 13.x, несовместимы с 14.x. pkg upgrade -f — обязательно.

/usr/src/UPDATING: всегда читать перед upgrade. Содержит специфичные инструкции для конкретных переходов между версиями — переименование конфигов, изменение зависимостей, удалённые функции.

Порядок: base system сначала, пакеты потом. Не наоборот — pkg из старой версии может не работать с новым ABI.

Jail'ы: каждый jail нужно обновить отдельно. Jail с base system 13.x на хосте 14.x будет работать (ядро одно), но это нештатная ситуация — лучше обновить.

Кастомное ядро: /boot/GENERIC должен существовать. Если ядро пересобиралось многократно, GENERIC мог быть потерян — восстановить из installation media (tar -C / -xf kernel.txz boot/kernel/kernel).

Обновление с Boot Environments (рекомендуемый подход)

ZFS boot environments — самый безопасный способ обновления. Описан в статье о ZFS, здесь — конкретный workflow.

Подход A: обновление в текущем BE (простой)

bectl create pre-upgrade-$(date +%Y%m%d)
freebsd-update -r 14.2-RELEASE upgrade
freebsd-update install
reboot
freebsd-update install
pkg upgrade
# Если всё работает — удалить старый BE
bectl destroy pre-upgrade-20260224
# Если сломалось — откат:
bectl activate pre-upgrade-20260224
reboot

Просто и работает для большинства случаев. freebsd-update сам создаёт BE, но явное создание с понятным именем — хорошая практика.

Подход B: обновление в новом BE (безопаснее)

# Создать новый BE и смонтировать
bectl create upgrade-14.2
bectl mount upgrade-14.2
# Допустим, смонтировано в /tmp/be_mount.XXXX

# Обновить в монтированном BE
freebsd-update -b /tmp/be_mount.XXXX -d /tmp/be_mount.XXXX/var/db/freebsd-update \
    -r 14.2-RELEASE upgrade
freebsd-update -b /tmp/be_mount.XXXX -d /tmp/be_mount.XXXX/var/db/freebsd-update install

# Обновить пакеты через chroot
mount -t devfs devfs /tmp/be_mount.XXXX/dev
chroot /tmp/be_mount.XXXX pkg upgrade -f
umount /tmp/be_mount.XXXX/dev

# Отмонтировать и активировать
bectl umount upgrade-14.2
bectl activate upgrade-14.2
reboot

Преимущество: текущая система не затрагивается до момента bectl activate. Если что-то сломалось при обновлении — просто bectl destroy upgrade-14.2 и система не тронута. Минус: требует больше ручной работы.

Обновление пакетов

Пакеты обновляются независимо от base system:

pkg update                         # обновить индекс репозитория
pkg upgrade                        # обновить все пакеты

# Перед обновлением — проверить, что изменится
pkg upgrade -n                     # dry run

# Проверить уязвимости
pkg audit -F

# Заблокировать пакет от обновления
pkg lock nginx
pkg lock -l                        # список заблокированных
pkg unlock nginx

BE для pkg upgrade

Boot environment покрывает base system и /usr/local (где живут пакеты). Поэтому bectl create перед pkg upgrade — защита и от сломанных пакетов:

bectl create before-pkg-$(date +%Y%m%d)
pkg upgrade
# Проверить работу сервисов
# Если сломалось:
bectl activate before-pkg-20260224
reboot

quarterly vs latest

Описано в статье о pkg: quarterly — стабильность, latest — свежие версии. При upgrade можно переключиться, переопределив репозиторий в /usr/local/etc/pkg/repos/FreeBSD.conf — сам /etc/pkg/FreeBSD.conf править не рекомендуется, об этом сказано в комментарии в его шапке:

# /usr/local/etc/pkg/repos/FreeBSD.conf — FreeBSD 15.x
FreeBSD-ports: {
    url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest"
}

В 15.0 репозитории из /etc/pkg/FreeBSD.conf переименованы: FreeBSD → FreeBSD-ports, FreeBSD-kmods → FreeBSD-ports-kmods. На 14.x они по-прежнему называются FreeBSD и FreeBSD-kmods, и старый конфиг с именем FreeBSD на 15.x молча заведёт лишний репозиторий вместо того, чтобы переопределить штатный.

После смены ветки: pkg update -f && pkg upgrade -f.

Обновление из исходников (buildworld)

Альтернатива freebsd-update — сборка из исходников. Используется когда: нужна STABLE или CURRENT ветка; хочется кастомизировать base system; freebsd-update не поддерживает архитектуру.

# Получить исходники
git clone -b releng/15.1 https://git.FreeBSD.org/src.git /usr/src
# Или обновить существующие:
cd /usr/src && git pull

# Прочитать UPDATING!
cat /usr/src/UPDATING | head -100

# Сборка
cd /usr/src
make -j$(sysctl -n hw.ncpu) buildworld
make -j$(sysctl -n hw.ncpu) buildkernel

# Установка
make installkernel
reboot
# После ребута на новом ядре:
make installworld
etcupdate                          # merge /etc (замена mergemaster)
make delete-old
make delete-old-libs               # после проверки, что всё работает

etcupdate(8) — современная замена mergemaster. Делает трёхстороннее слияние изменений в /etc и показывает конфликты. Выбора больше нет: mergemaster(8) удалён из базовой системы в 15.0 (в дереве исходников его вывели из эксплуатации в июле 2024, в stable/14 он ещё есть). При первом переходе с mergemaster на etcupdate возможны ложные конфликты — об этом предупреждает и Handbook.

Сборка из исходников на VPS обычно не нужна. freebsd-update быстрее, проще, и достаточен для RELEASE.

pkgbase — обновление base через pkg

pkgbase — проект по упаковке base system FreeBSD в pkg-пакеты. Цель: обновлять base system так же, как сторонние пакеты — через pkg upgrade. Это устранит разделение между freebsd-update и pkg. Официальные пакеты base публикуются с октября 2023; с FreeBSD 14 их использование остаётся экспериментальным, а начиная с 15.0-RELEASE freebsd-base(7) официально заявлен как tech preview для установки, minor- и major-обновлений.

Репозиторий FreeBSD-base описан в /etc/pkg/FreeBSD.conf, но выключен по умолчанию. Включается одной строкой:

echo "FreeBSD-base: { enabled: yes }" > /usr/local/etc/pkg/repos/FreeBSD.conf
pkg update -r FreeBSD-base
pkg upgrade -r FreeBSD-base
shutdown -r now

Флаг -r ограничивает операцию одним репозиторием, чтобы обновление base не потянуло за собой сторонние пакеты. Переход с RELEASE на STABLE или CURRENT требует pkg upgrade -f. Существующую систему, установленную из distribution sets, конвертирует утилита pkgbasify: она создаёт boot environment через bectl, пишет конфиги репозиториев, мержит /etc и перезапускает sshd. Обратная дорога тоже учтена: на системе с pkgbase цели installworld и installkernel заблокированы (15.1), и перед сборкой из исходников пакеты base нужно снять с учёта — как описано в freebsd-base(7).

Установщик с 15.0 предлагает выбор между Distribution Sets и Packages (Tech Preview). Handbook прямо рекомендует для production в течение всего жизненного цикла 15.x оставаться на distribution sets и freebsd-update: это по-прежнему дефолт для большинства установочных образов 15.x. Дефолтом pkgbase ожидаемо станет в FreeBSD 16.0, и он же должен со временем заменить тарболлы base.txz/kernel.txz и freebsd-update — причём план не выбросить freebsd-update, а научить его работать поверх pkg. Следить: wiki.freebsd.org/PkgBase и freebsd-base(7).

Стратегия обновления для VPS

Минимально необходимое (рутина)

Еженедельно или при выходе security advisory:

freebsd-update fetch install       # base system patches
pkg upgrade                        # пакеты
# Ребут если обновлено ядро

При minor/major upgrade

  1. Прочитать Release Notes и /usr/src/UPDATING
  2. bectl create (на ZFS)
  3. freebsd-update fetch install (пропатчить текущую)
  4. freebsd-update -r X.Y-RELEASE upgrade
  5. Серия install + ребутов
  6. pkg upgrade [-f] (force для major)
  7. Проверить сервисы
  8. Обновить jail'ы

Что НЕ делать

Не перепрыгивать через мажорную версию. Официально поддерживаются два направления: на более свежую minor-версию той же ветки (14.3 → 14.4) и на любую более свежую версию следующей мажорной ветки (14.3 → 15.0 или сразу 15.1). Скачок вида 13.5 → 15.1 не поддерживается, даже если инструменты его пропускают.

Не ориентироваться на номер версии как на «более новое». Из-за параллельных веток номера не растут хронологически: 14.4 вышла в марте 2026, а 15.0 — тремя месяцами раньше, в декабре 2025. Переход 14.4 → 15.0 — это шаг назад во времени, и он не поддерживается; целиться нужно в 15.1.

Не обновлять production без бэкапа/BE. Даже patch-level обновления изредка ломают вещи.

Не оставлять freebsd-update cron запущенным во время upgrade — может скачать патчи для старой версии и сломать процесс.

Не игнорировать merge в /etc — принимать изменения не глядя опасно для модифицированных конфигов.

Отличия от Linux

В Linux обновляются одновременно: ядро, системные утилиты и сторонний софт — всё через один менеджер пакетов (apt upgrade, dnf upgrade). Во FreeBSD base system и пакеты — два независимых мира.

В Linux major-upgrade дистрибутива (Ubuntu 22.04 → 24.04, Fedora 39 → 40) — сложная процедура с высоким риском. Во FreeBSD — freebsd-update -r + pkg upgrade -f, плюс ZFS BE для отката.

В Linux нет нативного аналога boot environments (Snap с Ubuntu Core — другая модель). Во FreeBSD — bectl из base system, глубоко интегрированный с загрузчиком.

etcupdate / merge конфигов в /etc — проблема в обеих системах, но во FreeBSD она эксплицитна и управляема, тогда как в Debian/Ubuntu .dpkg-new/.dpkg-old файлы часто теряются.

Источники


Связанные заметки

Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.

Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.