Диагностика NFSv4
> [!INFO] Применимость > **ALT Linux 10.4–11.x** · только NFSv4.0/4.1/4.2 · сервер и клиент Linux · CLI/TTY · доступ `root` > > Цель: определить, находится ли проблема в DNS, TCP/2049, конфигурации ex
[!INFO] Применимость
ALT Linux 10.4–11.x · только NFSv4.0/4.1/4.2 · сервер и клиент Linux · CLI/TTY · доступrootЦель: определить, находится ли проблема в DNS, TCP/2049, конфигурации export, правах, state recovery, клиентском mount или серверном хранилище.
Для NFSv4 не использовать
showmountкак основной диагностический инструмент. Он относится к старому протоколу MOUNT и может не показывать рабочие NFSv4 exports.
Оглавление
- [[#Быстрый алгоритм|Быстрый алгоритм]]
- [[#Сбор исходных данных|Сбор исходных данных]]
- [[#Уровень 1. DNS и сеть|Уровень 1. DNS и сеть]]
- [[#Уровень 2. Версия NFSv4|Уровень 2. Версия NFSv4]]
- [[#Уровень 3. Сервер и exports|Уровень 3. Сервер и exports]]
- [[#Уровень 4. Клиентский mount|Уровень 4. Клиентский mount]]
- [[#Уровень 5. Права и ID mapping|Уровень 5. Права и ID mapping]]
- [[#Уровень 6. Состояние NFSv4 и locks|Уровень 6. Состояние NFSv4 и locks]]
- [[#Уровень 7. Backend storage сервера|Уровень 7. Backend storage сервера]]
- [[#NFS server not responding|NFS server not responding]]
- [[#Stale file handle|Stale file handle]]
- [[#Процессы в состоянии D|Процессы в состоянии D]]
- [[#Долгая загрузка или выключение|Долгая загрузка или выключение]]
- [[#Kerberos-ошибки|Kerberos-ошибки]]
- [[#Таблица ошибок|Таблица ошибок]]
- [[#Сбор диагностического пакета|Сбор диагностического пакета]]
- [[#Расширенная отладка|Расширенная отладка]]
- [[#Что не делать|Что не делать]]
- [[#Источники|Источники]]
Быстрый алгоритм
На клиенте:
su -
getent hosts <SERVER_FQDN>
timeout 3 bash -c '</dev/tcp/<SERVER_FQDN>/2049'
echo $?
mount -t nfs \
-o nfsvers=4.2,proto=tcp,hard \
<SERVER_FQDN>:/<EXPORT_PATH> \
<MOUNTPOINT>
После ошибки:
journalctl -k -b -n 100 --no-pager
Если mount уже существует:
nfsstat -m
mountstats /<MOUNTPOINT>
На сервере:
systemctl status nfs --no-pager
cat /proc/fs/nfsd/versions
exportfs -v
ss -lntp | grep ':2049'
journalctl -b -u nfs --no-pager
Локализация:
| Где сломалось | Вероятный уровень |
|---|---|
| DNS | NSS/DNS |
| TCP/2049 | Маршрут, firewall, сервер |
| 4.2 не монтируется, 4.1 работает | Сервер не поддерживает 4.2 |
access denied by server |
/etc/exports, IP клиента, sec= |
| Mount есть, запись запрещена | Unix-права, ACL, UID/GID |
| Mount зависает | Сеть, сервер, backend storage |
Stale file handle |
Export/FS был заменён или inode исчез |
nobody |
ID mapping или отсутствующий пользователь |
| Kerberos ticket есть, доступа нет | Principal mapping, sec=, ACL |
| После перезапуска сервера locks не возвращаются | State recovery/grace/client identity |
Сбор исходных данных
Зафиксировать:
ALT Linux client:
ALT Linux server:
Client kernel:
Server kernel:
nfs-utils:
Server FQDN:
Server IP:
Client IP:
Export:
Mountpoint:
Requested version:
Negotiated version:
Security flavor:
Когда началась проблема:
Что изменялось:
Есть ли другие работающие клиенты:
Команды клиента:
cat /etc/os-release
uname -a
mount.nfs -V
nfsstat -m
findmnt -rn -t nfs,nfs4 -o TARGET,SOURCE,FSTYPE,OPTIONS
Команды сервера:
cat /etc/os-release
uname -a
rpc.nfsd --version
exportfs -v
cat /proc/fs/nfsd/versions
Уровень 1. DNS и сеть
DNS
getent ahosts <SERVER_FQDN>
host <SERVER_FQDN>
Сравнить IP с ожидаемым.
Маршрут
ip route get <SERVER_IP>
Проверить:
интерфейс
source IP
gateway
TCP/2049
timeout 3 bash -c '</dev/tcp/<SERVER_FQDN>/2049'
echo $?
При наличии nc:
nc -vz -w 3 <SERVER_FQDN> 2049
Firewall клиента
nft list ruleset
Если используется iptables:
iptables -S
iptables -L -n -v
Не очищать firewall ради теста.
Firewall сервера
Проверить входящий TCP/2049:
nft list ruleset
Интерфейсные ошибки
ip -s link show <INTERFACE>
ethtool -S <INTERFACE> | grep -Ei \
'error|drop|crc|timeout|reset|miss'
MTU
ip link show <INTERFACE>
Для IPv4 MTU 1500:
ping -M do -s 1472 <SERVER_IP>
Мелкие операции могут работать, а крупные чтения зависать из-за MTU/VPN-проблем.
Уровень 2. Версия NFSv4
На клиенте проверить активный mount:
nfsstat -m
Ожидается:
vers=4.2
или:
vers=4.1
На сервере:
cat /proc/fs/nfsd/versions
Пример:
-3 +4 +4.0 +4.1 +4.2
Если 4.2 недоступна:
-4.2
проверить 4.1:
mount -t nfs \
-o nfsvers=4.1,proto=tcp,hard \
<SERVER_FQDN>:/<EXPORT_PATH> \
<MOUNTPOINT>
Не проверять NFSv3 как fallback.
Проверка конфигурации сервера
grep -nA20 '^\[nfsd\]' /etc/nfs.conf
При наличии:
nfsconf --get nfsd vers3
nfsconf --get nfsd vers4
nfsconf --get nfsd vers4.1
nfsconf --get nfsd vers4.2
После изменения:
systemctl restart nfs
В рабочей среде перезапуск согласовать.
Уровень 3. Сервер и exports
Служба
systemctl status nfs --no-pager
Порт
ss -lntp | grep ':2049'
Активные exports
exportfs -v
Конфигурация
grep -vE '^[[:space:]]*(#|$)' /etc/exports
Перечитать exports
exportfs -rav
Проверить псевдокорень
Должен существовать один export:
fsid=0
Пример:
/srv/nfs4 10.20.30.0/24(ro,fsid=0,sync,no_subtree_check,root_squash,sec=sys)
Рабочая ветка:
/srv/nfs4/projects 10.20.30.0/24(rw,sync,no_subtree_check,root_squash,sec=sys)
Клиент монтирует:
server:/projects
а не:
server:/srv/nfs4/projects
если /srv/nfs4 определён как fsid=0.
Bind mount
Проверить:
findmnt /srv/nfs4/projects
Если export указывает на пустой каталог, а реальные данные должны быть bind-mounted, клиент увидит пустоту. Протокол исправен, человек забыл один уровень пирога.
Журнал
journalctl -b -u nfs --no-pager
journalctl -k -b --no-pager | grep -Ei 'nfsd|nfs'
Уровень 4. Клиентский mount
Точка
ls -ld <MOUNTPOINT>
findmnt --target <MOUNTPOINT>
Ручной mount
mount -v -t nfs \
-o nfsvers=4.2,proto=tcp,hard \
<SERVER_FQDN>:/<EXPORT_PATH> \
<MOUNTPOINT>
После ошибки
journalctl -k -b -n 100 --no-pager
Параметры
nfsstat -m
Статистика mount
mountstats <MOUNTPOINT>
nfsiostat 1 5 <MOUNTPOINT>
Проверить fstab
grep -nE '[[:space:]]nfs[[:space:]]' /etc/fstab
Проверить systemd unit
systemctl list-units --type=automount --type=mount | grep -F '<UNIT_PREFIX>'
journalctl -b -u <UNIT.mount> -u <UNIT.automount> --no-pager
Уровень 5. Права и ID mapping
Клиент:
id <USER>
Сервер:
id <USER>
Сравнить UID/GID.
Проверить серверный путь:
namei -l <SERVER_PATH>
getfacl -p <SERVER_PATH>
Проверить export:
exportfs -v
Проверить idmap domain:
nfsidmap -d
на клиенте и сервере.
Проверить пользователя:
getent passwd <UID>
getent group <GID>
Очистить кеш после исправления:
nfsidmap -c
Симптомы:
Permission denied
nobody
nogroup
root не пишет
могут быть штатным результатом прав и root_squash, а не неисправностью NFS.
Уровень 6. Состояние NFSv4 и locks
NFSv4 является stateful-протоколом. Сервер хранит сведения о клиентах, open state и locks.
Активные клиенты сервера
Проверить:
command -v nfsdclnts
Если доступно:
nfsdclnts
Альтернативно:
cat /proc/fs/nfsd/clients/*/info 2>/dev/null
Client identifier
На клиенте:
cat /sys/module/nfs/parameters/nfs4_unique_id 2>/dev/null
Проверить hostname:
hostnamectl
Клонированные машины с одинаковой NFSv4 identity могут конфликтовать при state recovery.
Grace period
После рестарта сервера NFSv4 входит в grace period, во время которого клиенты восстанавливают state/locks.
Проверить журнал:
journalctl -b -u nfs --no-pager | grep -Ei \
'grace|reclaim|client|state'
Не перезапускать сервер повторно во время recovery без необходимости.
Locks
Проверить процессы:
lslocks
Проверить приложение на обоих клиентах. В NFSv4 locking встроен в протокол; параметры nolock и отдельный NLM к NFSv4 не относятся.
Уровень 7. Backend storage сервера
Проверить заполнение:
df -hT <SERVER_PATH>
Проверить inode:
df -ih <SERVER_PATH>
Проверить read-only:
findmnt -no OPTIONS <SERVER_PATH>
Проверить дисковую нагрузку:
iostat -xz 1
Проверить ошибки:
journalctl -k -b --no-pager | grep -Ei \
'I/O error|Buffer I/O|read-only|EXT4-fs error|XFS.*error|BTRFS.*error|reset|timeout'
Проверить RAID/LVM/Multipath по архитектуре сервера.
NFS-клиент может сообщать:
server not responding
I/O error
когда сеть исправна, но серверная ФС или СХД зависла.
NFS server not responding
На клиенте
journalctl -k -b --no-pager | grep -Ei \
'NFS: server|not responding|timed out'
Проверить TCP:
timeout 3 bash -c '</dev/tcp/<SERVER>/2049'
Проверить route:
ip route get <SERVER_IP>
Проверить retransmissions:
ss -tin dst <SERVER_IP>:2049
nstat -az | grep -E 'TcpRetransSegs|TcpExtTCPLostRetransmit'
На сервере
systemctl status nfs --no-pager
ss -lntp | grep ':2049'
top
iostat -xz 1
journalctl -k -b -n 200 --no-pager
Не менять hard на soft
soft может заставить приложение получить ошибку вместо ожидания и не лечит причину недоступности сервера.
Stale file handle
Причины:
- файл или каталог удалён и создан заново;
- export перенесён;
- серверная ФС пересоздана;
- изменился filesystem identity;
- bind mount заменён;
- клиент сохранил старый file handle;
- failover выдал другой backend без согласованной identity.
Проверка
Клиент:
journalctl -k -b --no-pager | grep -i 'stale'
findmnt <MOUNTPOINT>
Сервер:
findmnt <SERVER_PATH>
stat <SERVER_PATH>
Исправление
Остановить приложение:
fuser -vm <MOUNTPOINT>
Отключить:
umount <MOUNTPOINT>
Подключить заново:
mount <MOUNTPOINT>
Если ошибка возвращается, проверять backend identity и export path.
Не удалять рабочий серверный каталог и не создавать его заново ради сброса stale handle.
Процессы в состоянии D
Показать:
ps -eo pid,ppid,state,wchan:32,cmd | \
grep -E '^[[:space:]]*[0-9]+[[:space:]]+[0-9]+[[:space:]]+D'
Проверить конкретный PID:
cat /proc/<PID>/stack
ls -l /proc/<PID>/fd
Если процесс ждёт NFS I/O, kill -9 не гарантирует немедленное завершение. Он завершится только после возврата из непрерываемого ожидания.
Действия:
- восстановить доступность сервера;
- проверить backend storage;
- остановить приложение штатно;
- отключить mount после освобождения;
- аварийно использовать
umount -l, если ресурс больше не будет возвращён.
Долгая загрузка или выключение
Проверить fstab:
grep -nE '[[:space:]]nfs[[:space:]]' /etc/fstab
Рекомендуемые параметры:
_netdev
nofail
x-systemd.automount
x-systemd.mount-timeout=30s
x-systemd.idle-timeout=300
Показать critical chain:
systemd-analyze critical-chain
Проверить units:
systemctl list-units --type=automount --type=mount | grep -i nfs
Журнал:
journalctl -b -u <UNIT.mount> -u <UNIT.automount> --no-pager
Не использовать soft как средство ускорения загрузки. Для этого существует automount и timeout первоначального подключения.
Kerberos-ошибки
Проверить mount:
nfsstat -m
Проверить ticket:
klist -ef
Проверить время:
timedatectl
Проверить DNS:
getent hosts <SERVER_FQDN>
Проверить gssd:
systemctl list-units --all | grep -E 'gssd|nfs'
journalctl -b --no-pager | grep -Ei \
'gssd|gss|kerberos|nfs'
Проверить keytab сервера:
klist -k /etc/krb5.keytab
Ожидается principal:
nfs/<SERVER_FQDN>@<REALM>
Проверить export:
exportfs -v
sec=krb5p на клиенте должен быть разрешён сервером.
Таблица ошибок
| Сообщение | Основные причины |
|---|---|
Protocol not supported |
Клиент/сервер не поддерживает запрошенную minor version |
Connection refused |
nfs не запущен, TCP/2049 закрыт |
Connection timed out |
Сеть/firewall/server hang |
access denied by server |
IP клиента, sec=, export path |
No such file or directory |
Неверный путь относительно fsid=0 |
Permission denied |
Mode/ACL/UID/GID/root_squash/Kerberos |
Stale file handle |
Backend/export identity изменён |
NFS server not responding |
Сеть, nfsd, CPU, storage |
NFS server OK |
Связь восстановилась после timeout |
nobody/nogroup |
ID mapping/NSS |
Required key not available |
Kerberos ticket/gssd/keytab |
Operation not permitted |
ACL, root_squash, unsupported operation |
Resource busy |
Открытые файлы или cwd |
Mount работает, showmount пуст |
Для NFSv4 это возможно и нормально |
Сбор диагностического пакета
Клиент
mkdir -p /root/nfsv4-diag-client
cat /etc/os-release \
> /root/nfsv4-diag-client/os-release.txt
uname -a \
> /root/nfsv4-diag-client/uname.txt
mount.nfs -V \
> /root/nfsv4-diag-client/mount-nfs-version.txt 2>&1
nfsstat -m \
> /root/nfsv4-diag-client/nfsstat-m.txt
mountstats \
> /root/nfsv4-diag-client/mountstats.txt
findmnt -rn -t nfs,nfs4 -o TARGET,SOURCE,OPTIONS \
> /root/nfsv4-diag-client/findmnt.txt
journalctl -k -b --no-pager \
> /root/nfsv4-diag-client/kernel.txt
ip addr > /root/nfsv4-diag-client/ip-addr.txt
ip route > /root/nfsv4-diag-client/ip-route.txt
ss -tin > /root/nfsv4-diag-client/ss-tcp.txt
Сервер
mkdir -p /root/nfsv4-diag-server
exportfs -v \
> /root/nfsv4-diag-server/exportfs.txt
cat /proc/fs/nfsd/versions \
> /root/nfsv4-diag-server/versions.txt
journalctl -b -u nfs --no-pager \
> /root/nfsv4-diag-server/nfs-service.txt
journalctl -k -b --no-pager \
> /root/nfsv4-diag-server/kernel.txt
df -hT > /root/nfsv4-diag-server/df-hT.txt
df -ih > /root/nfsv4-diag-server/df-ih.txt
Архив:
tar -C /root -czf \
/root/nfsv4-diag-client.tar.gz \
nfsv4-diag-client
Не включать keytab и Kerberos credentials в диагностический архив.
Расширенная отладка
Использовать только на время воспроизведения.
Client RPC/NFS debug
Проверить:
command -v rpcdebug
Включить минимально необходимое:
rpcdebug -m nfs -s all
Воспроизвести одну ошибку.
Выключить:
rpcdebug -m nfs -c all
Для RPC:
rpcdebug -m rpc -s all
После теста:
rpcdebug -m rpc -c all
Проверить журнал:
journalctl -k -b -n 500 --no-pager
Отладка создаёт много сообщений. Не оставлять включённой.
Packet capture
tcpdump -i <INTERFACE> \
-s 0 \
-w /root/nfsv4-2049.pcap \
host <SERVER_IP> and tcp port 2049
PCAP может раскрывать имена, операции и при sec=sys содержимое NFS-трафика. Передавать только доверенным специалистам.
Что не делать
- Не проверять NFSv4 только через
showmount. - Не включать NFSv3 ради диагностики.
- Не менять
hardнаsoftдля сокрытия зависаний. - Не перезапускать сервер до сбора state и журналов.
- Не очищать firewall целиком.
- Не удалять и не создавать заново export path при stale handle.
- Не применять
kill -9как лечение процессовD. - Не включать весь
rpcdebugнавсегда. - Не копировать keytab в диагностический архив.
- Не считать доступный TCP/2049 доказательством исправного backend storage.