Однако вскоре выяснилось, что Docker не запускается. При попытке старта демона появлялась ошибка:
Job for docker.service failed because the control process exited with error code.
Первым подозрением стало повреждение Docker-окружения или конфликт версий. Однако анализ логов через journalctl быстро указал на другую, более глубокую проблему: отсутствие рабочего сетевого экрана. Система не могла применить сетевые правила, необходимые для создания bridge-интерфейсов и проброса портов — критически важных для работы контейнеров.
Дальнейшее расследование показало, что сервис iptables не запускается, хотя пакеты iptables и iptables-services числятся установленными. Более того, сам бинарник /sbin/iptables отсутствовал в привычном месте, а попытки перезапустить фаервол приводили к ошибке:
iptables: /sbin/iptables does not exist.[WARNING]
Так началось расследование, в ходе которого мы столкнулись с тонкостями миграции iptables на nftables, особенностями пакетного менеджмента в RHEL-8-совместимых системах и хрупкостью интеграции между Docker и устаревшими инструментами управления сетью.
? Диагностика: что сломалось и почему
После обновления системы до Rocky Linux 8.10 стало очевидно, что проблема лежит не в Docker, а на более низком уровне — в сетевой подсистеме. Основной симптом — невозможность запуска docker.service — был всего лишь следствием. Корень проблемы указывал на отказ работы iptables, который Docker использует для настройки сетевых правил, NAT и маршрутизации между контейнерами и хостом.
? Первые признаки
Проверка статуса iptables.service показала, что он не запущен:
systemctl status iptables
Вывод указывал на неудачный старт и ошибку:
Job for iptables.service failed because the control process exited with error code.
А в логах через journalctl -xe появлялось тревожное сообщение:
iptables.init[...]: iptables: /sbin/iptables does not exist.[WARNING]
При этом пакет iptables числился установленным:
rpm -q iptables iptables-services
# Вывод: iptables-1.8.5-11.el8.x86_64
Но при попытке найти бинарник:
which iptables
— система не находила его в стандартных путях.
? Парадокс: пакет установлен, а бинарника нет
На первый взгляд — нонсенс. Однако анализ показал, что в RHEL 8 и производных (включая Rocky Linux) после обновлений произошли важные изменения в архитектуре пакета iptables:
Бинарники iptables, iptables-save, iptables-restore больше не являются независимыми исполняемыми файлами.
Они заменены на обёртки через nftables, используя общий бинарник xtables-nft-multi.
Управление версиями (iptables-legacy vs iptables-nft) теперь осуществляется через систему alternatives.
Тем не менее, скрипт инициализации /usr/libexec/iptables/iptables.init, используемый iptables.service, не адаптирован под эту новую реальность. Он ожидает, что /sbin/iptables — это реальный исполняемый файл или простой симлинк, и не распознаёт сложные цепочки симлинков через /etc/alternatives.
? Что ещё усугубило ситуацию
После обновления файл /etc/sysconfig/iptables (в котором хранятся правила фаервола) отсутствовал. Без него iptables.service отказывается стартовать, даже если бинарник доступен.
Система перешла на nftables как бэкенд, но iptables-services продолжает пытаться работать в старом режиме.
firewalld отсутствовал — ни установлен, ни запущен — что означало, что никто не управлял сетевыми правилами, кроме ожидаемого iptables.service.
? Вывод диагностики
Обновление yum update -y привело к:
Переходу на nftables как основной бэкенд.
Повреждению или игнорированию симлинков в /sbin/, из-за чего iptables.init не видит бинарник.
Отсутствию критического файла /etc/sysconfig/iptables.
Падению iptables.service → Docker не может настроить сеть → контейнеры не запускаются.
? Решение: как мы починили iptables
После тщательной диагностики стало ясно: чтобы вернуть Docker к жизни, нужно сначала восстановить работоспособность iptables.service. Проблема была не в отсутствии пакетов, а в некорректной работе симлинков и несоответствии ожиданий скрипта инициализации новой архитектуре nftables.
Вот пошаговое решение, которое нас выручило.
✅ Шаг 1: Убедились, что бинарник xtables-nft-multi на месте
Сначала проверили, что реальный исполняемый файл существует:
ls -l /usr/sbin/xtables-nft-multi
Вывод:
-rwxr-xr-x 1 root root 226104 Nov 16 2023 /usr/sbin/xtables-nft-multi
✅ Отлично — бинарник есть. Это единый бинарник, который реализует iptables, ip6tables, arptables и ebtables через nftables.
✅ Шаг 2: Настроили alternatives на использование iptables-nft
Система alternatives управляет тем, какая версия iptables используется по умолчанию. Проверили текущее состояние:
alternatives --display iptables
Убедились, что активна версия iptables-nft, и принудительно переключились на неё:
alternatives --set iptables /usr/sbin/iptables-nft
Теперь команда iptables использует nftables как бэкенд.
✅ Шаг 3: Восстановили симлинки в /sbin
Ключевая проблема: /sbin/iptables был симлинком, ведущим через /etc/alternatives, а старый скрипт iptables.init не умеет с этим работать.
Решение — создать прямые симлинки в /sbin, чтобы скрипт видел исполняемые файлы:
rm -f /sbin/iptables /sbin/iptables-save /sbin/iptables-restore
ln -s /usr/sbin/xtables-nft-multi /sbin/iptables
ln -s /usr/sbin/xtables-nft-multi /sbin/iptables-save
ln -s /usr/sbin/xtables-nft-multi /sbin/iptables-restore
Теперь /sbin/iptables — это прямой симлинк на xtables-nft-multi, и iptables.init его "видит".
✅ Шаг 4: Создали пустой файл с правилами
Скрипт iptables.init требует наличие файла /etc/sysconfig/iptables. Даже если правил нет — файл должен быть:
touch /etc/sysconfig/iptables
Без этого systemctl start iptables гарантированно падает.
✅ Шаг 5: Запустили iptables.service
systemctl start iptables
systemctl status iptables
Результат:
● iptables.service - IPv4 firewall with iptables
Loaded: loaded (/usr/lib/systemd/system/iptables.service; disabled; vendor preset: disabled)
Active: active (exited) since Sat 2025-08-09 13:41:05 MSK
✅ Успех! Сервис запущен, правила применены (даже если пустые), и Docker теперь может настраивать сеть.
? Почему это сработало
Мы обошли ограничения старого скрипта инициализации, создав симлинки в том виде, который он ожидает.
Мы сохранили современную архитектуру nftables, не возвращаясь к устаревшему iptables-legacy.
Мы удовлетворили требования iptables.service к наличию бинарника и файла правил.
? Финальный этап: запуск Docker и восстановление контейнеров
С iptables на месте казалось, что теперь Docker должен запуститься без проблем. Однако при попытке включить сервис:
systemctl start docker
— мы снова столкнулись с ошибкой:
Job for docker.service failed because the control process exited with error code.
А в логах через journalctl -xe увидели цикличное повторение:
docker.service: Start request repeated too quickly.
Система пыталась перезапустить Docker, он падал — и systemd блокировал дальнейшие попытки.
? Почему Docker не запускается?
Анализ показал, что проблема уже не в сетевых правилах, а в состоянии файловой системы.
После обновления и аварийного завершения работы Docker остался в "грязном" состоянии:
Некоторые контейнеры были запущены в момент обновления.
Их overlay-тома остались смонтированными, хотя сами процессы завершились.
При перезапуске dockerd пытается восстановить состояние — но не может размонтировать старые тома.
Вывод команды df -h подтвердил догадку:
overlay on /var/lib/docker/overlay2/.../merged type overlay (rw,relatime,...)
→ Несколько overlay-томов всё ещё были смонтированы, хотя Docker не работал.
✅ Шаг 1: Остановили Docker и containerd
systemctl stop docker containerd
При необходимости — принудительно убили процессы:
pkill dockerd
pkill containerd
✅ Шаг 2: Размонтировали все зависшие overlay-тома
Выполнили команду, чтобы размонтировать все точки, связанные с Docker:
for mount in $(mount | grep /var/lib/docker/overlay2 | awk '{print $3}'); do
umount "$mount"
done
Это безопасно, если контейнеры не работают — система "забудет" старое состояние, но при старте Docker восстановит актуальные контейнеры.
✅ Шаг 3: Перезапустили Docker
systemctl start docker
systemctl status docker
И — успех! Сервис запустился без ошибок.
✅ Шаг 4: Проверили, что контейнеры поднялись docker ps. Вывод:
CONTAINER ID IMAGE ... STATUS PORTS NAMES
60682eae8f57 elite-webserver ... Up 4 seconds 0.0.0.0:8882->80/tcp elite-webserver
60682eae8f57 gkds-webserver ... Up 4 seconds 0.0.0.0:8883->80/tcp gkds-webserver
...
✅ Все контейнеры — на месте, порты проброшены, сервисы доступны.
? Почему помогла бы перезагрузка?
Позже мы поняли, что простая перезагрузка сервера решила бы проблему быстрее. При загрузке:
Все overlay-тома снимаются.
iptables запускается с чистого листа.
Docker стартует в корректном окружении.
Но ручное решение дало нам глубокое понимание того, как устроена интеграция Docker, iptables и nftables — и теперь мы знаем, как чинить подобное без перезагрузки.
? Выводы и рекомендации
После долгого пути — от паники при падении Docker до глубокого погружения в архитектуру iptables, nftables и overlay-файловых систем — мы восстановили работоспособность сервера. Но главное — получили ценный опыт, который поможет избежать подобных инцидентов в будущем.
✅ Что мы выяснили
Обновление yum update -y на RHEL-совместимых системах может быть опасным
Особенно если оно затрагивает ключевые компоненты, такие как iptables, systemd, firewalld или containerd. Переход с 8.9 на 8.10 выглядел как патч-релиз, но на деле включил смену бэкенда сетевого экрана — с iptables-legacy на nftables.
iptables-services несовместим с современной моделью nftables
Скрипт инициализации /usr/libexec/iptables/iptables.init не умеет работать с alternatives и ожидает, что /sbin/iptables — это реальный бинарник. Это устаревшее поведение, но оно всё ещё стандартное для iptables-services.
Docker полностью зависит от состояния iptables
Без рабочего сетевого экрана он не может настроить bridge, NAT и проброс портов. Даже если containerd работает — dockerd не стартует.
Остатки overlay-томов могут блокировать перезапуск Docker
После аварийного завершения или обновления overlay-файловые системы могут остаться смонтированными, и dockerd не сможет восстановить состояние.
? Рекомендации
Никогда не обновляй yum update -y на продакшен-серверах без резервной копии
Даже если это «мелкое обновление». Версия 8.10 — не 9.0, но она может сломать всё.
Перед обновлением проверь, какие сервисы используют iptables
Docker, L2TP, OpenVPN, WireGuard — все они чувствительны к изменениям в фаерволе.
После обновления проверяй статус ключевых сервисов вручную
Не полагайся на автозагрузку. Проверь:
systemctl status iptables firewalld docker containerd
Используй nft list ruleset, а не iptables -L, на новых системах
Чтобы видеть реальное состояние фаервола.
Если используешь iptables.service — убедись, что /etc/sysconfig/iptables существует
Даже если он пустой.
Рассмотри переход на firewalld или nftables напрямую
Они лучше интегрированы с современной сетевой моделью и не конфликтуют с Docker.
? Крик души
Хочется высказать послать лучи добра тем, кто принимает решения в мире open-source.
Когда я обновляю систему с 8.9 до 8.10, я ожидаю исправление уязвимостей, стабильность, может быть — новые драйверы.
Я не ожидаю, что после этого сутки буду разбираться, почему перестал работать Docker.
Я не ожидаю, что изменится фундаментальная модель работы сетевого экрана без предупреждения, без миграционных скриптов, без хотя бы строки в RELEASE-NOTES.
Я консерватор, я люблю iptables! Да, nftables — это будущее. Да, iptables-legacy устарел.
Но если вы хотите его заменить — сделайте это в major-версии.
Не подсовывайте пользователям «совершенно новую систему» под видом «мелкого обновления».
Такие вещи ломают доверие.
Они заставляют админов бояться yum update, а не радоваться ему.
Они превращают рутинное обслуживание в квест с риском для бизнеса.
Мы не против прогресса.
Мы против того, чтобы платить за него стабильностью, временем и нервами.
? Заключение
Этот инцидент — не просто «ещё одна ошибка на сервере».
Это предупреждение: даже зрелые дистрибутивы могут вести себя непредсказуемо.
Но если понимать, как устроена система под капотом, — можно не только починить, но и понять, как сделать её устойчивее.
А мы тем временем добавили в мониторинг проверку статуса iptables и docker, настроили регулярные бэкапы конфигов и… проверили, что автоматические обновления везде отключены.
Потому что доверие нужно заслуживать.
С уважением,
Владимир Драч
(автор сайта drach.pro)
Дискуссия
Написал Владимир
Опубликовано в: Установка nginx c PHP-FPM под CentOS 7.0 in LinuxНаписал Rocky 9
Опубликовано в: Установка nginx c PHP-FPM под CentOS 7.0 in LinuxНаписал Константин
Опубликовано в: Докеризация стека LEMP под Ubuntu c помощью Compose in LinuxНаписал bammbr
Опубликовано в: Шлюз для маленького отдела на Red Hat 9 in LinuxНаписал Федор
Опубликовано в: Установка и конфигурация Samba на CentOS 7 in Linux