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

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

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

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

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

Мои вопросы:

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

/etc/fstab:

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

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

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

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

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

решение1

Вы используете 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ошибки.

решение2

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

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

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

Связанный контент