Debian 13: тайм-аути NFS — параметри монтування, що покращують стабільність (і коли ні)

Було корисно?

Ваші хости на Debian 13 працюють нормально — доки ні: збірка зависає, веб-вузол перестає обертати логи, або весь робочий вузол Kubernetes виглядає «up», але не може ls директорію. Ви перевіряєте додаток. Нічого. Перевіряєте CPU. Нудно. Потім знаходите це: nfs: server foo not responding, still trying.

Тайм-аути NFS здаються зрадою, бо рідко це одна проблема. Це переговори між клієнтським ядром, сервером, мережею та тим сховищем, що стоїть за сервером. Параметри монтування можуть зробити ці переговори справедливішими — або просто заткнути посланця, поки вогонь поширюється. Зробімо перше.

Що насправді означає «тайм-аут NFS» в Linux

На Debian 13 «тайм-аут NFS» зазвичай повідомляється як клієнтський симптом: RPC до сервера не завершилися в очікуваний час і клієнт повторює запити (або відмовляється, якщо ви примусово налаштували так). Важлива деталь:
більшість «тайм-аутів» — це не одноразове спрацювання таймера. Це серія повторних передач, зворотних відкатів і спроб відновлення стану на кількох рівнях.

Клієнт може чекати через:

  • Доставку по мережі: втрата пакетів, невідповідність MTU, переповнені буфери, перемикані лінки, дивна поведінка ECMP.
  • Обробку RPC на сервері: переповнені потоки nfsd, експорт ФС заблокований на дискових операціях, затримки менеджера блокувань.
  • Сховище за сервером: відновлення RAID, пул тонкого розподілу без вільного місця, перевантажений SSD, неправильно налаштований ARC, патологічні снапшоти.
  • Відновлення стану: оновлення оренди NFSv4, відкликання делегацій, зміни client ID після ребута, періоди grace.

Клієнти Linux NFS також можуть виглядати «завислими», водночас поводячись відповідно до проєктних семантик. hard mount буде повторювати I/O вічно (або дуже довго), бо коректність важливіша за швидке завершення з помилкою. Це не проблема тайм-ауту; це наслідок семантики, яку ви обрали.

Питання, що мають значення:

  • Чи клієнт повторює запити, бо сервер повільний, чи тому, що мережа втрачає пакети?
  • Чи клієнт заблокований у невідмінюваному сні (D) на NFS-викликах?
  • Чи сервер живий, але його бэк-енд сховища завис?
  • Чи обрали ви семантику монтування, що відповідає толерантності робочого навантаження до корупції vs часу простою?

Одна перефразована ідея від Werner Vogels (CTO Amazon): Все ламається; проектуйте так, щоб відмови були рутинними й відновлюваними.

Цікаві факти та історичний контекст

  • NFS старіший за «хмару» на десятиліття: NFS з’явився в середині 1980-х, розроблений для LAN, де «швидко» означало 10 Mbps і бежевий сервер.
  • NFSv3 навмисно «майже без стану»: сервер не зберігає відкритий стан по клієнтах так, як SMB; це зменшує складність сервера, але перекладає біль на блокування й повтори клієнтів.
  • NFSv4 інтегрував блокування: NLM/lockd було окремо в v2/v3; v4 об’єднав блокування і додав stateful протокол з орендою.
  • Налаштування тайм-аутів виникли через RPC поверх UDP: ранні NFS сильно покладався на UDP; поведінка повторів була критичною. TCP покращив транспорт, але не усунув зависання сервера.
  • «Stale file handle» — це фіча, а не баг: файлові дескриптори NFS кодують ідентичність на сервері; якщо інодін видалено або експорт переміщено, клієнт не може видавати його за той самий файл.
  • Війни rsize/wsize колись були реальні: старі мережі й NIC могли призвести до катастрофи продуктивності при поганих розмірах; сучасні значення за замовчуванням розумніші, але jumbo/оверлей мережі все ще можуть кусатися.
  • nconnect відносно новий: декілька TCP-з’єднань на монтування покращують паралелізм; корисно на завантажених клієнтах, але може збільшити навантаження на крихкі сервери.
  • Тайм-аути NFS часто звинувачують неправильний шар: масив сховища під час failover контролера виглядає ідентично «мережевій нестабільності» з точки зору клієнта.

План швидкої діагностики (перший/другий/третій)

Коли кажуть «NFS тайм-аут», виграшний ход — припинити сперечання про прапорці монтування і почати звужувати вузьке місце.
Це порядок, що швидко дає відповіді без зайвих дій.

Перший: підтвердьте режим відмови на клієнті (блокує? повторює? швидко падає?)

  • Перевірте журнали ядра на «not responding» і переходи в «OK».
  • Перевірте, чи процеси застрягли в стані D на NFS-системних викликах.
  • Перевірте статистику RPC клієнта NFS: сплески retrans vs нормальний трафік.

Другий: ізолюйте мережу vs CPU сервера vs сховище сервера

  • Ping недостатньо; перевіряйте втрати пакетів, проблеми з MTU шляху та TCP-повтори.
  • На сервері перевірте насичення потоків nfsd і завантаження системи з I/O wait.
  • На сервері перевірте затримки файлової системи бека: наприклад, iostat, і шукайте завислі пристрої.

Третій: вирішіть, чи параметри монтування — це пом’якшення чи маскування

  • Використовуйте параметри монтування, щоб узгодити семантику (hard vs soft, intr, timeo/retrans) з потребами навантаження.
  • Не «виправляйте» зависання сховища параметром soft, якщо ви не приймаєте ризик часткових записів і корупції на рівні додатку.
  • Переважайте опції, що покращують відновлення і зменшують патологічну поведінку: bg, nofail, розумний timeo, правильна версія протоколу і порядок systemd.

Параметри монтування, що допомагають стабільності (та пастки)

Стабільність NFS — це не лише «не тайм-аутитись». Це «коли щось повільно або зламалося, відмовлятися так, щоб система вижила». Це означає правильні дефолти для загального призначення і цільові винятки для робочих навантажень, що їх терплять.

Hard vs soft: обирайте семантику, не відчуття

hard означає, що клієнт повторює I/O, поки він не вдасться. Саме тому ви бачите «still trying».
Це правильний вибір для цілісності даних і більшості POSIX-подібних робочих навантажень. Воно також може заморозити потоки вашого додатку, якщо сервер зникне. Це ціна.

soft означає, що клієнт здається після повторів і повертає помилку додатку.
Здається «стабільним», поки ви не помітите: деякі додатки трактують помилки I/O як тимчасові і продовжують роботу, можливо після часткових записів або несподівано коротких читань. Ви не зробили NFS надійнішим; ви зробили відмову швидшою і більш креативною.

Поради:

  • Використовуйте hard для всього, що записує важливі дані: бази даних, черги повідомлень, сховища артефактів, домашні директорії.
  • Розглядайте soft лише для content read-mostly, кешованого, некритичного вмісту, де помилки прийнятні і обробляються (наприклад, рендер-ферма, що може повторно завантажити входи).
  • Якщо обрали soft, задокументуйте очікування з власниками додатків письмово. Ви змінюєте семантику, а не просто налаштовуєте.

Жарт №1: soft-монтування — як «тимчасове» правило firewall — всі його забувають, доки інцидент не потребує винного.

timeo і retrans: що вони насправді контролюють

У Linux NFS timeo не «час до відмови». Це базовий RPC-тайм-аут перед повтором, у десятих долях секунди для багатьох конфігурацій (звично: timeo=600 означає 60 секунд). Ефективне очікування може бути значно довшим через експоненційний backoff і повтори.

retrans — це скільки разів повторювати RPC перед ескалацією поведінки (а для soft — перед поверненням помилки).
Зменшення timeo може змусити клієнта швидше виявляти проблеми, але також збільшити навантаження під час конгестії через частіші повтори.
Збільшення timeo може зменшити шторм повторів на нестабільних мережах, але робить реальні відмови відчутно довшими.

Практичні поради:

  • Для стабільних LAN значення за замовчуванням часто підходять. Тюньте тільки за наявності доказів: сплески retrans, відомі WAN-канали або знані серверні зависання.
  • Для WAN-подібних або втратних лінків трохи вищий timeo може зменшити трясіння; не робіть його хвилинами, якщо вам не подобається, як люди перезавантажують вузли від безвиході.
  • Якщо бачите короткі паузи (кілька секунд) через failover сервера, не реагуйте надто агресивно з крихітним timeo; дайте відновленню відбутися.

proto=tcp і версії NFS: обирайте протокол, який можете підтримувати

У сучасному Debian слід використовувати TCP. UDP — переважно музейний експонат, якщо ви не працюєте навколо дуже дивної ситуації.
TCP дає кращу поведінку при втраті і опрацьовує великі payload-и більш адекватно.

Вибір версії:

  • NFSv4.x (включно з 4.1/4.2) зазвичай найкращий дефолт: менше портів для управління, інтегроване блокування, краща історія firewall.
  • NFSv3 досі може бути правильним вибором при застарілих серверах, деяких NAS-пристроях або рідкісних випадках. Але воно вимагає більше рухомих частин (rpcbind, mountd, lockd/statd).

З погляду стабільності: відновлення стану v4 може бути болісним під час ребутів сервера (grace-періоди), але при належній конфігурації воно передбачуваніше.
v3 може здаватися «простішим», поки ви не будете дебажити відновлення блокувань о 2-й ночі.

vers=4.1 або vers=4.2 vs «що домовляться»

Дозволяти клієнту й серверу домовлятися про версію іноді нормально, але саме так ви опиняєтесь з несподіваними даунгрейдами після змін.
Якщо ви працюєте в продакшені, фіксуйте версію, якщо немає причин інакше.

  • Фіксуйте vers=4.1, якщо сервер відомо стабільний на 4.1 і вам не потрібні фічі 4.2.
  • Використовуйте vers=4.2, якщо обидві сторони його підтримують і ви протестували. Деякі 4.2-фічі (наприклад, server-side copy/clone в деяких стеках) чудові; багаті реалізації — ні.

actimeo і кешування атрибутів: стабільність vs коректність

actimeo (і дрібніші acregmin/acregmax/acdirmin/acdirmax) контролює кешування атрибутів.
Збільшення часу кешу зменшує metadata RPC, що допомагає при навантаженні і зменшує експозицію до тимчасової повільності.
Воно також може змусити клієнти довше бачити застарілу метадані, що ламає додатки, які очікують close-to-open консистентності.

Випадки використання:

  • Build-farms і CI, що читають спільні залежності: більше кешування атрибутів може бути вигідним.
  • Спільні домашні директорії з частими правками з різних хостів: не ускладнюйте; тримайте дефолти або консервативні значення.

rsize/wsize: не гоніться за бенчмарками, слідкуйте за хвостовою затримкою

Більші розміри I/O можуть покращити пропускну здатність, але погіршити хвостову затримку, якщо сервер або мережа страждають від великих сплесків.
Сучасні дефолти зазвичай підходять. Якщо тюните — робіть вимірювання і мати план відкату.

Загальна схема стабільності: зменшити wsize трохи, коли крихкий сервер падає під важкими write-сплесками.
Але якщо ви це робите — ви лікуєте симптом; реальне виправлення — це потужність серверного/сховищного боку.

nconnect: більше паралелізму, більше способів перевантажити сервер

nconnect=N відкриває кілька TCP-з’єднань на одне монтування. Це може суттєво допомогти завантаженим клієнтам з паралельним I/O,
особливо коли один TCP-потік стає вузьким місцем.

Трейд-офи стабільності:

  • На надійних серверах це може зменшити тайм-аути, покращивши пропускну здатність і зменшивши черги.
  • На маргінальних серверах це може підсилити навантаження і зробити зависання частішими.

Рекомендація: почніть з nconnect=4 для клієнтів з високою пропускною, якщо потужність сервера відома як гарна; моніторьте CPU сервера, nfsd-потоки та затримки.

noatime: невеликий виграш, іноді реальний

Відключення atime-записів зменшує write-трафік для read-heavy навантажень. Це не виправить тайм-аути, спричинені серверними зависаннями,
але може зменшити фоновий шум і покращити стабільність при граничному навантаженні.

Параметри для стабільності під час завантаження системи: nofail, bg і тайм-аути systemd

Багато «інцидентів з тайм-аутами NFS» починаються як «хост не завантажується, бо NFS ще не доступний». Це не проблема продуктивності NFS.
Це питання порядку завантаження і обробки помилок.

  • nofail дозволяє продовжити завантаження, якщо монтування недоступне. Чудово для некритичних монтувань; небезпечно для необхідних.
  • bg (переважно для поведінки NFSv3) переводить спроби монтування в бекграунд після початкової спроби, дозволяючи завантаженню продовжитись.
  • x-systemd.automount створює on-demand automount; система завантажується, а монтування відбувається лише при зверненні. Це потужна опція для стабільності при обережному використанні.
  • x-systemd.mount-timeout= контролює, скільки systemd чекає на юніт монтування. Ви можете уникнути хвилинних зависань при завантаженні.

Блокування та «преривність»: знайте, на що підписуєтесь

Старі рецепти включали intr для переривання NFS-операцій сигналами. Сучасні ядра змінили поведінку; для багатьох налаштувань це або стандарт, або не має значення.
Сенс лишається: вбити процес, застряглий на NFS I/O, не завжди можливо, бо ядро чекає відповіді від сервера.

Якщо вам потрібно «kill завжди працює», NFS-семантика не підходить. Вам потрібна інша архітектура: локальний буферинг, асинхронна реплікація або об’єктне сховище.

Жарт №2: Тюнінг тайм-аутів NFS без вимірювання сервера — як лагодити повільний ліфт, змінюючи наклейку на кнопці «Close Door».

Особливості Debian 13: systemd, ядро, значення за замовчуванням

Debian 13 постачається з сучасним ядром і поведінкою systemd, що робить NFS-монтування відчутно відмінними від епохи «відредагував fstab, перезавантажив, молився».
Відповідні операційні зміни:

  • systemd трактує монтування як юніти з залежностями; порядок відносно network-online.target має значення для віддалених монтувань.
  • remote-fs.target може блокувати сервіси, якщо монтування є «обов’язковими». Визначте явно, що має блокуватися, а що ні.
  • Утиліти клієнта NFS розділені: клієнт забезпечується ядром; утиліти користувацького простору допомагають у діагностиці та конфігурації. Переконайтесь, що у вас встановлено nfs-common на клієнтах.

Мій упереджений базовий набір для «звичайного» продукційного клієнтського монтування на Debian 13 (NFSv4.1 у LAN) виглядає так:

cr0x@server:~$ cat /etc/fstab
nfs01:/export/shared  /mnt/shared  nfs  vers=4.1,proto=tcp,hard,timeo=600,retrans=2,noatime,_netdev,x-systemd.automount,x-systemd.idle-timeout=60  0  0

Чому така комбінація?

  • hard зберігає семантику даних коректною.
  • timeo=600,retrans=2 — консервативно (не занадто мало) і запобігає молотінню під час коротких збоїв; тюньте тільки за доказами.
  • x-systemd.automount уникає ситуацій, коли завантаження блокується через недоступність NFS для багатьох робочих навантажень.
  • x-systemd.idle-timeout=60 дозволяє automount йти в idle; це зменшує застарілий стан на ноутбуках чи епhemeral вузлах.
  • _netdev сигналізує «це залежить від мережі» для порядкування.

Коли цей базис не підходить:

  • Якщо монтування має бути доступне до запуску критичних сервісів (наприклад, бінарники розміщені там), automount може створити несподівану латентність при першому доступі. Краще змонтувати раніше і швидко провалюватися, або перепроєктувати.
  • Якщо ви в високолатентному WAN, можливо, знадобиться вищий timeo і обережні налаштування кешування.
  • Якщо ваш сервер робить планові failover-и, тестуйте відновлення під навантаженням; прапорці монтування не врятують від контролера сховища, що ставить паузу на 45 секунд.

12+ практичних завдань: команди, виводи, рішення

Нижче — операційні завдання, які я дійсно запускав би. Кожне включає, на що дивитися і яке рішення воно формує.
Запускайте їх спочатку на клієнті, потім на сервері. Ви будуєте хронологію і звужуєте шар, що брехав.

Завдання 1: Підтвердьте, що змонтовано і з якими опціями

cr0x@server:~$ findmnt -t nfs,nfs4 -o TARGET,SOURCE,FSTYPE,OPTIONS
TARGET       SOURCE              FSTYPE OPTIONS
/mnt/shared  nfs01:/export/shared nfs4  rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.10.2.15,local_lock=none

Що це значить: ви використовуєте NFSv4.1 поверх TCP з hard-монтуванням; клієнт буде повторювати запити. rsize/wsize показують узгоджені значення.

Рішення: якщо бачите несподіване vers=3, udp або відсутнє hard, виправте визначення монтування перед тим, як шукати примар.

Завдання 2: Слідкуйте за журналами ядра на «not responding» і «OK» флапи

cr0x@server:~$ sudo journalctl -k -g 'nfs' -S -2h
Dec 29 09:12:41 client01 kernel: nfs: server nfs01 not responding, still trying
Dec 29 09:13:10 client01 kernel: nfs: server nfs01 OK
Dec 29 09:27:02 client01 kernel: nfs: server nfs01 not responding, still trying

Що це значить: у вас періодичні затримки, а не чистий аут. Рядок «OK» підказує, що відновлення відбувається.

Рішення: періодичні затримки спрямовують розслідування у бік серверних/сховищних затримок і втрат у мережі, а не DNS чи помилок у fstab.

Завдання 3: Перевірте процеси, що застрягли в невідмінюваному сні (D state)

cr0x@server:~$ ps -eo pid,state,comm,wchan:32,args | awk '$2=="D"{print}' | head
21453 D  tar          nfs_wait_on_request      tar -cf /mnt/shared/backup.tar /var/lib/app
30112 D  rsync        rpc_wait_bit_killable    rsync -a /data/ /mnt/shared/data/

Що це значить: користувацькі процеси заблоковані в очікуванні NFS/RPC. Вбивати їх може не допомогти, поки ядро не завершить I/O або не спрацюють семантики timeout.

Рішення: якщо багато процесів в D, розглядайте це як інфраструктурний інцидент, а не баг додатку. Продовжуйте до статистики RPC і перевірок сервера.

Завдання 4: Перегляньте статистику RPC клієнта NFS на предмет повторів

cr0x@server:~$ nfsstat -c
Client rpc stats:
calls      retrans    authrefrsh
128904     8421       0

Client nfs v4:
null         read         write        commit       open         open_conf
0            48210        19342        0            188          0

Що це значить: retrans високий відносно calls (тут ~6.5%). Зазвичай це означає втрати пакетів, конгестію або серверні затримки, що тривають достатньо довго, щоб викликати повтори.

Рішення: якщо retrans близько до нуля, проблема може бути на боці додатку або блокування на сервері без втрат пакетів (також можливо). Якщо retrans високий — пріоритет мережі та реактивності сервера.

Завдання 5: Підтвердьте базову доступність шляху і виявлення втрат (не лише латентності)

cr0x@server:~$ ping -c 50 -i 0.2 nfs01
PING nfs01 (10.10.2.20) 56(84) bytes of data.
64 bytes from 10.10.2.20: icmp_seq=1 ttl=64 time=0.424 ms
64 bytes from 10.10.2.20: icmp_seq=2 ttl=64 time=0.391 ms
...
--- nfs01 ping statistics ---
50 packets transmitted, 50 received, 0% packet loss, time 10047ms
rtt min/avg/max/mdev = 0.320/0.410/0.690/0.072 ms

Що це значить: немає очевидної втрати ICMP; гарний знак, але не доказ. ICMP може мати іншу пріоритизацію, ніж трафік NFS.

Рішення: якщо тут є втрата, у вас мережевий інцидент. Якщо ні — продовжуйте з TCP і лічильниками інтерфейсу.

Завдання 6: Перевірте лічильники інтерфейсу на предмет drop-ів і помилок на клієнті

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
      912345678  854321      0    412       0   12345
    TX:  bytes packets errors dropped carrier collsns
      812345001  743210      0      0       0       0

Що це значить: RX drops вказують на конгестію, переповнення ring buffer або upstream-проблеми. Drops добре корелюють з retrans RPC.

Рішення: якщо drops збільшуються під час інцидентів, досліджуйте NIC offload-настройки, завантаження хоста, конгестію на комутаторі і MTU. НЕ чіпайте ще тайм-аути NFS.

Завдання 7: Перевірте узгодженість MTU і шукайте підказки щодо фрагментації

cr0x@server:~$ ip link show dev eth0 | grep -E 'mtu|state'
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000

Що це значить: MTU — 1500. Якщо ваша мережа використовує jumbo frames непослідовно, ви можете отримати PMTU blackhole, що виглядає як «випадкові зависання NFS».

Рішення: якщо підозрюєте невідповідність MTU, тимчасово стандартизуйтесь на 1500 кінь-в-кінь або забезпечте узгодженість jumbo (хости, комутатори, bonds, VLAN, оверлеї).

Завдання 8: Перевірте TCP-повтори на клієнті

cr0x@server:~$ nstat -az | egrep 'TcpRetransSegs|TcpTimeouts'
TcpRetransSegs                 1932
TcpTimeouts                    41

Що це значить: TCP retrans і timeouts вказують на втрати мережі або серйозну конгестію — не чисто серверну проблему NFS.

Рішення: якщо ці показники стрибали під час інцидентів — фокус на мережевому шляху і чергах NIC. Якщо стабільні — більше приділяйте увагу затримкам сервера/сховища.

Завдання 9: Підтвердьте, що сервер досяжний на очікуваних портах і протоколі

cr0x@server:~$ sudo ss -tn dst 10.10.2.20 | head
State  Recv-Q Send-Q Local Address:Port   Peer Address:Port  Process
ESTAB  0      0      10.10.2.15:51144    10.10.2.20:2049
ESTAB  0      0      10.10.2.15:51146    10.10.2.20:2049

Що це значить: активні TCP-з’єднання до порту 2049 (NFS). Якщо ви очікували NFSv4 і бачите купу допоміжних портів — можливо, ви на v3.

Рішення: якщо з’єднання флапають або Recv-Q росте — може бути серверна повільність або мережеве чергування. Перейдіть до метрик сервера.

Завдання 10: На сервері перевірте насичення потоків nfsd і базове здоров’я

cr0x@server:~$ sudo cat /proc/net/rpc/nfsd | head -n 20
rc 0 0 0
fh 0 0 0 0 0
io 123456 654321
th 64 0 0.000 0.000 0.000 0.000 0 0 0 0
ra 32 0 0 0 0 0 0 0 0 0 0 0
net 0 0 0 0
rpc 1234 0 0 0 0 0 0 0 0 0 0
proc2 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
proc3 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
proc4 2 0 0

Що це значить: рядок th показує число nfsd-потоків (тут 64). Якщо це число мале на завантаженому сервері — отримаєте черги.

Рішення: якщо nfsd-потоків замало — збільшіть їх відповідно (і забезпечте доступний CPU). Якщо потоків достатньо, але зависання лишаються — дивіться затримки бека сховища.

Завдання 11: На сервері швидко помітити I/O wait і заблоковане сховище

cr0x@server:~$ sudo iostat -xz 1 5
Linux 6.10.0 (nfs01)  12/29/2025  _x86_64_ (16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.10    0.00    4.20   38.50    0.00   45.20

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz  aqu-sz  %util
nvme0n1         210.0  16800.0     0.0   0.00    8.20    80.0     95.0   9200.0     0.0   0.00   62.30    96.8    7.10   92.0

Що це значить: високий %iowait плюс високий w_await і велике %util вказують на насичення або високу затримку сховища.

Рішення: якщо беке сховище — вузьке місце, параметри монтування не вилікують. Потрібні потужність сховища, кеші, налаштування черг або обмеження навантаження.

Завдання 12: Підтвердьте експорти та доступ по клієнтах на сервері

cr0x@server:~$ sudo exportfs -v
/export/shared  10.10.2.0/24(rw,wdelay,root_squash,sec=sys,async,no_subtree_check,fsid=0)
/export/backups 10.10.2.15(rw,root_squash,sec=sys,sync,no_subtree_check)

Що це значить: показує опції експорту. Зауважте різницю між async і sync, та область доступу по клієнтах/мережах.

Рішення: якщо бачите випадкове sync на навантаженому експорті (або навпаки), ви знайшли важіль стабільності/продуктивності — працюйте обережно і тестуйте. Також перевірте, чи дозволені потрібні клієнти; відмова в доступі може виглядати як тайм-аут для додатків.

Завдання 13: Перевірте логи NFS-сервера на grace-періоди і події відновлення

cr0x@server:~$ sudo journalctl -u nfs-server -S -2h | tail -n 30
Dec 29 09:11:58 nfs01 systemd[1]: Starting NFS server and services...
Dec 29 09:11:58 nfs01 kernel: NFSD: starting 64-second grace period (net ffffffff9a6a0000)
Dec 29 09:12:02 nfs01 systemd[1]: Started NFS server and services.

Що це значить: grace-періоди впливають на відновлення стану NFSv4 і повернення блокувань. Під час grace деякі операції можуть блокуватись або давати специфічні помилки.

Рішення: якщо тайм-аути кластуються навколо рестартів/failover-ів сервера — плануйте для grace/відновлення: retry додатків, maintenance-окна або HA, що зберігає стан правильно.

Завдання 14: Перевірте відповідність імен і idmap (NFSv4 проблема, що схожа на «зависання»)

cr0x@server:~$ nfsidmap -c
cr0x@server:~$ nfsidmap -l | head
0x00000001: user@domain
0x00000002: nobody@domain

Що це значить: кеші idmap можуть застаріти або бути неправильно налаштовані, спричиняючи аномалії з правами, які помилково інтерпретують як «NFS зламався».

Рішення: якщо користувачі бачать «permission denied» або дивні власності на змонтованих шляхах — перевірте idmapping і узгоджену стратегію UID/GID перед тим, як чіпати тайм-аути.

Завдання 15: Протестуйте відчутну латентність контрольним циклом малих I/O

cr0x@server:~$ time bash -c 'for i in {1..200}; do echo $i > /mnt/shared/.lat_test.$i; done'
real    0m2.913s
user    0m0.059s
sys     0m0.351s

Що це значить: швидка перевірка для малих синхронних записів. Повторіть під час інциденту; якщо real стрибає — ви бачите затримки сховища або обробки на сервері.

Рішення: якщо малі записи стають секундними або хвилинними — параметри монтування не допоможуть. Досліджуйте диски сервера, опції експорту (sync/async) і навантаження сервера.

Три корпоративні міні-історії з практики

Міні-історія 1: Інцидент через хибне припущення («hard mounts — проблема»)

Середня компанія мала Debian-клієнти, що монтували спільний NFS-експорт для CI-артефактів. Збірки почали «рандомно зависати».
Платформ-команда помітила процеси в D і вирішила, що монтування — проблема. Вони переключили монтування на soft,timeo=50,retrans=2.

Зависання припинилися. Квитки втихли. Двотижні потому release-engineering виявили пошкоджені артефакти:
tarball-и, що розпаковувалися з відсутніми файлами, хеші не сходилися, і кілька збірок «успішно» завершилися, але їх не можна було відтворити.
Логи показували іноді EIO від write-викликів, які інструменти збірки не вважали фатальними, бо не були розраховані на ненадійне сховище.

Підлягаюча причина була в масиві сховища за NFS-сервером, що час від часу мав латентні сплески під час очищення снапшотів.
Сервер не «падав», він іноді не міг обслуговувати RPC вчасно; клієнти повторювали, а потім — при soft — відмовлялися.

Вони відкотили до hard, потім виправили справжню причину: графік снапшотів і запас потужності масиву.
Також додали перевірку артефактів і зробили правило: «I/O помилки — фатальні» в CI-пайплайні.
Урок не був «ніколи soft монтувати». Це був урок: «не використовуйте семантику як ручку налаштування».

Міні-історія 2: Оптимізація, що обернулась проти (агресивне кешування та jumbo frames)

Інша організація мала швидкий NFS-сервер і хотіла зменшити навантаження на метадані. Хтось налаштував кешування атрибутів:
actimeo=60 по флоту, плюс більші rsize/wsize, плюс увімкнення jumbo frames на нових хостах.
Пропускна здатність в тестах була відмінна. Менше RPC, більше MB/s. Слайди були зроблені. Просування майже відбулося.

Потім підмножина клієнтів почала бачити дивні зависання і «server not responding» у пікові години.
Не всі клієнти. Не завжди. Проблема, що перетворює впевнених інженерів на аматорів астрології.

Причина була в невідповідності MTU через пару портів комутаторів у leaf-парі.
Деякі шляхи обробляли jumbo, деякі мовчки скидали надвеликий трафік. TCP PMTU discovery не завжди відновлювався через фільтрацію ICMP «fragmentation needed» на сегменті firewall, який «не мав бути в шляху».

Кешування спочатку маскувало проблему (менше метаданих), але більші розміри I/O плюс jumbo зробили чорну діру більш болючою.
Виправили узгодженість MTU і дозволили потрібні ICMP — стабільність повернулась. Вони залишили помірне кешування, але перестали вважати мережу магічною ідеальною підставою.

Міні-історія 3: Нудна практика, що врятувала день (automount + явний порядок)

Компанія, що працювала поруч з фінансами, мала звичку: кожне NFS-монтування у fstab використовувало _netdev,x-systemd.automount,x-systemd.mount-timeout=15,
а «критичні» монтування мали окремий юніт, який вимагав network-online.target плюс health-check.
Це не було гламурним. Це не підвищувало бенчмарків. Це була проста доросла наглядовість під час завантаження.

Одного дня core-комутатор несподівано перезавантажився. Половина флоту втратила мережу на кілька хвилин.
Драматичні сервіси мигнули; нудні — відновились. Головне: хости не застрягли під час завантаження і не блокували несуміжні сервіси.
Коли NFS-сервер знову став доступний, automount відновив монтування по доступу.

Вони все ще мали помилки додатків (через мережевий розрив), але не мали вторинної катастрофи: застряглих завантажень, завислих деплойментів і панічних перезавантажень, що уповільнювали відновлення. Постмортем мав рідкісний рядок: «Конфігурація монтувань поводилась як задумано».

Практика не була хитрою. Вона була правильною. І в продакшені «правильне» старіє краще, ніж «хитре».

Поширені помилки: симптом → корінь → виправлення

1) «server not responding» спам, але ping в порядку

Симптом: журнали ядра показують NFS not responding; ICMP ping не показує втрат.

Корінь: серверні затримки сховища або насичення nfsd; ICMP не відображає прикладну RPC-латентність.

Виправлення: перевірте iostat сервера на високий await/%util; перевірте потоки nfsd; збільште запас потужності сховища. Не тюньте timeo навмання.

2) Зависання при завантаженні, що триває вічно через NFS

Симптом: рестартований вузол сидить на «A start job is running for /mnt/shared».

Корінь: обов’язкове монтування без правильного порядку systemd/тайм-аутів; мережа ще не «online», або NFS-сервер недоступний.

Виправлення: використовуйте _netdev, x-systemd.automount та явний x-systemd.mount-timeout=. Для справді потрібних монтувань вмикайте gating сервісів і швидкий провал.

3) Випадковий «permission denied» після успішного монтування

Симптом: монтування успішне; користувачі бачать неправильну власність або відмову в доступі; називають це «NFS flaky».

Корінь: невідповідність idmapping NFSv4 (домен), неузгоджені UID/GID, застарілий кеш idmap.

Виправлення: стандартизуйте ідентичності (LDAP/SSSD або узгоджені локальні IDs), налаштуйте idmap домен, очистіть кеші через nfsidmap -c.

4) Процеси клієнта в D-state годинами

Симптом: невбивні процеси; система «up», але непридатна.

Корінь: hard-семантика монтування + сервер недоступний або I/O завис; іноді ускладнюється мережевою чорної дірою.

Виправлення: відновіть сервер/мережу. Якщо це неприйнятно операційно — перепроєктуйте: локальний буферинг, асинхронні канали або відокремте критичні шляхи від NFS.

5) «Stale file handle» після обслуговування сервера або зміни експорту

Симптом: додатки падають на існуючих шляхах; нові монтування працюють.

Корінь: серверні об’єкти ФС змінилися/перемістилися; експорт перемаплено; underlying FS пересоздано; снапшоти відкотилися.

Виправлення: перемонтуйте клієнти; уникайте зміни ідентичності кореня експорту; використовуйте стабільні експорти; документуйте кроки обслуговування, що інвалідизують дескриптори.

6) Перехід на soft «виправляє» тайм-аути, але спричиняє мовчазні проблеми з даними

Симптом: менше зависань; пізніше бачите пошкоджені файли або неповні результати без явних помилок.

Корінь: soft-монтування повертає помилки під час операції; додаток не трактує це як фатальну помилку; часткові результати залишаються.

Виправлення: поверніться до hard для записів; додайте наскрізні перевірки цілісності; виправте сервер/мережу, що спричиняє retrans.

7) nconnect покращує пропускну здатність, потім тайм-аути погіршуються

Симптом: в тестах вища пропускна здатність; у продакшені сервер стає менш відзивним; з’являються тайм-аути.

Корінь: збільшений паралелізм підсилює навантаження на CPU сервера, nfsd або сховище; чергування збільшує хвостову латентність.

Виправлення: зменшіть nconnect, збільшіть потужність сервера або ізолюйте навантаження; виміряйте серверну латентність і насичення потоків.

Контрольні списки / покроковий план

Чекліст A: стабілізувати спочатку, потім тюнити

  1. Підтвердьте семантику монтування: тримайте hard для всього, що записує важливі дані.
  2. Запобігайте «заручникам» при завантаженні: додавайте _netdev,x-systemd.automount,x-systemd.mount-timeout=15 для некритичних монтувань.
  3. Фіксуйте протокол/версію: обирайте свідомо vers=4.1 або vers=4.2; забезпечуйте proto=tcp.
  4. Виміряйте retrans: використовуйте nfsstat -c і nstat перед зміною timeo.
  5. Виправляйте повільний шар: мережеві втрати, насичення CPU сервера або затримки сховища. Параметри монтування — не двигун.

Чекліст B: рішення по параметрах монтування за робочим навантаженням

  • Бази даних на NFS: уникайте, якщо можливо; якщо змушені — використовуйте hard, консервативне кешування, перевірте гарантії сервера і тестуйте відновлення при failover.
  • Домашні директорії: hard, дефолти кешування; фокус на HA сервера і стабільності мережі.
  • Read-mostly спільні залежності: розгляньте tweaks кешування атрибутів; розгляньте x-systemd.automount, щоб уникнути проблем при завантаженні.
  • Ефемерні обчислювальні вузли: automount з idle timeout зменшує довгоживучий застарілий стан і робить ребути менш драматичними.
  • WAN-лінки: прийміть вищу латентність; тюньте timeo вгору помірно; розгляньте локальні кеші замість того, щоб вдавати, що WAN — LAN.

Покроково: розумний план змін для параметрів монтування

  1. Виберіть один клієнт як канар. Не «флотовий» rollout у стилі вчимося методом підпалювання.
  2. Запишіть базову лінію: findmnt, nfsstat -c, nstat і короткий таймінг I/O циклу.
  3. Змініть одну вісь (наприклад, зафіксуйте vers=4.1 або додайте x-systemd.automount).
  4. Повторно протестуйте під навантаженням; стежте iostat сервера і nfsd-статистику.
  5. Розгорніть поступово. Зберігайте інструкції з відкату в таску/квитку, а не в чиїйсь голові.

FAQ

1) Використовувати hard чи soft, щоб уникнути «зависань»?

Використовуйте hard для коректності, особливо для записів. soft запобігає невизначеному блокуванню, повертаючи помилки,
але змінює семантику і може спричинити корупцію даних у додатків, що погано поводяться при помилках.

2) Які добрі значення за замовчуванням для timeo і retrans?

Починайте з дефолтів, якщо немає доказів. Поширена консервативна пара — timeo=600,retrans=2 для LAN-навантажень.
На втратахих або високолатентних лінках зростайте timeo помірно; не просто крутіть кількість повторів.

3) Чому я бачу «server not responding», а потім «OK»?

Бо клієнт повторює RPC, і сервер врешті-решт відповідає. Така картина часто вказує на тимчасові мережеві втрати,
перевантаження сервера або сплески латентності в сховищі за сервером.

4) Чи робить x-systemd.automount NFS надійнішим?

Воно робить завантаження і запуск сервісів більш стійким, уникаючи жорсткої залежності від миттєвого успіху монтування. Воно не лікує повільний сервер,
але запобігає тому, щоб повільний сервер ламав несуміжні частини системи.

5) Чи можна «виправити» тайм-аути NFS, змінивши rsize/wsize?

Іноді можна зменшити симптоми, особливо в крихких мережах або на певних пристроях, але це не корінь проблеми.
Тюньте під хвостову латентність і стабільність, а не під пік-пропускну здатність.

6) Чи завжди NFSv4 кращий за NFSv3?

Не завжди, але зазвичай. NFSv4 простіший для firewall і має чистішу протокольну історію. NFSv3 може бути прийнятним у стабільних середовищах,
але додає допоміжні сервіси і порти, що збільшує операційні режими відмов.

7) Що означає, коли процеси stuck в D стані?

Вони чекають на I/O ядра, який важко перервати. Якщо це пов’язано з NFS, ядро чекає на завершення RPC.
Вирішіть підлягаючу проблему з підключенням або сервером; не сподівайтесь, що kill -9 врятує ситуацію.

8) Чи можуть firewall/NAT проблеми спричинити тайм-аути NFS, навіть якщо з’єднання є?

Так. Stateful firewall-и, що таймаутять неактивні потоки, асиметрична маршрутизація, MTU blackhole-и та фільтрація ICMP — усе це може спричинити зависання,
що виглядають як «NFS flakiness». Саме тому рано перевіряти TCP retrans і drop-и інтерфейсу.

9) Коли доречно nofail?

Для монтувань, що корисні, але не необхідні для завантаження або здоров’я основних сервісів — наприклад, опціональні спільні інструменти або кеші.
Не використовуйте його для критичних монтувань, якщо ви не додали явний health-gating у сервіси.

10) Якщо мені потрібно «ніколи не блокувати», що робити замість NFS?

Використовуйте локальне сховище з реплікацією або архітектуру, що переносить відмову віддаленого сховища: об’єктне сховище, артефактні сховища з content-addressed підходом,
або write-behind буферизацію з чіткими гарантіями довговічності. NFS чудовий, але не чарівний.

Висновок: що робити далі

Якщо ви візьмете одну операційну ідею з тайм-аутів NFS на Debian 13, візьміть цю: параметри монтування — це не ліки,
це контракт. Спочатку встановіть контракт (hard vs soft, версія протоколу, поведінка при завантаженні), а потім міряйте, де система фактично повільна.

Практичні кроки на цей тиждень:

  1. Перерахуйте всі NFS-монтування за допомогою findmnt; стандартизуйте на TCP і фіксуйте версії, де доречно.
  2. Додайте x-systemd.automount і тайм-аути монтування для некритичних монтувань, щоб уникнути «заручників» при завантаженні.
  3. Зберіть мінімальний «NFS incident pack»: nfsstat -c, nstat, ip -s link, журнали ядра клієнта, iostat сервера і /proc/net/rpc/nfsd.
  4. Запустіть контрольний failover/reboot сервера NFS і спостерігайте поведінку клієнтів, включно з grace-періодами, під навантаженням.
  5. Коли потрібно тюнити timeo/retrans, робіть це як експеримент на канарі, а не як догму.
← Попередня
Стиснення ZFS за допомогою zstd: вибір рівнів без перевантаження CPU
Наступна →
Драма 12VHPWR: як один конектор став легендою

Залишити коментар