open atlas
↑ К треку
Linux: операционная система LIN · 04 · 03

Зависимости, удержания и пиннинг

Пакеты Debian объявляют Depends, Recommends, Suggests и Conflicts. apt разрешает полный граф зависимостей до касания диска. Hold замораживает пакет на текущей версии; пиннинг контролирует, какая версия побеждает, когда несколько источников предоставляют один пакет.

LIN Middle ◷ 22 min
Уровень
ОсновыJuniorMiddleSenior

Ты запускаешь apt upgrade — и он хочет обновить ядро. Твой production-сервер использует кастомный модуль ядра, несовместимый с новой версией. Или ты закрепил конкретную версию PostgreSQL, потому что ваш DBA говорит, что минорное обновление ломает функцию репликации. Или ты смешиваешь пакеты из Debian stable и backports, а apt продолжает «полезно» обновлять пакеты, которые ты хотел оставить на stable-версии. Все три проблемы решаются двумя инструментами: удержаниями и пиннингом. Ошибись здесь — и «актуальный» сервер либо незаметно сломан, либо навсегда завис на небезопасном пакете.

Цель

После этого урока ты сможешь объяснить разницу между Depends, Recommends и Suggests; читать ограничения версий вида (>= 2.0) и (= 1.18.0-6ubuntu14); удерживать пакет на текущей версии с помощью apt-mark; безопасно снимать удержание; и писать пин в /etc/apt/preferences.d/ для управления тем, какой репозиторий побеждает для конкретного пакета.

1

Типы зависимостей имеют разную семантику — apt обрабатывает их по-разному. Понимание разницы объясняет, почему apt install --no-install-recommends может значительно сократить использование диска на сервере.

# Просмотр всех полей зависимостей пакета
apt-cache show nginx | grep -E '^(Depends|Recommends|Suggests|Pre-Depends|Conflicts|Breaks):'

# Depends: ДОЛЖНЫ быть установлены; apt откажет без них
# Recommends: устанавливаются по умолчанию, но пропускаемые; --no-install-recommends пропускает их
# Suggests: только информационные; никогда не устанавливаются автоматически
# Pre-Depends: как Depends, но должны быть настроены ДО распаковки этого пакета
# Conflicts: не может быть установлен вместе с перечисленным пакетом
# Breaks: перечисленный пакет будет некорректно работать рядом с этим

На минимальном сервере --no-install-recommends часто оправдан:

# В Dockerfile: экономит 30-60% на размере образа для многих пакетов
RUN apt-get install -y --no-install-recommends nginx

Pre-Depends встречаются редко, но критически важны: они существуют для пакетов вроде libc6, которые должны быть полностью настроены до того, как будет тронуто что-либо ещё в системе, потому что сам dpkg от них зависит.

2

Ограничения версий позволяют мейнтейнерам точно выражать совместимость. Ты увидишь их в выводе apt-cache show и в собственных спецификациях зависимостей:

Depends: libssl3 (>= 3.0.0), libpcre3 (>= 1:8.31), nginx-common (= 1.18.0-6ubuntu14.4)
ОграничениеЗначение
(>= 1.2)версия 1.2 или любая более поздняя
(<= 2.0)версия 2.0 или любая более ранняя
(= 1.2.3-4)ровно эта версия, включая суффикс ревизии Debian
(>> 1.0)строго больше 1.0 (редко)
(<< 2.0)строго меньше 2.0 (редко)
# Проверить, удовлетворяет ли установленный пакет ограничению
dpkg --compare-versions "1.18.0-6ubuntu14.4" ">=" "1.18.0" && echo "satisfies" || echo "does not"
# satisfies

# Именно это apt выполняет внутри при разрешении зависимостей

Префикс эпохи Debian (1: в 1:8.31) переопределяет обычную сортировку версий. Версия пакета 1:0.1 сортируется выше, чем 9.99, потому что номер эпохи побеждает. Эпохи существуют, когда схема версионирования upstream изменилась, а новый номер версии численно ниже старого.

3

apt-mark hold замораживает пакет на установленной версии. apt upgrade будет полностью пропускать удержанные пакеты — они не обновятся, даже если доступна новая версия.

# Удержать пакет на текущей версии
sudo apt-mark hold nginx
# nginx set on hold.

# Проверить
apt-mark showhold
# nginx

# Проверить статус dpkg — теперь показывает "hi" (hold + installed)
dpkg -l nginx
# hi  nginx  1.18.0-6ubuntu14.4  ...

# apt upgrade предупредит об удержанных пакетах:
# The following packages have been kept back: nginx

# Снять удержание, когда готов к обновлению
sudo apt-mark unhold nginx

Самое распространённое применение: удержание ядра на сервере с out-of-tree модулем до выхода совместимой сборки от вендора. Подводный камень: удержанный пакет может блокировать обновления безопасности пакетов, которые от него зависят. Периодически запускай apt upgrade и проверяй, что остаётся в «kept back» — удержание должно быть осознанным, проверенным решением, а не тем, о чём ты забыл полгода назад.

4

Пиннинг управляет тем, какую версию apt предпочитает, когда несколько репозиториев предоставляют один пакет. Файл /etc/apt/preferences (или файлы в /etc/apt/preferences.d/) назначает числовые приоритеты. Побеждает наибольший приоритет.

# /etc/apt/preferences.d/backports-pin
# Приоритеты по умолчанию:
#   500  = пакеты из целевого релиза (основной suite)
#   100  = установленные пакеты и пакеты из нецелевых релизов
#   1    = «никогда не устанавливать из этого источника автоматически»
#   -1   = «никогда не устанавливать, даже если явно запрошено»

# Закрепить nginx на версии из backports (приоритет 900 > 500 по умолчанию)
Package: nginx
Pin: release a=jammy-backports
Pin-Priority: 900

# Все остальные пакеты из backports с БОЛЕЕ НИЗКИМ приоритетом (предотвращает массовые обновления)
Package: *
Pin: release a=jammy-backports
Pin-Priority: 100
# Проверить эффективную политику для пакета — показывает, какой репозиторий побеждает
apt-cache policy nginx
# Installed: 1.18.0-6ubuntu14.4
# Candidate: 1.25.3-1~jammy  ← backports побеждает из-за приоритета 900
# Version table:
#  1.25.3-1~jammy 900        ← из jammy-backports (закреплён)
#     ...
#  1.18.0-6ubuntu14.4 500    ← из jammy (стандартный приоритет)

Приоритет пиннинга выше 1000 даже понизит версию установленного пакета — крайне опасно в production, используется только для экстренных откатов.

5

Конфликты зависимостей возникают, когда два пакета не могут сосуществовать. Conflicts: означает «dpkg откажется устанавливать оба одновременно». Breaks: означает «я буду работать, но перечисленный пакет будет некорректно функционировать рядом со мной».

# Пример: попытка установить два конфликтующих пакета
sudo apt install apache2 nginx-full
# The following packages conflict:
#   nginx-full conflicts with apache2 (оба слушают порт 80 по умолчанию)

# Решение: сначала удалить конфликтующий пакет
sudo apt remove apache2
sudo apt install nginx-full

# Симулировать действия apt без касания диска
apt-get install -s nginx-full  # -s = simulate

# Когда apt говорит "held broken packages" при обновлении:
sudo apt install -f   # fix broken: устанавливает недостающие зависимости

apt install -f (fix) — первый ответ на сломанное состояние зависимостей. Он не устанавливает случайные вещи — он читает текущее состояние dpkg и устанавливает или удаляет ровно то, что нужно для достижения согласованного состояния. Если -f сам завершается ошибкой — читай её внимательно: обычно в ней назван конкретный конфликтующий пакет.

Разбор примера

Безопасное смешивание Debian stable и backports для одного пакета.

Цель: запустить nginx из bookworm-backports на сервере Debian 12, оставив всё остальное на stable. Без пиннинга apt upgrade со временем подтянет все обновления из backports.

# 1. Добавить backports в sources (формат deb822)
cat > /etc/apt/sources.list.d/backports.sources << 'EOF'
Types: deb
URIs: http://deb.debian.org/debian
Suites: bookworm-backports
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF

# 2. Написать файл пина
cat > /etc/apt/preferences.d/backports-selective << 'EOF'
# Подавить автоматические обновления из backports для всего
Package: *
Pin: release a=bookworm-backports
Pin-Priority: 100

# Кроме nginx — предпочесть backports
Package: nginx nginx-common nginx-core
Pin: release a=bookworm-backports
Pin-Priority: 900
EOF

# 3. Обновить и проверить
sudo apt update
apt-cache policy nginx
# Candidate должен показывать версию из backports

# 4. Установить (версия из backports побеждает из-за приоритета 900)
sudo apt install nginx

# 5. Убедиться, что удержания не мешают
apt-mark showhold
# (ничего не удержано — пиннинг отличается от удержания)

Ключевое различие: удержание замораживает уже установленную версию. Пин управляет тем, какую версию apt выбирает кандидатом — работает даже до установки.

Частая ошибка

Бессрочное удержание критически важного с точки зрения безопасности пакета — распространённая ошибка, которая кажется безопасной, но таковой не является. Удержание предотвращает автоматическое обновление, но также блокирует обновления безопасности именно этого пакета. Удержанный nginx с известной CVE никогда не обновится, пока ты явно не снимешь удержание. Правильный паттерн: удерживай на определённый период («пока вендор нашего кастомного модуля не выпустит обновление»), установи напоминание в календаре и снимай удержание как можно скорее. apt-mark showhold должен быть частью еженедельной гигиены сервера, а не неожиданным открытием спустя полгода.

Проверь себя
Викторина

Ты закрепил пакет в /etc/apt/preferences.d/ с Pin-Priority: 900 из backports, и отдельно запустил apt-mark hold для того же пакета. apt upgrade сообщает, что пакет 'kept back'. Какой механизм фактически предотвращает обновление?

Итог

Depends должны быть удовлетворены для установки; Recommends устанавливаются по умолчанию, пропускаемые с --no-install-recommends; Suggests только информационные. Ограничения версий (>=, =, <<) позволяют мейнтейнерам выражать точную совместимость. apt-mark hold замораживает пакет и предотвращает его касание apt upgrade — используй apt-mark showhold для аудита, удержания могут молча блокировать обновления безопасности. Пиннинг через /etc/apt/preferences.d/ назначает числовые приоритеты: по умолчанию 500, backports по умолчанию 100, выше 500 продвигает пакеты репозитория. Пин выше 1000 форсирует понижение версии. Hold против pin: удержание блокирует обновление установленного; пин выбирает, какая версия является кандидатом.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources1
expand
  1. 01

Trademarks belong to their respective owners. Editorial reference only.