Ви перезавантажуєте вузол Proxmox, і він повертається з тим самовпевненим сірим рядком:
Dependency failed for …. Веб-інтерфейс недоступний, віртуальні машини зупинені, і ви дивитесь на консоль, яка фактично каже:
«Щось інше не відбулося, тому й я не запустився».
Підступ у тому, що юніт, показаний на екрані, часто є жертвою, а не винуватцем. systemd повідомляє, що не змогло запуститися,
а не що спричинило ланцюгову реакцію. Цей посібник пояснює, як знайти перше доміно — швидко, повторювано і без гадань.
Ментальна модель: що насправді означає «Dependency failed»
systemd — це рушій залежностей з потягом до логування. Він запускає юніти (сервіси, mount-и, пристрої, таргети) на основі заявлених відносин
(Requires=, Wants=, After=, Before=, плюс неявні зв’язки від mount-юнітів, device-юнітів
і генераторів).
Повідомлення про «Dependency failed» для юніта X означає, що одна з вимог юніта X перейшла в стан failed
(або не з’явилась у межах таймауту). Це може бути:
- Сервіс, який зазнав невдачі (ненульовий код виходу, таймаут, watchdog, відсутня конфігурація).
- Mount, який не примонтувався (пошкоджена файлова система, відсутній пристрій, неправильний UUID, ZFS/LVM не імпортовано).
- Device-юніт, який ніколи не з’явився (вилучений диск, HBA з проблемною прошивкою).
- Target, досягнення якого неможливе через невдачу необхідного для нього юніта.
Рядок, що ви бачите на консолі, майже завжди є downstream. Ваше завдання — рухатись upstream, поки не знайдете перший юніт, що зазнав невдачі, і поставити собі запитання:
це реальна помилка (поломка), чи проблема порядку запуску (неправильні залежності)?
Одне міркування, яке варто тримати в голові, приписується Джону Голлу (перефразована ідея): «Складні системи, що працюють, зазвичай еволюціонували з простіших систем, що працювали».
Якщо ваше завантаження складне, налагоджуйте його як еволюцію: знайдіть найранішу невдачу, а не останній симптом.
Швидкий план діагностики (перші/другі/треті перевірки)
Якщо це продакшн і ви втрачаєте хвилини, робіть це в порядку. Мета — визначити перший юніт, що зазнав невдачі, і чи це сховище, мережа, кластер чи проста конфігураційна помилка.
Перший крок: перелічити невдачі й переглянути найранішу
cr0x@server:~$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● pve-cluster.service loaded failed failed The Proxmox VE cluster filesystem
● zfs-import-cache.service loaded failed failed Import ZFS pools by cache file
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
Рішення: якщо є лише один-два failed юніти, почніть з того, що виглядає найфундаментальнішим (імпорт сховища, mount, network-online). Якщо їх багато, «фундаментальний» майже завжди — перша невдача.
Другий крок: читайте журнали попереднього завантаження, а не поточної сесії shell
cr0x@server:~$ journalctl -b -0 -p err..alert --no-pager | head -n 50
Dec 26 09:14:03 server systemd[1]: zfs-import-cache.service: Failed with result 'exit-code'.
Dec 26 09:14:03 server systemd[1]: Failed to start Import ZFS pools by cache file.
Dec 26 09:14:03 server systemd[1]: Dependency failed for ZFS Mount.
Dec 26 09:14:03 server systemd[1]: Dependency failed for Proxmox VE firewall.
Рішення: віддавайте пріоритет першому рядку «Failed to start …». Пізніші «Dependency failed for …» записи — це downstream.
Третій крок: намалюйте ланцюг залежностей для юніта-жертви
cr0x@server:~$ systemctl list-dependencies --reverse pve-firewall.service
pve-firewall.service
● pve-container.service
● pve-guests.service
● multi-user.target
Рішення: якщо жертва — «листовий» сервіс (файрвол, UI, керування гостьовими), перестаньте закидати на нього провину. Пройдіться вгору до залежності, яка фактично зазнала невдачі (імпорт сховища, mount, network-online).
Евристика заощадження часу: сховище перед кластером перед мережею перед «випадковим сервісом»
На вузлах Proxmox блокувальники завантаження збираються в чотири відра:
імпорт сховища (ZFS/LVM), mount-и (включаючи /var/lib/vz),
кластерна файлова система (pve-cluster, corosync) і готовність мережі.
Сервіси рівня застосунків зазвичай падають, бо один із цих елементів не відбувся.
Жарт №1: systemd як дуже суворий бібліотекар — якщо ви пошепки скажете «After=network-online.target», не впорядкувавши це правильно, він присоромить ваше завантаження.
Цікаві факти та історичний контекст (для кращої інтуїції)
- systemd замінив SysV init у більшості дистрибутивів Linux на початку 2010-х, принісши паралельний старт і явні графи залежностей замість упорядкування в шелл-скриптах.
- «After=» не є вимогою. Воно лише задає порядок запуску. Люди досі плутають його з
Requires=, і з цього народжуються помилки завантаження. - Mount-и — це повноцінні юніти. systemd генерує
.mountюніти з/etc/fstab, і вони стають залежностями для сервісів, яким вони потрібні. - Device-юніти з’являються динамічно. Відсутній диск не «падає»; він просто ніколи не з’являється. Downstream юніти тоді чекають таймаут і це виглядає як помилка сервісу.
- ZFS на Linux використовує сервіси імпорту (
zfs-import-cache/zfs-import-scan) для піднімання пулів під час завантаження; відсутні кеш-файли або перейменовані пули можуть зупинити все, що залежить від mount-ів. - Proxmox опирається на /etc/pve, кластерну файлову систему, яку надає pmxcfs. Якщо pmxcfs не змонтовано, велика частина стека управління не може читати конфіг.
- Поняття «мережа онлайн» є дискусійним. Різні дистрибутиви постачають різні wait-online сервіси. Увімкнення невірного може додати затримок або створити deadlock, коли залучені мости/VLAN-и.
- Зміни в initramfs бувають делікатними. Відсутній модуль в initramfs може перетворити нормальний кореневий диск у «не знайдено», і повідомлення про помилку завантаження виглядатиме неочевидним.
- systemd давно вміє показувати критичний шлях за часом. Це один з найшвидших способів виявити вузьке місце завантаження, що не обов’язково «падає».
Практичні завдання: команди, очікуваний вивід, рішення
Це перевірки з практики. Кожна містить команду, що означає її вивід, і що робити далі.
Не виконувати все підряд; обирайте ті, що відповідають домену невдачі, який ви бачите.
Завдання 1: Перелік невдалих юнітів (очевидна відправна точка)
cr0x@server:~$ systemctl --failed --no-pager
UNIT LOAD ACTIVE SUB DESCRIPTION
● zfs-mount.service loaded failed failed Mount ZFS filesystems
● pveproxy.service loaded failed failed PVE API Proxy Server
2 loaded units listed.
Значення: pveproxy ймовірно колатеральний збиток. zfs-mount — фундаментальний.
Рішення: інспектуйте zfs-mount перед проксі.
Завдання 2: Перегляд статусу юніта, що впав (статус містить останні логи)
cr0x@server:~$ systemctl status zfs-mount.service --no-pager -l
× zfs-mount.service - Mount ZFS filesystems
Loaded: loaded (/lib/systemd/system/zfs-mount.service; enabled)
Active: failed (Result: exit-code) since Thu 2025-12-26 09:14:03 UTC; 1min 2s ago
Process: 812 ExecStart=/sbin/zfs mount -a (code=exited, status=1/FAILURE)
Main PID: 812 (code=exited, status=1/FAILURE)
Dec 26 09:14:03 server zfs[812]: cannot mount 'rpool/data': failed to create mountpoint: /rpool/data
Dec 26 09:14:03 server systemd[1]: zfs-mount.service: Failed with result 'exit-code'.
Значення: невдача чітко вказана: ZFS не може створити mountpoint.
Рішення: перевірте, чи mountpoint не доступний для запису тільки для читання, чи не відсутній кореневий mount, або чи не блокує його конфлікт директорії/файлу.
Завдання 3: Визначити першу невдачу в хронології завантаження
cr0x@server:~$ journalctl -b -0 --no-pager | grep -E "Failed to start|Dependency failed" | head -n 30
Dec 26 09:14:02 server systemd[1]: Failed to start Import ZFS pools by cache file.
Dec 26 09:14:03 server systemd[1]: Dependency failed for ZFS Mount.
Dec 26 09:14:03 server systemd[1]: Failed to start Mount ZFS filesystems.
Dec 26 09:14:03 server systemd[1]: Dependency failed for Proxmox VE cluster filesystem.
Значення: zfs-import-cache впав першим. Решта — каскадні помилки.
Рішення: перегляньте логи zfs-import-cache.service.
Завдання 4: Глибоке занурення в логи юніта через journalctl
cr0x@server:~$ journalctl -u zfs-import-cache.service -b -0 --no-pager -l
Dec 26 09:14:02 server systemd[1]: Starting Import ZFS pools by cache file...
Dec 26 09:14:02 server zpool[771]: cannot open '/etc/zfs/zpool.cache': No such file or directory
Dec 26 09:14:02 server systemd[1]: zfs-import-cache.service: Main process exited, code=exited, status=1/FAILURE
Dec 26 09:14:02 server systemd[1]: zfs-import-cache.service: Failed with result 'exit-code'.
Значення: відсутній кеш-файл. Не завжди фатально, якщо є zfs-import-scan, але граф залежностей може вимагати саме кеш-імпорт.
Рішення: перевірте, чи ввімкнений scan-імпорт, або відновіть кеш із робочого імпорту.
Завдання 5: Перевірити, чи пули ZFS взагалі доступні для імпорту
cr0x@server:~$ zpool import
pool: rpool
id: 1234567890123456789
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
rpool ONLINE
mirror-0 ONLINE
sda3 ONLINE
sdb3 ONLINE
Значення: пул існує й здоровий, але не імпортований.
Рішення: спробуйте ручний імпорт (спочатку readonly, якщо підозрюєте пошкодження), потім виправте конфігурацію імпорту під час завантаження.
Завдання 6: Ручний імпорт (обережно, але ефективно для діагностики)
cr0x@server:~$ sudo zpool import -N rpool
cr0x@server:~$ zpool status rpool
pool: rpool
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda3 ONLINE 0 0 0
sdb3 ONLINE 0 0 0
errors: No known data errors
Значення: імпорт працює. Збій при завантаженні ймовірно конфігураційний/порядок запуску (файл кешу, увімкнений юніт), а не фізична поломка дисків.
Рішення: відновіть /etc/zfs/zpool.cache і переконайтесь, що увімкнено правильний юніт імпорту.
Завдання 7: Перевірити блокування на wait-online/мережу
cr0x@server:~$ systemd-analyze blame | head -n 15
1min 32.104s systemd-networkd-wait-online.service
8.771s pve-cluster.service
4.210s zfs-mount.service
2.018s networking.service
Значення: завантаження не стільки «падає», скільки зависає на «network online».
Рішення: підтвердіть, чи вузлу справді потрібен «online» (часто ні). Якщо служби Proxmox помилково вимагають цього, виправте залежності або конфігурацію.
Завдання 8: Показати критичний ланцюг завантаження для конкретного таргету
cr0x@server:~$ systemd-analyze critical-chain multi-user.target
multi-user.target @1min 42.909s
└─pve-guests.service @1min 42.870s +37ms
└─pve-cluster.service @1min 33.982s +8.884s
└─network-online.target @1min 32.111s
└─systemd-networkd-wait-online.service @0min 0.008s +1min 32.104s
Значення: «критичний ланцюг» показує, що фактично затримало досягнення таргету.
Рішення: налаштуйте wait-online сервіс або приберіть вимогу, якщо вона не потрібна для успішного завантаження.
Завдання 9: Переглянути залежності юніта, показаного як «Dependency failed»
cr0x@server:~$ systemctl show -p Requires -p Wants -p After -p Before pve-cluster.service
Requires=system.slice basic.target
Wants=corosync.service
After=network.target syslog.target corosync.service
Before=
Значення: pve-cluster хоче corosync і стартує після нього, але тут явно не вимагає network-online.
Затримка може бути в іншому місці, або інший юніт підтягує network-online.
Рішення: пройдіть фактичний ланцюг з systemd-analyze critical-chain і перевірте drop-in файли.
Завдання 10: Знайти drop-in переоприділення (де ховаються «корисні» зміни)
cr0x@server:~$ systemctl cat pve-cluster.service
# /lib/systemd/system/pve-cluster.service
[Unit]
Description=The Proxmox VE cluster filesystem
After=network.target corosync.service
Wants=corosync.service
[Service]
Type=forking
ExecStart=/usr/bin/pmxcfs -l
ExecStop=/usr/bin/killall -TERM pmxcfs
Restart=on-failure
# /etc/systemd/system/pve-cluster.service.d/override.conf
[Unit]
After=network-online.target
Wants=network-online.target
Значення: хтось додав drop-in, який змушує pve-cluster чекати на «online».
Рішення: вирішіть, чи це обґрунтовано. У більшості Proxmox-налаштувань це не потрібно; віддавайте перевагу network.target, якщо вам не потрібне маршрутизоване підключення під час завантаження.
Завдання 11: Підтвердити, що саме означає «network-online» на вашій машині
cr0x@server:~$ systemctl status network-online.target --no-pager -l
● network-online.target - Network is Online
Loaded: loaded (/lib/systemd/system/network-online.target; static)
Active: active since Thu 2025-12-26 09:14:00 UTC; 4min ago
Docs: man:systemd.special(7)
Dec 26 09:14:00 server systemd[1]: Reached target Network is Online.
Значення: таргет задовольняється, коли його «wait» сервіс задоволено. Який саме wait сервіс залежить від вашого мережевого стеку.
Рішення: перевірте, чи ви використовуєте systemd-networkd, NetworkManager або ifupdown, і вимкніть невідповідний wait-online юніт.
Завдання 12: Перевірити mount-и сховища, прив’язані до Proxmox (fstab і mount-юніти)
cr0x@server:~$ findmnt -rno TARGET,SOURCE,FSTYPE,OPTIONS /var/lib/vz
/var/lib/vz rpool/data/subvol-100-disk-0 zfs rw,xattr,noacl
Значення: шляхи сховища Proxmox існують і підкріплені очікуваною файловою системою.
Рішення: якщо цього немає або неправильно, виправте імпорт/mount ZFS/LVM перед тим, як торкатися Proxmox-сервісів.
Завдання 13: Переглянути fstab на наявність блокувальників завантаження (погані UUID, застарілі mount-и)
cr0x@server:~$ grep -vE '^\s*#|^\s*$' /etc/fstab
UUID=2f1f9e2d-aaaa-bbbb-cccc-5f9b9d1d2e3f / ext4 defaults 0 1
UUID=deadbeef-1111-2222-3333-444444444444 /mnt/backup ext4 defaults 0 2
Значення: mount як /mnt/backup може блокувати завантаження, якщо диск зник.
Рішення: якщо це не критично, додайте nofail і розумний x-systemd.device-timeout=, або видаліть запис.
Завдання 14: Підтвердити, чи існує відсутній пристрій
cr0x@server:~$ lsblk -o NAME,SIZE,FSTYPE,UUID,MOUNTPOINT
NAME SIZE FSTYPE UUID MOUNTPOINT
sda 447.1G
├─sda1 512M vfat 8A1B-2C3D /boot/efi
├─sda2 1G ext4 0b7c9c2f-1234-5678-90ab-7e1f2c3d4e5f /boot
└─sda3 445.6G zfs_member
sdb 447.1G
└─sdb3 445.6G zfs_member
Значення: якщо UUID у fstab тут не з’являється, mount зазнає невдачі.
Рішення: виправити UUID, перевірити кабелі/HBA або позначити mount як nofail, якщо він необов’язковий.
Завдання 15: Перевірити стан pmxcfs і /etc/pve (специфічно для Proxmox)
cr0x@server:~$ mount | grep -E "/etc/pve|pmxcfs"
pmxcfs on /etc/pve type fuse.pmxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
Значення: якщо /etc/pve не змонтовано, конфіг Proxmox недоступний; багато сервісів «таємниче» падають.
Рішення: виправте pve-cluster.service перед тим, як ганятися за помилками pveproxy/pvedaemon.
Завдання 16: Перевірити corosync без здогадок
cr0x@server:~$ systemctl status corosync.service --no-pager -l
● corosync.service - Corosync Cluster Engine
Loaded: loaded (/lib/systemd/system/corosync.service; enabled)
Active: active (running) since Thu 2025-12-26 09:14:01 UTC; 6min ago
Значення: якщо corosync впав, pve-cluster може зависнути або зазнати невдачі, залежно від конфігурації.
Рішення: перегляньте логи corosync і мережу (multicast/unicast, ring-інтерфейси), але не «перезапускайте все підряд» без плану.
Завдання 17: Знайти, який юніт підключив таргет (хто «хотів» його)
cr0x@server:~$ systemctl list-dependencies --reverse network-online.target
network-online.target
● pve-cluster.service
● pvescheduler.service
● zfs-import.target
Значення: ці юніти примушують semantics «online».
Рішення: перегляньте, чи кожному справді це потрібно; видаліть drop-in, що додають непотрібне очікування.
Завдання 18: Перевірити вихід генератора (перетворення fstab у юніти)
cr0x@server:~$ systemctl status mnt-backup.mount --no-pager -l
× mnt-backup.mount - /mnt/backup
Loaded: loaded (/run/systemd/generator/mnt-backup.mount; generated)
Active: failed (Result: exit-code) since Thu 2025-12-26 09:14:05 UTC; 2min ago
Where: /mnt/backup
What: /dev/disk/by-uuid/deadbeef-1111-2222-3333-444444444444
Dec 26 09:14:05 server mount[901]: mount: /mnt/backup: special device /dev/disk/by-uuid/deadbeef-1111-2222-3333-444444444444 does not exist.
Значення: mount-юніт згенерований з fstab і падає, бо пристрій відсутній.
Рішення: або відновіть шлях/UUID, або зробіть mount опціональним (nofail плюс таймаут).
Завдання 19: Перевірити initramfs і розпізнавання кореневого пристрою (коли завантаження справді поламано)
cr0x@server:~$ lsinitramfs /boot/initrd.img-$(uname -r) | grep -E "zfs|dm_mod|nvme" | head
usr/lib/modules/6.8.12-4-pve/kernel/drivers/md/dm-mod.ko
usr/lib/modules/6.8.12-4-pve/kernel/drivers/nvme/host/nvme.ko
usr/lib/modules/6.8.12-4-pve/updates/dkms/zfs.ko
Значення: критичні модулі присутні в initramfs. Якщо їх немає, ядро не знайде диски на ранньому етапі.
Рішення: перебудуйте initramfs і перевірте DKMS-модулі, особливо після оновлень ядра.
Завдання 20: Перегенерувати initramfs (тільки після того, як з’ясували, чого бракує)
cr0x@server:~$ sudo update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-6.8.12-4-pve
W: Possible missing firmware /lib/firmware/i915/tgl_dmc_ver2_12.bin for module i915
Значення: попередження про прошивку GPU зазвичай неактуальні для серверів; відсутня прошивка для сховища/мережі — серйозно.
Рішення: якщо бачите відсутню прошивку для сховища/мережі, виправте це перед наступним перезавантаженням. Інакше продовжуйте.
Звідки зазвичай походять збої завантаження Proxmox
Коли Proxmox «не завантажується», ядро, ймовірно, завантажилось нормально. systemd працює. Проблема в тому, що система не досягла таргету, який
включає сервіси управління. Proxmox додає кілька особливих точок напруги:
1) Імпорт сховища та mount-и
Вузли Proxmox майже завжди залежать від локального сховища на ранньому етапі: ZFS пули, LVM volume group-и або обидва. Якщо сховище не імпортовано,
mount-юніти падають, а сервіси, що читають конфіг або зберігають стан, не запускаються. Відсутність UI — симптом, а не причина.
Слід звертати увагу на:
- Невдачі імпорту ZFS через відсутній
/etc/zfs/zpool.cache, перейменовані пули або змінені шляхи пристроїв. - Проблеми LVM через відсутні PV або активацію VG.
- Записи fstab для зовнішніх резервних дисків, які «опціональні», поки раптом не перестають працювати.
2) /etc/pve і pmxcfs
/etc/pve — не звичайна директорія. Це FUSE-файлова система, яку надає pmxcfs і яку контролює pve-cluster.service.
Якщо pmxcfs не змонтовано, багато інструментів Proxmox поводяться так, ніби конфігурація зникла.
Консоль із задоволенням скаже «Dependency failed for Proxmox VE API Proxy Server.»
Це правда, але не корисно. Проксі залежить від конфігів та сертифікатів. Немає /etc/pve — немає роботи проксі.
3) Припущення corosync
У кластері corosync — це спосіб, яким вузли погоджують членство. Вузол може працювати як одиночний, але наявність кластерної конфігурації змінює поведінку завантаження.
Неправильні ring-інтерфейси, нова назва NIC після заміни обладнання або занадто сувора залежність від «network-online» можуть затримати кластерні юніти.
4) network-online target і «корисне» упорядкування завантаження
Мережевий стек — багаторівневий: лінк піднімається, адреси застосовуються, з’являються маршрути, DNS може працювати, і лише тоді у вас з’являється «online».
network.target зазвичай означає «базова мережа налаштована», а не «інтернет доступний».
Якщо хтось змусив сервіси Proxmox вимагати network-online.target, можна створити deadlock, коли wait-online чекає на міст/VLAN,
який створюється сервісом, що сам чекає на network-online. Вітаємо, ви винайшли циклічну залежність.
Жарт №2: Цикл залежностей — єдиний випадок, коли ваш сервер вдало моделює організаційну структуру корпорації.
Полювання на кореневий юніт: ланцюги, порядок і чому очі брешуть
Найпоширеніша помилка оператора в цих інцидентах — ставитися до повідомлення на екрані як до кореневої причини. systemd виводить «Dependency failed for X»,
бо X був поставлений у чергу і потім скасований. Це як менеджер проєкту, що каже «демо скасовано» без згадки про відключення електрики.
Починайте з «failed units», але не зупиняйтесь на цьому
systemctl --failed необхідний, але не достатній. Він показує, що завершилося невдачею. Але юніт, що має значення, може бути:
- Mount-юнітом, згенерованим з fstab (
something.mount). - Device-юнітом, який ніколи не з’явився (немає явного стану «failed»; натомість щось таймаутито).
- One-shot юнітом, який впав рано і загубився в логах.
Віддавайте перевагу «critical-chain» замість «blame», коли підозрюєте порядок
systemd-analyze blame перелічує час, витрачений у юнітах, що корисно для повільного завантаження. Але це може вводити в оману, якщо юніт чекав на інший юніт.
Критичний ланцюг показує реальний шлях залежностей до таргету.
Якщо ви застрягли при завантаженні і щось чекає вічно, запитайте:
- До якого таргету я намагаюсь дійти? Зазвичай
multi-user.targetна серверах. - Який юніт останній у критичному ланцюгу?
- На що цей юніт чекає? (status + journal)
Розумійте три осі залежностей: вимога, порядок і відношення
systemd має відносини, що звучать схоже, але поводяться по-різному:
- Requires=: якщо потрібний юніт зазнає невдачі, цей юніт також впаде.
- Wants=: слабка залежність; підтягує юніт, але не робить помилку фатальною для залежного при її падінні.
- After=/Before=: лише порядок. Ніякої вимоги.
Багато інцидентів «dependency failed» походять від адмінів, які додають After= без Wants= або Requires=, очікуючи,
що systemd автоматично запустить щось. Не запустить.
Коли реальний винуватець — mount або пристрій
Якщо сервіс має RequiresMountsFor=/var/lib/vz (або неявну залежність через використання шляху), і цей mount відсутній, systemd відмовиться його запускати.
Сервіс не «зламався». Він діє обачно.
Найкращий трюк: перевірте статус .mount юніта і логи. Вони часто більш явні, ніж лог сервісу.
Коли реальний винуватець — таймаут
Деякі повідомлення «Dependency failed» з’являються тому, що залежність не впала явно — вона просто ніколи не стала активною.
Наприклад: device-юніт ніколи не з’явився, бо диск не енумерувався. Тоді mount чекає, таймаутиться, падає, і це ламає сервіс.
У таких випадках важливі ранні рядки логів: повідомлення ядра, udev, помилки драйвера сховища або затримки прошивки. Не ігноруйте dmesg.
cr0x@server:~$ dmesg --level=err,warn | tail -n 30
[ 7.112345] sd 2:0:0:0: [sdc] tag#23 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[ 7.112400] blk_update_request: I/O error, dev sdc, sector 0 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0
Рішення: якщо бачите помилки транспорту, припиніть редагувати systemd-юніти і почніть перевіряти кабелі/HBA/стан дисків.
Три корпоративні міні-історії з практики
Міні-історія 1: Інцидент через хибне припущення
Середня компанія мала двовузловий Proxmox-кластер на віддалених сайтах. Вузли були стабільні й майже не чіпані — поки не прийшов мережевий апгрейд.
Команда замінила комутатор і поправила VLAN-и. Вузли повернулись, але один залишився «напівзавантаженим». На консолі було «Dependency failed for Proxmox VE API Proxy Server».
Природно, перша реакція — перезапустити pveproxy. Потім pvedaemon. Потім corosync. Потім вузол перезавантажили знову, бо перезавантаження — спосіб життя.
Хибне припущення: «pveproxy — проблема, бо користувачі бачать саме його». Насправді ні. Справжнім винуватцем був drop-in, доданий місяці тому
до pve-cluster.service, який вимагав After=network-online.target та Wants=network-online.target.
Комутатор затримував DHCP на управлінському VLAN, який узагалі не мав використовувати DHCP.
systemd-networkd-wait-online чекав на адресу, яка так і не з’явилася. Це не дало network-online.target,
що заблокувало pve-cluster, що не дозволило pmxcfs змонтувати /etc/pve, що завадило pveproxy зчитати конфіг.
Повідомлення «Dependency failed» було точним, але звинувачувало невинного спостерігача.
Виправлення було приземленим: видалили override, повернули інтерфейс управління на статичну адресу і прийняли, що network.target достатній
для більшості локальних сервісів. Також додали перевірку при зміні мережі: підтвердити, що «online» означає те, що ви думаєте. Зазвичай — ні.
Міні-історія 2: Оптимізація, яка відбилася боком
Інша організація мала звичку: прискорити завантаження, «спростивши залежності». Хтось помітив, що вузол завантажується 90 секунд через відсутній
резервний диск у fstab. Додали nofail. Добрий початок. Потім пішли далі і додали агресивні таймаути скрізь, включно з імпортом ZFS, бо «таймаути — погано».
Вони також відключили zfs-import-cache і покладалися на scan-імпорт, як більш «гнучкий». На папері — так.
На практиці scan-імпорт інколи давав затримки при зміні мультипасу після оновлень прошивки. Іноді пул імпортувався трохи пізніше, що було б нормально —
якщо б вони не скоротили таймаути для mount-ів і сервісів, що від них залежать.
Результат: періодичні помилки при завантаженні. Не кожного разу, а це найгірше. Mount-и таймаутились, ZFS імпортувався згодом, але система вже провалила критичні юніти.
Перезавантаження інколи вирішувало проблему, що заохочувало команду продовжувати перезавантажувати, поки пощастить. Це не інженерія надійності; це бажання.
Відновлення полягало у скасуванні «оптимізації» і ставленні до залежностей завантаження як до угоди. Якщо сховище потрібне — дозвольте йому чекати достатньо довго.
Якщо диск опціональний — позначайте його опціональним, але не скорочуйте таймаути для ресурсів, що обов’язкові. Завантаження має бути детермінованим, а не перегонами.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
Одна корпоративна команда працювала з Proxmox вузлами на ZFS mirror-ах і невеликій локальній LVM для тимчасових даних. Вони мали політику:
будь-яка зміна, що зачіпає залежності завантаження, вимагала валідацію на консолі, знімок override-ів сервісів і збережений «золотий лог» завантаження.
Люди скаржилися, що це бюрократія.
Потім була ніч на чергуванні. Оновлення ядра принесло новий initramfs, і DKMS збірка для ZFS тихо впала через відсутній пакет заголовків після зміни репозиторію.
Вузол перезавантажився і впав у стан, де ZFS-модулі не були доступні в ранньому етапі. Імпорт сховища впав,
mount-и зазнали невдачі, сервіси Proxmox каскадно впали.
Нудна практика окупилася. Вони порівняли «золотий лог» з поточним через journalctl -b -1 і побачили рядок про невдачу DKMS в попередньому запуску.
Також у них був збережений список увімкнених юнітів і override-ів, тож вони відкинули версію «хтось змінив systemd-залежності».
Усунення було швидким: встановити відсутні заголовки, перебудувати DKMS, перегенерувати initramfs, перезавантажити. Без драм, без випадкових перезапусків сторонніх сервісів.
Постмортем теж був нудний: зберегти політику. Нудно — добре, коли ваша робота — тримати чиїсь захоплюючі ідеї подалі від продакшну.
Типові помилки: симптом → корінна причина → виправлення
Ось бібліотека патернів. Якщо впізнали симптом — пропускайте гадання.
1) «Dependency failed for Proxmox VE API Proxy Server»
- Симптом: pveproxy/pvedaemon не запускаються; UI недоступний.
- Корінна причина:
/etc/pveне змонтовано (pmxcfs впав), або відсутні сховища/mount-и. - Виправлення: перевірте
pve-cluster.serviceі mount pmxcfs; виправляйте corosync/мережевий порядок лише якщо логи це вказують.
2) «Dependency failed for ZFS Mount» або «Failed to import ZFS pools»
- Симптом: ZFS сервіси падають; mount-и відсутні; гості не стартують.
- Корінна причина: відсутній кеш-файл, перейменований пул, зміни шляхів пристроїв, відсутній ZFS-модуль в initramfs або реальні помилки диска.
- Виправлення: підтвердьте пули через
zpool import, імпортуйте вручну для діагностики, відновіть кеш, переконайтесь, що сервіс імпорту й initramfs коректні.
3) Завантаження зависає приблизно на 90 секунд у «A start job is running …»
- Симптом: довге затримання завантаження; інколи закінчується dependency failures.
- Корінна причина: wait-online сервіс чекає інтерфейс, або fstab mount чекає відсутній диск.
- Виправлення: визначте очікуваний юніт через
systemd-analyze critical-chain; вимкніть або налаштуйте wait-online; позначте неважливі mount-и якnofail.
4) Кластерні збої після перейменування NIC або заміни обладнання
- Симптом:
corosync.serviceпадає;pve-clusterне запускається; вузол не може приєднатись до кластеру. - Корінна причина: corosync налаштовано на інтерфейс, що більше не існує.
- Виправлення: виправте конфіг ring-інтерфейсу corosync і перезапустіть corosync/pve-cluster у правильному порядку; уникайте бинду на нестабільні імена інтерфейсів.
5) «Dependency failed for Local File Systems»
- Симптом: система опускається в emergency shell; багато сервісів скасовано.
- Корінна причина: обов’язковий fstab mount упав (неправильний UUID, помилки fs, відсутній пристрій).
- Виправлення: виправте fstab, додайте
nofailдля некритичних mount-ів, запустіть fsck де потрібно, або виправте апаратну проблему.
6) Після оновлення ядра імпорт сховища падає періодично
- Симптом: ZFS/LVM сервіси не працюють лише після певних оновлень; перезавантаження рулетка.
- Корінна причина: збірка DKMS модулів не вдалась або initramfs позбавлений модуля/прошивки.
- Виправлення: перевірте стан DKMS, перебудуйте initramfs, переконайтесь, що заголовки відповідають ядру, підтвердіть наявність модулів через
lsinitramfs.
Чеклісти / покроковий план (безпечно, нудно, ефективно)
Чекліст A: Знайти справжній юніт, що впав
- Запустіть
systemctl --failed. Запишіть список failed юнітів. - Запустіть
journalctl -b -0 -p err..alert. Знайдіть найраніший рядок «Failed to start …». - Перегляньте цей юніт:
systemctl status UNIT -l. - Якщо «failed unit» — листовий сервіс (UI, firewall), простежте залежності назад:
systemctl list-dependencies --reverse. - Використайте
systemd-analyze critical-chain multi-user.target, щоб підтвердити, що саме блокувало досягнення таргету.
Чекліст B: Якщо пахне сховищем
- Перевірте наявність пулів/VG:
zpool import,vgs,pvs(якщо застосовно). - Пошукайте невдачі mount-юнітів:
systemctl --failed | grep mount, потімsystemctl status *.mount. - Перевірте критичні для Proxmox mount-и:
findmnt /var/lib/vzі те, що тримає диски VM. - Проскануйте логи ядра на помилки транспорту:
dmesg --level=err,warn. - Тільки потім розгляньте ручний імпорт/активацію. Якщо ручний імпорт працює, виправляйте порядок/конфіг, не «ремонтуйте» здорові пули даремно.
Чекліст C: Якщо пахне network-online або кластером
- Перевірте затримки при завантаженні:
systemd-analyze blameіsystemd-analyze critical-chain. - Подивіться, хто підтягує network-online:
systemctl list-dependencies --reverse network-online.target. - Перегляньте override-и юнітів:
systemctl cat pve-cluster.service(і підозрілі юніти). - Підтвердіть стан corosync:
systemctl status corosyncі логи за потреби. - Приберіть непотрібні залежності «online». Віддавайте перевагу
network.target, якщо ви не можете письмово пояснити, чому потрібне «online».
Покроковий план виправлення: робіть без шкоди
Коли діагностика завершена, виправляйте обдумано:
- Змінюйте по одній речі. Якщо змінити три речі і завантаження вдалось, ви нічому не навчились.
- Віддавайте перевагу drop-in замість редагування vendor юнітів, але не зберігайте старі drop-in-и без причини.
- Після змін перезавантажте systemd і рестартуйте тільки релевантні юніти.
cr0x@server:~$ sudo systemctl daemon-reload
cr0x@server:~$ sudo systemctl restart zfs-import-cache.service zfs-mount.service
cr0x@server:~$ sudo systemctl restart pve-cluster.service pveproxy.service
Що означає вивід: якщо рестарт тепер працює, ваша проблема була в порядку запуску/конфігурації, а не в фундаментальній поломці.
Якщо рестарт все ще падає — читайте логи юніта знову: ваше виправлення не зачепило реальну причину.
Питання та відповіді
1) Чому systemd показує «Dependency failed» не для того об’єкта?
Бо воно виводить те, що скасовано. Корінна причина зазвичай — перший юніт, що впав раніше в ланцюгу. Знайдіть той юніт у журналі.
2) Який найшвидший спосіб знайти перший юніт, що впав?
journalctl -b -0 -p err..alert і шукайте найраніший запис «Failed to start …». Потім перегляньте логи цього юніта через journalctl -u.
3) Може я просто перезапустю всі сервіси Proxmox?
Ні. Перезапуск стека може приховати проблеми порядку і зробити наступне перезавантаження знову неуспішним. Виправляйте залежність (сховище/mount/мережа) першою.
4) Чи добре використовувати After=network-online.target для Proxmox?
Зазвичай ні. Це додає режими відмов і затримки. Використовуйте його тільки якщо сервіс справді вимагає маршрутизованої мережі під час старту і ви правильно налаштували wait-online.
5) Як відрізнити проблему сховища від проблеми порядку systemd?
Якщо ручний імпорт/активація працює (zpool імпортується, VG активується) і немає I/O помилок у kernel logs, то ймовірно це порядок/конфіг.
Якщо пристрої відсутні або dmesg показує помилки — це апаратне/сховище.
6) Що робити, якщо відсутній резервний диск у fstab ламає завантаження?
Зробіть його опціональним: додайте nofail і короткий x-systemd.device-timeout=. Або монтуйте за потреби. Не дозволяйте опціональному сховищу стати воротами завантаження.
7) Чому systemd-analyze blame іноді вказує на неправильне вузьке місце?
Тому що він вимірює час, витрачений у юнітах, включно з часом очікування. Використовуйте systemd-analyze critical-chain, щоб побачити справжній шлях залежностей.
8) Якщо /etc/pve не змонтовано, чи можу я відновити вузол?
Так, але потрібно привести в робочий стан pve-cluster/pmxcfs. Почніть з виправлення corosync (якщо є кластер) і забезпечення необхідних сховищ/mount-ів. Потім перезапустіть pve-cluster.
9) Чи може «Dependency failed» бути спричинено циклічною залежністю?
Так. Особливо з кастомними override-ами, які примушують network-online або mount-и в неправильному напрямку. Шукайте цикли в логах і використовуйте systemctl cat, щоб знайти override, що його створив.
10) Який найбезпечніший спосіб змінювати systemd-залежності?
Використовуйте drop-in під /etc/systemd/system/UNIT.d/override.conf, документуйте причину і тестуйте перезавантаження. Якщо не можете це обґрунтувати — не впроваджуйте.
Висновок: наступні кроки, які можна зробити сьогодні
Лікування «Dependency failed» — це не містика. Це трасування графа.
Знайдіть перший юніт, що впав у журналі, підтвердіть ланцюг залежностей і виправте upstream-блокер — зазвичай імпорт/mount сховища, pmxcfs або network-online.
Практичні наступні кроки:
- На робочому вузлі зробіть baseline:
systemctl --failed(має бути порожнім),systemd-analyze critical-chain, і збережіть увімкнені override-и (systemctl catдля ключових Proxmox-юнітів). - Аудитуйте
/etc/fstabна предмет некритичних mount-ів і позначте їх опціональними або монтуйте за потреби. - Пошукайте й видаліть «таємничі» drop-in-и, що примушують
network-online.targetбез вагомої причини. - Після оновлень ядра перевіряйте присутність модулів сховища в initramfs перед плануванням перезавантажень.