Назад | Перейти на главную страницу

Обработка устаревшего файла NFS после перезагрузки сервера NFS: почему это происходит и как с этим справляются промышленность?

Эта проблема сводила меня с ума.

У меня есть сервер NFS с общими ресурсами NFS, установленными на различных клиентах. Однако всякий раз, когда мне приходится перезагружать сервер NFS, я неизменно получаю кучу ошибок «Устаревший дескриптор файла» при монтировании на всех моих клиентах, что вынуждает меня вручную размонтировать и перемонтировать мои общие ресурсы NFS на клиентах.

Я проверил свой экспорт на моем сервере NFS с помощью cat /etc/exports и я передаю один и тот же fsid для каждого экспорта NFS при перезагрузке.

Мои вопросы:

  1. Как промышленность решает эту проблему? Мне сложно представить, чтобы системные администраторы вручную размонтировали / перемонтировали каждого клиента или просто перезапустили подключенных клиентов в массовом порядке. Или это действительно так? (Помимо стандарта: «У нас никогда не бывает простоев и нам никогда не нужно перезапускать серверы NFS».)
  2. Почему это происходит? Это потому, что, хотя fsid может быть таким же, сервер NFS пересчитывает дескрипторы файлов, которые могут быть разными при перезагрузках?
  3. Есть ли что-то, что мне нужно улучшить в моей конфигурации монтирования, чтобы предотвратить это?

/etc/fstab:

[NFSserver]:/mnt/backup /mnt/backup nfs bg,nfsvers=3,tcp 0 0

За эта почтабыло предложено добавить hard и intr варианты монтирования, но это, похоже, не имело никакого значения.

  1. Если ничего не помогает, следует ли мне просто вернуться к использованию сценария bash для отслеживания каталога mount / на предмет ошибки устаревшего файла и заставить его выполнить цикл umount / mount?

Заранее спасибо.

-Гаечный ключ

Вы используете NFS версии 3, для которой требуется несколько вспомогательных служб в дополнение к основной службе NFS в порту 2049. Одна из них - rpc.statd, который играет ключевую роль в обнаружении перезагрузок и восстановлении / снятии блокировок NFS после перезагрузки.

Эти вспомогательные службы могут располагаться в случайных портах, и они обнаруживаются при обращении к сопоставителю портов RPC (обычно к процессу с именем rpcbind на современных Linux). В современных сетях с брандмауэрами такое поведение может усложнить задачу: даже если вы можете найти их в портах с детерминированным внешним видом после перезагрузки, они могут быть выделены совсем другим номерам портов, если / когда вы перезапустите службы NFS.

К счастью, во многих современных Unix-подобных системах вы можете заблокировать номера портов диспетчера блокировок NFS (исторически rpc.lockd, в настоящее время обычно реализуется в ядре), rpc.statd и rpc.mountd. Это важно, если вы хотите передать NFSv3 через брандмауэры с какой-либо надежностью.

Для RHEL и связанных дистрибутивов вы можете заблокировать номера вспомогательных портов NFS, добавив эти строки в /etc/sysconfig/network:

LOCKD_TCPPORT=4045
LOCKD_UDPPORT=4045
STATD_PORT=4046
MOUNTD_PORT=4047

Для Debian и связанных дистрибутивов вы можете добавить эту строку в /etc/modprobe.d/nfs.conf:

options lockd nlm_udpport=4045 nlm_tcpport=4045

... и эта строка в /etc/default/nfs-common:

STATDOPTS="-p 4046"

... и эта строка в /etc/default/nfs-kernel-server:

RPCMOUNTDOPTS="-p 4047" # you may want to add a --manage-gids option here

(При желании вы можете использовать другие номера портов, но 4045 является портом по умолчанию для диспетчера блокировок NFSv3 в Solaris и жестко запрограммирован для него в HP-UX 11.31.)


Но в протоколе NFSv3 есть еще один подводный камень. Хотя вы можете успешно смонтировать общий ресурс NFS, используя только IP-адреса, протокол блокировки NFSv3 внутренне использует имена хостов. И клиент, и сервер должны знать друг друга по правильным именам, иначе блокировка файлов NFS и восстановление блокировки после перезагрузки не сработают. И "правильное имя" для каждой системы - это имя, сообщенное uname -n.

Так что если uname -n возвращается server.example на сервере и соответственно client.example на клиенте, то вы должны убедиться, что эти точные имена будут разрешаться в IP-адреса, которые хосты должны использовать для NFS. Другими словами, сервер должен иметь возможность связываться с клиентским rpc.statd используя имя client.example и наоборот.

Если вы этого не сделаете, сначала может показаться, что все работает хорошо ... но при любой из конечных перезагрузок вы можете получить эти Stale file handle ошибки.

В дополнение к отличному ответу от @telcoM я хотел бы предложить два других возможных решения:

  • смонтировать nfs с помощью noac вариант (помните, что это воля вызвать потерю производительности при выдаче ls в большом каталоге или stat на многих файлах)

  • используйте NFS v4.1 (v4.0 имеет некоторые ошибки, приводящие к «обработке устаревших файлов», поэтому обязательно выберите протокол v4.1).