Ви не помічаєте, що віддалена файлова система крихка, поки вона не стає вашою повною інцидентною точкою. Завдання збірки зупиняється на «copying artifacts…», shell перестає реагувати при cd, а ваш графік моніторингу виглядає нормально, бо моніторинг ніколи не намагався торкнутися монту.
Debian 13 робить простим змонтувати майже що завгодно. Він не робить простим змонтувати щось правильно. Якщо вам потрібно, щоб «не зависало випадково» було безумовною властивістю, потрібно свідомо обрати правильний протокол і налаштувати семантику відмов.
Рішення: що не буде випадково зависати?
Якщо ваша вимога — «монтувати так, щоб у продакшені не зависало випадково», чесна відповідь така:
- Обирайте NFSv4.1+ для продакшен-шерів (сервіси, артефакти CI, домашні директорії, об’єми контейнерів там, де доречно), та налаштуйте таймаути/retrans/семантику automount так, щоб відмови були обмежені.
- Використовуйте SSHFS для інструментів: швидкий доступ ad-hoc, одноразові міграції, дебаг, «мені зараз потрібна та директорія» або обмежені робочі процеси розробників — але розглядайте його як зручність, а не платформу зберігання.
Чому? Бо «випадкові зависання» зазвичай не випадкові. Це семантика блокування, що зустрічається з нестабільною мережею, мертвим сервером або невідповідністю станів. У NFS є десятки років операційних налаштувань, щоб визначити, що означає «вниз» і як клієнти мають поводитись. SSHFS — це FUSE-файлова система, яка базується на інтерактивному протоколі (SFTP), не призначеному для суворих POSIX-семантик з низькою затримкою під відмовами.
Тим не менше: NFS теж може зависати ваші процеси. Просто з NFS ви можете обрати, як воно відмовлятиме, і зробити це помітним. З SSHFS ви витрачаєте більше часу на реверс-інжиніринг, чому FUSE-запит застряг за завислим SSH-каналом.
Правило великого пальця: якщо вас буде дратувати завислий ls о 3:00 ранку, не будуйте систему навколо SSHFS. Якщо вас буде дратувати завислий ls о 3:00 ранку, також не розгортайте NFS без явних опцій монтування. Ласкаво просимо у світ зберігання.
Цитата, щоб не забувати реальність: Hope is not a strategy
— Rick Page.
Жарт #1: SSHFS — як кишеньковий ніж. Чудовий, поки ви не почнете з ним реконструювати будинок.
Факти та історія, які можна використовувати в аргументах
Короткі, конкретні пункти контексту, що пояснюють, чому ці інструменти поводяться так, як вони поводяться:
- NFS існує з 1984 року (Sun Microsystems). Він створювався для спільних Unix-файлових систем на LAN, має довгу історію операційного тонінгу та очікувань підприємств.
- NFSv4 перейшов від «RPC-супу» до більш інтегрованого протоколу, зменшивши залежність від окремих демонів/портів порівняно з NFSv3 і додавши станофі функції, як-от делегації та кращу блокування.
- Семантика «hard mount» у NFS навмисно вперта: клієнт буде повторювати I/O, бо провал запису може пошкодити припущення на рівні застосунку. Це «зависання» — функція, поки воно не стає проблемою.
- SSHFS — це FUSE-файлова система. Це означає, що кожна операція файлової системи переходить у простір користувача, і продуктивність/затримка сильно залежать від демона FUSE і обробки запитів.
- SSHFS використовує SFTP, який не є «рідним» для файлової системи. Це протокол передачі файлів, адаптований під вигляд файлової системи, що створює невідповідності навколо операцій метаданих і блокувань.
- FUSE може створювати процеси, що виглядають не вбиваними, коли ядро чекає відповіді від користувацького простору. Ви можете виконати
kill -9процес; ядро все одно чекатиме, якщо запит заблоковано. - У NFS відомий сценарій «stale file handle», коли експортовані директорії змінюються під клієнтом (наприклад, серверна fs замінена, некоректне failover). Це класика, а не новинка.
- Systemd automount змінив правила гри для мережевих монтувань: можна уникнути зависань при завантаженні й обмежити наслідки відмов, монтувавши при доступі, а не при старті системи.
Що насправді означає «зависання» в Linux
Коли люди кажуть «монтування зависло», Linux зазвичай має на увазі одне з такого:
1) Ваш процес у нескінченному сні (стан D)
Класика для NFS hard-mounts, а також можлива для FUSE, коли ядро чекає відповіді від демона FUSE. Якщо процес справді у D-state, його не померти, поки базовий I/O не вирішиться або ядро не відмовиться (часто: не відмовляється).
2) Ваш shell в порядку, але будь-який шлях під монтом блокує
Це найпотаємніший режим відмови. Моніторинг дивиться на завантаження хоста і місце на диску і не реагує. Тим часом будь-що, що торкається /mnt/share, — повна зупинка.
3) «Зависання» насправді DNS або автентифікація
Хелпери монтування можуть блокуватися на зворотних DNS-запитах, отриманні Kerberos-токена або зв’язку з rpcbind/mountd (NFSv3). Це виглядає як проблема зі зберіганням. Часто це — резолюція імен.
4) «Зависання» — мережевий шлях, а не протокол
Несумісність MTU, асиметрична маршрутизація, вичерпання conntrack, фаєрвол, що відкидає фрагменти, ненадійний ToR або VPN з агресивними таймаутами іділ. SSH витримує деякі з цих проблем краще, бо їде в одному TCP-потоці. Або ще гірше: витримує, зависнувши назавжди.
Операційно вам потрібно дві речі:
- Обмежена відмова: запити мають таймаути й клієнти отримують помилки замість нескінченних блокувань.
- Гарна спостережуваність: коли щось відмовляє, ви бачите причину в логах/метриках і відтворюєте простими інструментами.
SSHFS на Debian 13: де він відмінно працює, а де підводить
SSHFS привабливо простий. У вас вже є SSH. Виконав команду — отримав монтування. Немає демона сервера для тонінгу (окрім sshd), немає exports, немає idmap, немає засідань фаєрвол-комітету.
А потім воно починає «випадково зависати». Ось чому так відбувається і що з цим робити.
Модель надійності SSHFS (що ви фактично купуєте)
- Один зашифрований TCP-сеанс (SSH), що несе SFTP-запити.
- Файлова система в прострі користувача (FUSE), що транслює POSIX-подібні операції в SFTP-дії.
- Відмова часто проявляється як «блокований syscall», бо ядро чекає на FUSE, FUSE чекає на SSH, а SSH чекає на мережу.
SSHFS чудовий, коли робочий процес толерує випадкові затримки, або коли «воно впало» означає «я спробую ще раз» і нічого не обслуговує користувацький трафік.
Типові тригери зависань SSHFS
- TCP-сеанси, що вмирають через NAT/VPN при просте: SSH-канал з клієнтської перспективи все ще «up», але шлях чорнийхолдиться.
- Перевантаження на сервері: sshd і підсистема SFTP завантажені по CPU (шифрування, компресія або забагато сеансів).
- Навантаження, що інтенсивно працює з метаданими:
git status, рекурсивні пошуки, інсталяції залежностей. SSHFS посилює затримку і чутливість до RTT. - Накопичення запитів FUSE: демон у прострі користувача застряг; ядро чекає; процеси скупчуються.
Як запускати SSHFS без саботажу
На Debian 13 припускаємо, що ви використовуєте sshfs з FUSE3. Тактика:
- Використовуйте SSH keepalives, щоб виявляти мертві шляхи.
- Використовуйте automount, щоб мертвий сервер не блокував завантаження або сервіси, яким це не потрібно.
- Прийміть, що кешування складне. Надмірне кешування покращує швидкість і підвищує ризик «застарілого вигляду»; недостатнє кешування перетворює репозиторій у бенчмарк затримок.
- Не ілюструйте, що блокування ідеальні. Якщо вам потрібна коректна багатоклієнтська POSIX-поведінка, SSHFS — не той інструмент.
Жарт #2: Найшвидший спосіб знайти проблему SSHFS — сказати, що «я просто використаю його у продакшені — тимчасово».
NFS на Debian 13: продакшен-рівень, якщо його поважати
NFS має погану репутацію через дві причини: люди, які використовували NFSv3 по ненадійних мережах, і люди, які залишали дефолти недоторканими, а потім дивувалися, що відбулася саме така поведінка.
Модель надійності NFS
Клієнти NFS роблять віддалений I/O схожим на локальний. Коли сервер або шлях відмовляє, клієнт вирішує, що робити, базуючись на опціях монтування:
- Hard mounts: продовжують повторювати. Чудово для цілісності даних, небезпечно для доступності, якщо ви не ізолювали радіус ураження.
- Soft mounts: відмовляються і повертають помилку. Краще для інтерактивних інструментів і «best effort» читань; ризиковано для записів.
- Таймаути і retrans: визначають, скільки чекати і як агресивно повторювати.
- Systemd automount: монтує лише при доступі і уникає дедлоків під час завантаження.
Як виглядає «випадкове зависання» в світі NFS
Зазвичай це одне з наступного:
- Hard mount + сервер недоступний ⇒ задачі в стані D, які можуть накопичуватись.
- Проблеми з блокуванням / відновленням стану після перезавантаження сервера ⇒ зависання або помилки I/O залежно від версії та навантаження.
- Невідповідність DNS/idmap ⇒ дивна поведінка дозволів, що виглядає як баг застосунку.
- Фаєрвол/NAT ⇒ періодичні затримки під навантаженням (особливо з додатковими сервісами NFSv3).
Що розгорнути за замовчуванням
Якщо хочете розумну базову конфігурацію для клієнтів Debian 13:
- NFSv4.1 або новіше (4.2, якщо сервер підтримує), TCP.
- Systemd automount для всього, що не критично при завантаженні; для критичних монтувань явно вкажіть залежності і таймаути.
- Hard mounts для write-heavy критичних даних, але ізолюйте їх (окремий сервіс, окрема mount namespace за потреби) і моніторте застрягання I/O.
- Soft mounts тільки для read-mostly, некритичного доступу, і лише якщо ваш застосунок може пережити помилки I/O.
Обмежена відмова з NFS не означає «ніколи hard». Це означає: hard там, де важлива коректність, і з оточенням запобіжників, щоб воно не заморозило весь хост.
Практичні завдання: команди, результати, рішення (12+)
Це перевірки, які я справді виконую, коли приходить повідомлення про «випадкове зависання». Кожне завдання включає те, що вивід означає, і яке рішення робити далі.
Завдання 1 — Ідентифікуйте, що змонтовано і як
cr0x@server:~$ findmnt -t nfs,nfs4,fuse.sshfs
TARGET SOURCE FSTYPE OPTIONS
/mnt/build nfs01:/exports/build nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,proto=tcp,sec=sys,clientaddr=10.0.2.10
/mnt/tools dev@jump:/srv/tools fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000
Значення: ви бачите протокол, версію і чи NFS — hard/soft. SSHFS показується як fuse.sshfs.
Рішення: якщо NFS hard і монтування на шляху, що використовують критичні системні сервіси (наприклад підшляхи /var), пріоритезуйте зменшення радіусу ураження (automount або ізоляція сервісу).
Завдання 2 — Підтвердіть узгодження версії NFS з клієнта
cr0x@server:~$ nfsstat -m
/mnt/build from nfs01:/exports/build
Flags: rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.2.10
Значення: це підтверджує, що ядро фактично використовує, а не те, що ви думаєте, що налаштували.
Рішення: якщо воно каже vers=3, а ви чекали v4, перевіряйте підтримку сервера, опції монтування і фаєрвол (v3 більш крихкий через мережі).
Завдання 3 — Виявіть «застряглі» процеси і чи це D-state
cr0x@server:~$ ps -eo pid,state,comm,wchan:32,args | awk '$2 ~ /D/ {print}'
23144 D rsync nfs_wait_on_request rsync -a /mnt/build/ /var/cache/build/
Значення: D-state з каналом очікування nfs_* кричить «заблоковано на NFS I/O». Якщо це fuse_wait, думайте про SSHFS/FUSE.
Рішення: не перезапускайте застосунки наосліп. Тепер ви знаєте, що це очікування ядра I/O; зосередьтеся на мережі/сервері, а не на застосунку.
Завдання 4 — Перевірте журнали ядра на помилки клієнта NFS
cr0x@server:~$ journalctl -k -n 50 --no-pager
Dec 30 10:12:03 server kernel: NFS: server nfs01 not responding, still trying
Dec 30 10:12:33 server kernel: NFS: server nfs01 not responding, still trying
Dec 30 10:13:04 server kernel: NFS: server nfs01 OK
Значення: транзитні проблеми з сервером/шляхом. Якщо ви бачите «still trying» постійно, клієнт застряг у циклі повторів (поведінка hard mount).
Рішення: якщо це трапляється часто, налаштуйте таймаути і дослідіть падіння мережі; не «виправляйте» додатковими перезапусками застосунків.
Завдання 5 — Підтвердьте експорт сервера з боку клієнта
cr0x@server:~$ showmount -e nfs01
Export list for nfs01:
/exports/build 10.0.2.0/24
Значення: валідовує, що сервер експортує і ваша мережа дозволяє. (Переважно для NFSv3; все ще корисно для простих перевірок.)
Рішення: якщо це не вдається або зависає, підозрюйте фаєрвол/rpc-сервіси або неправильний DNS.
Завдання 6 — Перевірте резолюцію і зворотний DNS (так, це важливо)
cr0x@server:~$ getent hosts nfs01
10.0.2.20 nfs01
cr0x@server:~$ getent hosts 10.0.2.20
10.0.2.20 nfs01
Значення: пряма і зворотна резолюція послідовні. Непослідовність викликає дивні проблеми з автентифікацією, затримки і «висить лише інколи».
Рішення: якщо зворотний lookup повільний або неправильний, виправте DNS або додайте адекватні записи у відповідний стек резольвера. Не погоджуйтесь на 5-секундні затримки DNS для кожного шляху монтування.
Завдання 7 — Виміряйте базовий RTT і втрати пакетів до сервера
cr0x@server:~$ ping -c 5 nfs01
PING nfs01 (10.0.2.20) 56(84) bytes of data.
64 bytes from 10.0.2.20: icmp_seq=1 ttl=64 time=0.41 ms
64 bytes from 10.0.2.20: icmp_seq=2 ttl=64 time=0.38 ms
64 bytes from 10.0.2.20: icmp_seq=3 ttl=64 time=0.43 ms
64 bytes from 10.0.2.20: icmp_seq=4 ttl=64 time=0.40 ms
64 bytes from 10.0.2.20: icmp_seq=5 ttl=64 time=0.39 ms
--- nfs01 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4090ms
rtt min/avg/max/mdev = 0.38/0.40/0.43/0.02 ms
Значення: базова доступність виглядає нормально, але ping не гарантує, що NFS/SSH не встануть. Проте втрати тут — червоний прапор.
Рішення: якщо є втрата пакетів — виправляйте мережу спочатку. Тюнінг зберігання марний на шляхах з втратою.
Завдання 8 — Перевірте MTU або дивні шляхи з tracepath
cr0x@server:~$ tracepath nfs01
1?: [LOCALHOST] pmtu 1500
1: nfs01 0.439ms reached
Resume: pmtu 1500 hops 1 back 1
Значення: PMTU адекватний і шлях простий. Якщо PMTU несподівано падає, видно ризик фрагментації.
Рішення: якщо PMTU нижчий, ніж очікується (наприклад 1400 у LAN), перевірте overlay/VPN і узгодьте MTU, щоб уникнути періодичних затримок.
Завдання 9 — Перевірте налаштування SSH keepalive для сценаріїв SSHFS
cr0x@server:~$ ssh -G jump | egrep 'serveraliveinterval|serveralivecountmax|tcpkeepalive'
tcpkeepalive yes
serveraliveinterval 15
serveralivecountmax 3
Значення: SSH виявить мертві шляхи приблизно за ~45 секунд. Без цього SSH може сидіти на мертвому TCP-сеансі довго, залежно від мережі.
Рішення: якщо ці параметри відсутні або великі, додайте їх до виклику SSHFS або конфігурації SSH, щоб відмови ставали помітними.
Завдання 10 — Відтворіть «зависання» одним syscall і обгорткою з таймаутом
cr0x@server:~$ timeout 5s stat /mnt/build/. || echo "stat timed out"
stat timed out
Значення: це доводить, що зависання в файловому доступі, а не в викликаючій програмі. Використання timeout робить це помітним і скриптуємим.
Рішення: якщо stat зависає, а ping в нормі — підозрюйте серверну NFS thread starvation, проблеми зі станом фаєрволу або застряглі RPC на клієнті.
Завдання 11 — Інспектуйте живу RPC-активність NFS (зі сторони клієнта)
cr0x@server:~$ nfsstat -rc
Client rpc stats:
calls retrans authrefrsh
124981 317 0
Client nfs v4:
null read write commit open open_conf
3 20811 14402 0 9812 14
Значення: швидке зростання retrans вказує на втрати пакетів або повільність сервера. Невеликий стабільний retrans під час нормальної роботи — нормально; сплески — ні.
Рішення: якщо retrans зростає під час інцидентів, розглядайте це як проблему мережі/ємності сервера, а не «NFS поганий».
Завдання 12 — Підтвердьте порядок systemd і ризик завантаження
cr0x@server:~$ systemctl show -p After -p Wants remote-fs.target
After=network-online.target
Wants=network-online.target
Значення: ваші віддалені монтування прив’язані до network-online.target. Якщо network-online нестабільний, завантаження може бути повільним або зависнути.
Рішення: для некритичних монтувань переключіться на systemd automount, так система завантажиться навіть якщо зберігання недоступне.
Завдання 13 — Помітте зворотний тиск SSHFS/FUSE і заблоковані запити
cr0x@server:~$ ps -eo pid,state,comm,wchan:32,args | egrep 'sshfs|fuse' | head
18211 S sshfs wait_woken sshfs dev@jump:/srv/tools /mnt/tools -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3
Значення: ще не D-state, але ви можете корелювати час з повідомленням про зависання. Якщо бачите багато процесів, застряглих у fuse_wait або подібному, SSHFS заклинено.
Рішення: якщо це регулярно зависає під навантаженням — перестаньте використовувати SSHFS для цього навантаження. Це невідповідність дизайну, а не питання налаштування.
Завдання 14 — Переконайтесь, що NFS сервер доступний на потрібному порті (v4)
cr0x@server:~$ nc -vz nfs01 2049
Connection to nfs01 (10.0.2.20) 2049 port [tcp/nfs] succeeded!
Значення: TCP/2049 відкрито. NFSv4 переважно потребує цього. Якщо це періодично не вдається, підозрюйте фаєрвол або load balancer, що «допомагають».
Рішення: якщо 2049 закрито — припиніть. Жодна опція монтування не обійде «порт закритий». Виправляйте політику мережі.
Завдання 15 — Перевірте реальні опції монтування у /proc (джерело правди)
cr0x@server:~$ grep -E ' /mnt/build | /mnt/tools ' /proc/mounts
nfs01:/exports/build /mnt/build nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.2.10 0 0
dev@jump:/srv/tools /mnt/tools fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
Значення: це те, чого використовує ядро. Якщо ви думаєте, що встановили опцію, а її тут немає — вона не застосована.
Рішення: виправте mount unit/fstab/команду і перемонтуйте.
Швидкий план діагностики
Коли хтось каже «віддалений монтування завис», ви можете витратити годину на здогадки. Або виконати це за п’ять хвилин і виглядати так, ніби все було заплановано.
Перше: визначте, NFS це чи SSHFS, і чи щось у D-state
- Запустіть:
findmnt -t nfs,nfs4,fuse.sshfsіps ... | awk '$2 ~ /D/' - Якщо є D-state: це очікування ядра I/O. Перезапуск застосунків не допоможе. Перейдіть до перевірок мережі/сервера.
- Якщо D-state немає: все ще може бути повільно/застрягло в прострі користувача (SSHFS) або проблеми з резолюцією/автентифікацією.
Друге: перевірте просту перевірку життя для точного шляху монтування
- Запустіть:
timeout 5s stat /mnt/whatever - Якщо stat зависає: ви відтворили проблему одним syscall. Тепер корелюйте з логами, RPC-статистикою і мережею.
- Якщо stat працює: ваше «зависання» ймовірно на вищих шарах (блокування застосунку, велика операція по директоріях, повільні метадані).
Третє: ізолюйте домен — мережа, сервер, клієнт або семантика
- Мережа:
ping,tracepath, перевірка retrans вnfsstat -rc, перевірка порту 2049 зnc. - Сервер: шукайте «server not responding» у логах ядра; якщо маєте доступ, перевірте насичення ниток NFS сервера і затримку дисків (поза цією статтею, але ви у курсі).
- Конфігурація клієнта: підтвердіть опції монтування в
/proc/mountsі що systemd робить під час завантаження. - Невідповідність семантики: якщо навантаження метадані-важке і ви на SSHFS — припиніть. Якщо вам потрібні суворі семантики відмов, але NFS змонтований як hard на критичному шляху — переробіть.
Типові помилки (симптом → корінь → виправлення)
1) Симптом: «Весь хост заморожено», але тільки деякі команди зависають
Корінь: shell або системний сервіс торкнувся шляху з hard-mounted NFS; процеси застрягли в D-state, чекаючи I/O.
Виправлення: використовуйте x-systemd.automount для некритичних монтувань і уникайте розміщення NFS під шляхами, що використовуються основними сервісами. Для критичних монтувань ізолюйте сервіси і моніторьте NFS.
2) Симптом: SSHFS монтування працює, потім «випадково» заморожується після просте
Корінь: NAT/VPN idle timeout чорнихолить TCP-сеанс; SSH не виявляє цього швидко без keepalives.
Виправлення: встановіть ServerAliveInterval і ServerAliveCountMax (на боці клієнта), і розгляньте TCP keepalive. Віддавайте перевагу automount, щоб монтування відновлювалось при доступі.
3) Симптом: NFS монтування інколи займає 30–90 секунд, інколи миттєво
Корінь: затримки зворотного DNS або непостійні резольвери; або спроба різних версій/портів з таймаутом перед відкатом.
Виправлення: виправте консистентність DNS; явно вкажіть vers=4.2; переконайтесь, що TCP/2049 дозволено наскрізь.
4) Симптом: «Permission denied» на NFSv4, незважаючи на відповідність UID/GID
Корінь: невідповідність idmapping/domain або export з root_squash, що не відповідає моделі ідентичності клієнта.
Виправлення: узгодьте налаштування idmap domain, якщо ви покладаєтесь на картування по іменах, або використовуйте послідовні числові ID між системами. Перевірте опції експорту на сервері.
5) Симптом: «Stale file handle» після технічних робіт/failover
Корінь: серверна файловa система замінена/переміщена; клієнти тримають посилання на старі filehandles.
Виправлення: перемонтуйте файлову систему; уникайте заміни експортованих дерев без координованого remount клієнтів або правильних HA-семантик.
6) Симптом: CI задачі повільно працюють на SSHFS; CPU стрибає на обох кінцях
Корінь: операції з метаданими над зашифрованим SFTP + контекстні переключення FUSE; опційна компресія погіршує ситуацію.
Виправлення: використовуйте NFS для артефактів збірки; якщо мусите використовувати SSHFS — вимкніть компресію для LAN і уникайте використання його для «гарячих» шляхів.
7) Симптом: Завантаження висить, чекаючи віддалених монтувань
Корінь: монтування в /etc/fstab без automount; network-online target фактично не онлайн; hard mount чекає.
Виправлення: використовуйте nofail, x-systemd.automount і x-systemd.mount-timeout=; забезпечте, щоб network-online service коректно працював для вашого стеку мережі.
8) Симптом: NFS працює, але деякі застосунки поводяться дивно (блокування, часткові записи, помилки)
Корінь: використання soft для навантажень, що припускають, що записи ніколи не відмовляють посередині; або змішування старих версій NFS з очікуваннями блокування.
Виправлення: використовуйте hard для write-critical навантажень; забезпечте NFSv4 і коректне оброблення lock/state; переробіть застосунки для обробки помилок I/O, якщо ви наполягаєте на soft.
Контрольні списки / покроковий план
План A: Потрібна надійна спільна файлова система (більшість продакшен-випадків)
- Обирайте NFSv4.2 через TCP, якщо немає вагомої причини інакше.
- Визначте семантику відмов для кожного монтування:
- Критичні для запису: hard, але ізолюйте.
- Переважно для читання і некритичні: розгляньте soft з короткими таймаутами.
- Використовуйте systemd automount для всього, що не потрібно при завантаженні.
- Встановіть явні таймаути і retrans, замість довіри дефолтам, які ви не тестували.
- Моніторьте появу повідомлень «server not responding» і сплесків retrans.
- Документуйте радіус ураження: які сервіси торкаються монтування? які вузли? що відбувається, якщо воно зависне?
План B: Потрібен лише безпечний ad-hoc доступ (інструменти розробника, міграції)
- Використовуйте SSHFS з keepalives і поведінкою reconnect.
- Уникайте навантажень, що інтенсивно працюють з метаданими (великі репозиторії, package managers), коли вам важлива швидкість або стабільність.
- Монтуйте на вимогу за допомогою systemd або вручну, а не як критичну залежність при завантаженні.
- Віддавайте перевагу rsync/scp для масових передач, коли вам не потрібен монтуваний вигляд.
Фрагменти конфігурації Debian 13, які ви реально можете розгорнути
Пакети клієнта NFS і адекватний запис у fstab (з automount)
cr0x@server:~$ sudo apt-get update
...output...
cr0x@server:~$ sudo apt-get install -y nfs-common
...output...
cr0x@server:~$ sudo mkdir -p /mnt/build
cr0x@server:~$ sudo sh -c 'printf "%s\n" "nfs01:/exports/build /mnt/build nfs4 rw,vers=4.2,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,x-systemd.automount,x-systemd.idle-timeout=300,noatime,nofail,x-systemd.mount-timeout=30s 0 0" >> /etc/fstab'
Що це дає: хост завантажується навіть якщо NFS недоступний (nofail), монтування відбувається при доступі (automount), і якщо швидко змонтувати не вдається — воно швидко провалюється замість блокування на завантаженні.
SSHFS з keepalives і reconnect (ручне монтування)
cr0x@server:~$ sudo apt-get install -y sshfs
...output...
cr0x@server:~$ sudo mkdir -p /mnt/tools
cr0x@server:~$ sshfs dev@jump:/srv/tools /mnt/tools -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,IdentityFile=/home/dev/.ssh/id_ed25519,allow_other
Операційна нотатка: allow_other вимагає user_allow_other в /etc/fuse.conf. Використовуйте його тільки якщо маєте на увазі; інакше тримайте монтування приватним для користувача.
Systemd automount для SSHFS (щоб не клинило завантаження)
Коли SSHFS використовується сервісом, я віддаю перевагу unit-ам systemd, щоб можна було встановити таймаути і поведінку перезапуску.
cr0x@server:~$ sudo tee /etc/systemd/system/mnt-tools.mount &>/dev/null <<'EOF'
[Unit]
Description=SSHFS tools mount
After=network-online.target
Wants=network-online.target
[Mount]
What=dev@jump:/srv/tools
Where=/mnt/tools
Type=fuse.sshfs
Options=_netdev,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,IdentityFile=/home/dev/.ssh/id_ed25519,allow_other
[Install]
WantedBy=multi-user.target
EOF
...output...
cr0x@server:~$ sudo tee /etc/systemd/system/mnt-tools.automount &>/dev/null <<'EOF'
[Unit]
Description=Automount SSHFS tools
[Automount]
Where=/mnt/tools
TimeoutIdleSec=300
[Install]
WantedBy=multi-user.target
EOF
...output...
cr0x@server:~$ sudo systemctl daemon-reload
cr0x@server:~$ sudo systemctl enable --now mnt-tools.automount
Created symlink /etc/systemd/system/multi-user.target.wants/mnt-tools.automount → /etc/systemd/system/mnt-tools.automount.
Рішення: якщо SSHFS-сервер недоступний, доступи до /mnt/tools спробують змонтувати і проваляться в межах таймаутів systemd, замість клинити завантаження.
Три корпоративні історії з практики
Історія 1: Інцидент через неправильне припущення («це просто монтування»)
Середня компанія запускала Debian на build-runner’ах. Комусь потрібен був швидкий доступ до легасі-артфакт-стору, у якого був відкритий лише SSH через хардений джамп-хост. SSHFS був очевидним обходом: жодного запиту у фаєрвол, жодних змін на сервері, і воно працювало перші п’ять хвилин.
Вони вписали SSHFS у /etc/fstab на раннерах, бо CI job очікував існування /mnt/artifacts. Це було «тимчасово», що в корпоративних масштабах означає «доки наступного реорганізації». Тижнями здавалося, що все нормально, бо мережевий шлях був стабільний і джамп-хост був недовантажений.
Потім змінили VPN і додали idle timeout. SSH-сеанси, що сиділи тихо, не коректно закривались; вони просто чорнихолилися. Виклики SSHFS почали блокуватися. CI воркери не були просто «вниз»; вони були ще гірше — працювали, спалюючи слоти виконавців на задачах, що зависали під час tar розпакування.
Неправильне припущення було в тому, що монтування — як локальна директорія з іншим профілем затримки. Це не так. Це залежність з режимами відмов. Коли вона відмовляє, зазвичай це відбувається всередині syscall’ів, де ваш застосунок не може «поймати» це.
Виправлення було не героїчне: прибрали SSHFS з fstab, додали systemd automount з keepalives, і перемістили сховище артефактів за фаєрвол на NFS. Більш важлива зміна була культурною: віддалі монтування почали трактувати як бази даних — з власниками, моніторингом і рев’ю.
Історія 2: Оптимізація, що відбилася боком (більше не завжди краще)
Ще одна команда мала NFS-share для аналітичних задач. Вони побачили проблеми з пропускною здатністю і зробили те, що робить кожен: збільшили rsize і wsize, ввімкнули агресивне кешування на боці клієнта і відзначили перемогу, коли один бенчмарк показав краще число.
Це було не зі злим умислом. Це нормально. Хтось запустив послідовний тест читання і отримав гарний показник. Потім робоче навантаження змінилося: тисячі дрібних файлів, багато операцій з метаданими та кілька клієнтів. Раптом «швидка» конфігурація дала довгі зависання під час піку.
Зворотній ефект прийшов з двох боків. По-перше, більші I/O розміри не допомагають для навантажень, що інтенсивно працюють з метаданими, і іноді уповільнюють відновлення при втратах пакетів (більше даних для повторної передачі). По-друге, semantics automount/timeout команди ще були майже дефолтними, тож коли сервер завантажився, клієнти накопичували повтори і все виглядало замороженим.
Вони виправили це, розділивши тюнінг по класах навантажень. Залишили великі I/O розміри для послідовного шляху даних, але винесли метадані-важкі дерева в окремі експорти і ввели адекватні таймаути на клієнті. Найбільше покращення дало зробити відмови видимими і обмеженими, а не вичавлювати ще 5% продуктивності.
Історія 3: Нудна правильна практика, що врятувала день (і ніхто не отримав трофея)
В одному регульованому середовищі домашні директорії були на NFS. Усі боялися «NFS hangs», тож спокуса була зробити soft mounts повсюди. Але ops-команда зробила одне агресивно нудне: класифікувала монтування за вимогами коректності і встановила політики відповідно.
Домашні директорії монтували як hard, бо втрата записів неприпустима. Але їх також монтували з systemd automount і тримали подалі від шляхів, критичних для завантаження. Сесії користувачів блокувалися, якщо філер помер, але хост лишався керованим. Ця різниця важлива, коли ви намагаєтесь виправити проблему.
Вони також мали рутину щотижневої перевірки: вибіркова латентність stat, моніторинг частоти повідомлень ядра «not responding» і алерт на сплески retrans NFS. Нічого фантастичного. Просто маленькі перевірки, що виявляли «це починає бути дивно» ще до того, як сталося пекло.
Коли мережева технічна робота спричинила коротку втрату пакетів, вони бачили підйом retrans і повідомлення «server not responding». Оскільки у них були базові показники, вони швидко сказали: «Це ненормально і корелює з вікном змін». Виправлення пройшло швидко, а вплив на користувачів залишився обмеженим.
Найкраще: runbook спрацював навіть для нових on-call інженерів. Система не залежала від одного чаклуна, що пам’ятає інцидент 2019 року.
FAQ
1) Що швидше на Debian 13: SSHFS чи NFS?
Для більшості реальних навантажень NFS швидший і передбачуваніший, особливо при конкуренції і доступі, що інтенсивно працює з метаданими. SSHFS додає накладні витрати шифрування, переходи в простір користувача і витрати на трансляцію SFTP.
2) Що безпечніше за замовчуванням?
SSHFS успадковує шифрування і автентифікацію SSH, тому його часто простіше розгорнути безпечно через недовірені мережі. NFS може бути безпечним, але його потрібно проєктувати: ізоляція мережі, фаєрволи і (за потреби) Kerberos.
3) Що насправді викликає «випадкові зависання» на NFS?
Найчастіше: hard mounts, що повторюють запити під час проблем з сервером/шляхом, втрата пакетів, що викликає бурю retrans, або проблеми з відновленням стану/блокуваннями під час перезавантажень сервера. Виправлення зазвичай — краща семантика відмов плюс усунення мережевих/серверних проблем.
4) Чи можна зробити SSHFS «не-зависаючим»?
Ви можете зменшити ймовірність, використовуючи keepalives і automount, але не зміните факт, що FUSE + SFTP можуть блокувати syscalls, коли канал стоїть. Якщо «ніколи не зависати» — ваш критерій, не ставте SSHFS на критичні шляхи.
5) Чи варто використовувати soft mounts NFS, щоб запобігти зависанням?
Лише для read-mostly, некритичних навантажень, де застосунок може пережити помилки I/O. Soft mounts міняють «висить вічно» на «інколи провалюється», і провал запису посередині може призвести до тонких корупцій на рівні застосунку.
6) Чи systemd automount кращий за autofs?
Для багатьох налаштувань Debian 13 systemd automount простіший і добре інтегрується з порядком завантаження і таймаутами. Autofs залишається корисним, коли потрібна розширена логіка map або спадкова поведінка.
7) Які опції монтування найважливіші для запобігання болю всього хоста?
x-systemd.automount (уникнути залежності при завантаженні і обмежити доступ), nofail, і явні timeo/retrans, щоб ви знали, що означає «вниз». Також: не монтуйте віддалені файлові системи під шляхами, від яких залежать основні сервіси, якщо ви цього не маєте на увазі.
8) Чому df зависає, коли монтування поламано?
df опитує статистику файлових систем для всіх монтувань. Якщо один віддалений монтування блокує, df блокує. Використовуйте df -l для локальних тільки, або таргетуйте конкретні файлові системи акуратно.
9) Чи підходить NFS по Wi‑Fi або по публічному інтернету?
По Wi‑Fi: може працювати, але очікуйте варіабельність і retrans. По публічному інтернету: не радив би, якщо ви точно не знаєте, що робите з безпечним транспортом, очікуваннями затримки і семантикою відмов. SSH-інструменти зазвичай краще підходять для таких середовищ.
10) Яка найпростіша безпечна рекомендована конфігурація?
NFSv4.2 з systemd automount для продакшен-шерів; SSHFS з keepalives для ad-hoc доступу лише. Якщо тягне зробити навпаки — ви отримаєте дорогий урок.
Висновок: що робити у понеділок вранці
Якщо запам’ятаєте одну річ: віддалені файлові системи — це залежності, що відмовляють всередині syscall’ів. Обирайте протокол, який відповідає вашій терпимості до відмов, а потім налаштуйте його так, щоб відмови були обмежені і видимі.
- Зробіть інвентаризацію монтувань за допомогою
findmntі класифікуйте: критичні записи vs зручні читання. - Мігрируйте продакшен-шляхи до NFSv4.2, де можливо. Тримайте SSHFS для інструментів, а не для основи.
- Додайте systemd automount для некритичних при завантаженні монтувань. Зробіть «storage down» відновлюваним станом.
- Встановіть явні таймаути і keepalives (NFS timeo/retrans; SSH ServerAliveInterval/CountMax).
- Напишіть одну сторінку runbook з кроками швидкої діагностики: перевірка D-state,
timeout stat, логи, retrans, доступність порту.
Мета не «ніколи не відмовляти». Мета — «відмовлятися так, як ви можете вижити, діагностувати і пояснити без брехні». Саме це перетворює монтування з таємниць на керовані залежності — і зберігає ваш on-call від вивчення нових лайливих слів.