Вопрос или проблема
Извините за длинный текст ниже. Надеюсь, это даст достаточный контекст и следы, чтобы кто-то мог мне помочь.
Контекст
Я храню домашние директории пользователей на наборе данных zfs (по одному на пользователя), где у каждого пользователя есть одна разная домашняя директория для каждой дистрибутивы и версии Linux (например, Debian Buster), но где каталоги XDG (например, Загрузки или Рабочий стол) всех этих домашних директорий фактически указывают на одну и ту же директорию, чтобы пользователь имел доступ ко всем своим файлам, независимо от дистрибутива Linux, запущенного в терминале, в который вошел пользователь. У меня такая же структура для двоичных файлов, хранящихся в домашней папке. Посмотрите пример ниже (см. ниже значение чисел в квадратных скобках):
/media/zfs/home/user1/XDG-DIRS/[1]Загрузки
| /[2]Видео
| /<еще несколько директорий и файлов>
|
/homes/[3]debian_buster/<некоторые файлы(1)>
| /[4]ubuntu_groovy/<некоторые файлы(2)>
|
/[5]usr/share/<некоторые файлы(3)>
| /include/<некоторые файлы(4)>
|
/local/linux-x86_64/[6]bin
| /[7]lib
|
/linux-armhf/[8]bin
/[9]lib
Используя конкретные монтирования для корректных точек в структуре выше, можно восстановить домашнюю директорию со всеми файлами настроек пользователя, соответствующими рабочей среде, предоставляемой дистрибутивом и его версией, но все же получить доступ ко всем личным файлам и даже домашним двоичным файлам, совместимым с ОС и архитектурой, на которую вошел пользователь. Например, пользователь, вошедший в систему на Linux Debian Buster, работающий на архитектуре x86_64, должен иметь такую структуру домашней директории. Число в квадратных скобках в конце названий директорий означает, что содержание этой директории должно фактически соответствовать содержимому директории с тем же номером в начале ее имени в структуре выше. Я дам вам угадать, как выглядит домашняя директория пользователя, вошедшего в систему на raspberry pi, работающий на ubuntu groovy.
/home/AD.EXAMPLE.COM/user1[3]/Загрузки[1]
/Видео[2]
/.local[5]/bin[6]
/lib[7]
Это можно осуществить, запустив autofs на терминальном компьютере и используя исполняемый файл карты, который приводит к такому количеству nfs монтирований, сколько необходимо (5 на пользователя в приведенном выше примере, обычно больше из-за большего количества XDG директорий). Проблема, которую я предполагаю с этим, заключается в том, что если пользователь хочет переместить файл из “Загрузок” в “Видео”, то, поскольку это две разные точки монтирования nfs, файл фактически загружается на терминал, а затем загружается обратно на сервер. Я на самом деле не тестировал, приводит ли это к снижению производительности. Если у вас есть какие-либо соображения по этому поводу, пожалуйста, дайте мне знать.
Чтобы ограничить описанную выше проблему с производительностью, я фактически восстанавливаю домашние директории для каждого дистрибутива/версии (с одной стороны) и для каждой ОС/архитектуры (с другой стороны) на сервере, используя autofs, а затем экспортирую результаты через NFS. Это означает, что я строю следующую структуру на сервере, используя привязанные монтирования autofs
/media/user_data/unix/user1/home/[10]debian_buster/Загрузки[1]
| | /Видео[2]
| | /.local/<пусто>
| /ubuntu_groovy/Загрузки[1]
| /Видео[2]
| /.local/<пусто>
/[11]local/linux-x86_64[5]/bin[6]
| /lib[7]
/local/linux-armhf[5]/bin[8]
/lib[9]
/etc/auto.master.d/user_data.autofs
(сторона сервера)
/media/user_data/unix/ /etc/auto.AD.EXAMPLE.COM.unix --ghost --timeout=120
/etc/auto.AD.EXAMPLE.COM.unix
(сторона сервера, исполняемые и читаемые биты установлены для ugo)
#!/bin/bash
key=$1
echo '- /home -fstype=bind :/media/zfs/home/'$key'/unix/ browse \'
for i in $(ls /media/zfs/home/$key/unix)
do
for j in $(ls /media/zfs/home/$key/XDG_DIRS)
do
echo ' /home/'$i"https://unix.stackexchange.com/"$j' -fstype=bind :/media/zfs/home/'$key'/XDG_DIRS/'$j' browse \'
done
done
for i in $(ls /media/zfs/home/$key/usr)
do
echo ' /local/'$i' -fstype=bind :/media/zfs/home/'$key'/local/ browse \'
for j in $(ls /media/zfs/home/$key/usr/$i)
do
echo ' /local/'$i"https://unix.stackexchange.com/"$j' -fstype=bind :/media/zfs/home/'$key'/usr/'$i"https://unix.stackexchange.com/"$j' browse \'
done
done
echo ''
Вот образец вывода вышеуказанного скрипта
root@server:~# /etc/auto.AD.EXAMPLE.COM.unix user1
- /home -fstype=bind :/media/zfs/home/user1/unix/ browse \
/home/debian_buster/Загрузки -fstype=bind :/media/zfs/home/user1/XDG_DIRS/Загрузки browse \
/home/debian_buster/Видео -fstype=bind :/media/zfs/home/user1/XDG_DIRS/Видео browse \
/local/linux-armhf -fstype=bind :/media/zfs/home/user1/local/ browse \
/local/linux-armhf/bin -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/bin browse \
/local/linux-armhf/lib -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/lib browse \
/local/linux-armhf/sbin -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/sbin browse \
/local/linux-x86_64 -fstype=bind :/media/zfs/home/user1/local/ browse \
/local/linux-x86_64/bin -fstype=bind :/media/zfs/home/user1/usr/linux-x86_64/bin browse \
/local/linux-x86_64/lib -fstype=bind :/media/zfs/home/user1/usr/linux-x86_64/lib browse \
root@server:~#
Это работает безупречно, хотя немного медленно на мой вкус. Я экспортирую /media/user_data/unix
через NFS, используя файл экспорта ниже:
# <другие экспорты не связанных директорий>
/media/user_data *(sec=krb5p,rw,crossmnt)
# <другие экспорты не связанных директорий>
На данный момент стоит упомянуть, что одной из причин, почему шаг “user_data” существует в этой файловой иерархии, является то, что если я экспортирую /media/user_data/unix
в /etc/exportfs
(или эквивалентно, /media/unix
, хотя это не продемонстрировано ниже), то я получаю предупреждения ниже. Это не обнадеживает, но я все же пробую с этим дополнительным слоем user data
в иерархии, надеясь, что crossmnt
также сможет экспортировать то, что смонтировано внутри экспортируемой иерархии. Система, похоже, не возражает против этой попытки.
root@server:~# cat /etc/exports
# Другие экспорты не связанных директорий
/media/user_data *(sec=krb5p,rw,crossmnt)
/media/user_data/unix *(sec=krb5p,rw,crossmnt)
# Больше не связанных экспортов
root@server:~# exportfs -ra; zfs share -a
exportfs: /etc/exports [5]: Никакие 'subtree_check' или 'no_subtree_check' не указаны для экспорта "*:/media/user_data".
Предполагаю поведение по умолчанию ('no_subtree_check').
ПРИМЕЧАНИЕ: это значение по умолчанию изменилось с версии nfs-utils 1.0.x
exportfs: /media/user_data/unix не поддерживает экспорт NFS
root@server:~# showmount -e
Список экспортов для сервера:
/media/user_data *
/media/user_data/unix *
# <nfs экспортов не относящихся к zfs наборам данных>
root@server:~#
В следующем тексте я удалил экспорт /media/user_data/unix
в /etc/exports
и запустил exportfs -ra
и zfs share -a
, чтобы сервер NFS не жаловался на любую директорию, которая не поддерживает экспорт NFS. Наконец, autofs на терминальном компьютере должен только смонтировать домашнюю директорию, соответствующую дистрибутиву, который он запускает, и его версии, а также подкаталог local
, соответствующий ОС и архитектуре, что приводит к следующей иерархии для user1 на Linux Debian Buster x86_64.
/home/AD.EXAMPLE.COM/user1[10]/Загрузки
/Видео
/.local[11]
Которую я пытаюсь достичь с помощью конфигурации autofs ниже
/etc/auto.master.d/home.autofs
(сторона терминала, Linux Debian Buster, x86_64)
/media/AD.EXAMPLE.COM /etc/auto.AD.EXAMPLE.COM.home --timeout=120
/etc/auto.AD.EXAMPLE.COM.home
(сторона терминала, Linux Debian Buster, x86_64, исполняемые и читаемые биты установлены для ugo)
#!/bin/bash
key=$1
distributor()
{
lsb_release -i | cut -f 2 -d : | xargs echo | tr '[:upper:]' '[:lower:]'
}
codename()
{
lsb_release -c | cut -f 2 -d : | xargs echo | tr '[:upper:]' '[:lower:]'
}
architecture()
{
uname -m | tr '[:upper:]' '[:lower:]'
}
os()
{
uname -s | tr '[:upper:]' '[:lower:]'
}
echo '- / -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/'$key'/home/'$(distributor)'_'$(codename)' \'
echo ' /.local -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/local/'$key'/local/'$(os)'-'$(architecture)' \'
echo ''
Вот образец вывода скрипта выше
root@terminal:~$ /etc/auto.AD.EXAMPLE.COM.exp user1
- / -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/user1/home/debian_buster \
/.local -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/local/user1/local/linux-x86_64 \
root@terminal:~$
Проблема
Autofs на терминальном компьютере не удается смонтировать восстановленную домашнюю директорию, экспортированную с сервера. Это след, который я получаю от automount, когда пытаюсь перечислить содержимое /home/AD.EXAMPLE.COM/user1
:
root@terminal:~# automount -d -f -v
... <много вывода>
get_nfs_info: вызвано с хостом server.example.com(192.168.80.101) proto 17 version 0x30
get_nfs_info: nfs v3 rpc ping time: 0.000000
get_nfs_info: хост server.example.com стоит 0 вес 0
prune_host_list: выбран подмножество хостов, которые поддерживают NFS3 по TCP
mount_mount: mount(nfs): вызов mkdir_path /media/AD.EXAMPLE.COM/user1
mount_mount: mount(nfs): вызов mount -t nfs -s -o vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/user1/home/debian_buster /media/AD.EXAMPLE.COM/user1
>> mount.nfs: монтирование server.example.com:/media/user_data/unix/user1/home/debian_buster не удалось, причина, указанная сервером: Нет такого файла или директории
mount(nfs): nfs: сбой монтирования server.example.com:/media/user_data/unix/user1/home/debian_buster на /media/AD.EXAMPLE.COM/user1
do_mount_autofs_offset: смонтировать смещение /media/AD.EXAMPLE.COM/user1/.local на /media/AD.EXAMPLE.COM/user1
mount_autofs_offset: вызов mount -t autofs -s -o fd=16,pgrp=20379,minproto=5,maxproto=5,offset automount /media/AD.EXAMPLE.COM/user1/.local
смонтированное смещение на /media/AD.EXAMPLE.COM/user1/.local с таймаутом 120, частота 30 секунд
mount_autofs_offset: смонтирован триггер /media/AD.EXAMPLE.COM/user1/.local на /media/AD.EXAMPLE.COM/user1/.local
dev_ioctl_send_ready: токен = 114
смонтирован /media/AD.EXAMPLE.COM/user1
И перечисленное содержимое /home/AD.EXAMPLE.COM/user1
пустое:
root@terminal:~$ ls /home/AD.EXAMPLE.COM/user1
root@terminal:~$
Хотя предполагаемая смонтированная директория с сервера полна файлов:
root@server:~# ls /media/user_data/unix/user1/home/debian_buster
файл1 файл2 файл3
root@server:~#
Вывод automount выше намекает, что директория, которую пытались смонтировать, не существует на сервере, но это странно, прежде всего потому, что попытка перечислить ту самую директорию с сервера показывает, что она существует (см. выше), и я могу смонтировать эту директорию вручную с терминала, как показывает следующий вывод:
root@terminal:~$ mount -vvvv -t nfs server.example.com:/media/user_data/unix/user1/home/debian_buster /mnt
mount.nfs: тайм-аут установлен на субботу 13 февраля 22:37:06 2021
mount.nfs: пытается текстовые параметры 'vers=4.2,addr=192.168.80.101,clientaddr=192.168.104.1'
mount.nfs: mount(2): Нет такого файла или директории
mount.nfs: пытается текстовые параметры 'addr=192.168.80.101'
mount.nfs: прог 100003, пытается версию 3, протокол 6
mount.nfs: пытается 192.168.80.101 прог 100003 версия 3 протокол TCP порт 2049
mount.nfs: прог 100005, пытается версию 3, протокол 17
mount.nfs: пытается 192.168.80.101 прог 100005 версия 3 протокол UDP порт 39874
root@terminal:~$ ls /mnt
файл1 файл2 файл3
root@terminal:~$
Моя попытка решения
Я думал, что autofs на терминале может не найти директорию для монтирования, потому что она еще не смонтирована на сервере, поэтому я попытался использовать --ghost
и browser
параметры (вы можете увидеть их в файлах сервера /etc/auto.master.d/media.autofs
и /etc/auto.AD.EXAMPLE.COM.unix
, показанных выше), но безрезультатно. У меня заканчиваются идеи для исследования, чтобы найти постоянное решение.
Временное решение
Временное решение, которое я использую в данный момент, – это не использовать autofs на стороне сервера, а вместо этого вручную привязать все директории, чтобы получить правильную файловую иерархию для экспорта. Я не слишком доволен этим решением, так как оно требует, чтобы много монтирований было постоянно активны, и, похоже, оставляет сервер в каком-то нестабильном состоянии, хотя я не знаю, почему именно.
Замечания
- Как сервер, так и терминал работают на Debian Buster (Linux x86_64) в моих тестах, и это создало приведенные выше следы.
- NFS жалуется на то, что восстановленная директория autofs не поддерживает экспорт NFS, намекает, что я не должен пытаться экспортировать ее вовсе, преследуя родительскую директорию вместо этого. Я не смог найти никаких ссылок на то, что невозможно экспортировать NFS директорию, имеющую подкаталог, смонтированный с помощью autofs, поэтому это все еще стоит попробовать. Более того, это хорошо работает, когда я
mount --bind
эти подкаталоги вручную на стороне сервера вместо использования autofs, так что должна быть надежда. - Это довольно сложная (и хрупкая?) настройка; если у вас есть более простое (и более надежное) предложение, чтобы достичь тех же функций, я также заинтересован 🙂
Кажется, ваш клиент сначала по умолчанию пытается использовать NFSv4. Когда монтируется вручную, он переходит на NFSv3. Autofs, вероятно, сдается при первой неудаче.
Возможно, вам удастся настроить поведение клиента по умолчанию для использования NFSv3 в первую очередь.
Ответ или решение
Анализ проблемы с автоматическим монтированием NFS-директорий через Autofs
Контекст проблемы:
Вы настроили структуру каталогов на сервере, используя NFS и Autofs, чтобы обеспечить доступ к домашним директориям пользователей, исходя из их дистрибутивов и архитектур. Несмотря на то что вы успешно можете вручную монтировать каталоги NFS на клиентской машине, автоматическое монтирование через Autofs завершается неудачей, несмотря на выполнение всех необходимых условий.
Проблема
Автоматическое монтирование через Autofs некорректно взаимодействует с NFS и приводит к ошибке, утверждающей, что целевой каталог не существует. Тем не менее, вы можете успешно проверить наличие этого каталога через команду ls
на сервере и вручную монтировать каталог, используя те же параметры.
Возможные причины и решения
-
Версии NFS:
- Из журналов видно, что Autofs, вероятно, пытается использовать NFSv4 по умолчанию, в то время как при ручном монтировании происходит переход на NFSv3. Это может быть причиной неудач при попытке монтирования, так как Autofs может завершать свою работу при первой ошибке.
- Решение: Определите версию NFS, используемую Autofs, и попробуйте вручную установить более низкую версию в конфигурации. Например, в вашем
/etc/auto.AD.EXAMPLE.COM.home
добавьте параметрvers=3
в строках с монтированием:echo '- / -fstype=nfs,vers=3,sec=krb5p,fsc server.example.com:/media/user_data/unix/'$key'/home/'$(distributor)' \'
-
Ошибки в конфигурации Autofs:
- Убедитесь, что скрипт, генерирующий ваши мапы, работает корректно и создает правильные пути к каталогам. Убедитесь, что переменные
key
,distributor
, и т.д. правильно заполняются в конфигурации. - Решение: Проверьте консистентность выводимых данных. Временно добавьте отладочные команды
echo
, чтобы отследить фактические пути и параметры монтирования.
- Убедитесь, что скрипт, генерирующий ваши мапы, работает корректно и создает правильные пути к каталогам. Убедитесь, что переменные
-
Проблемы с правами доступа:
- Неправильные права доступа каталогов на сервере могут препятствовать корректному монтированию.
- Решение: Проверьте права доступа к каталогам, убедитесь, что пользователю, под которым работает клиент, назначены достаточные разрешения на чтение и выполнение.
-
Конфликты с mtab и fstab:
- Убедитесь, что монтирование, происходящее через Autofs, не конфликтует с уже существующими записями в
/etc/mtab
или/etc/fstab
. Это может приводить к путанице при попытке доступа к монтируемым точкам. - Решение: Отключите или закомментируйте все потенциальные конфликты в этих файлах при тестировании Autofs.
- Убедитесь, что монтирование, происходящее через Autofs, не конфликтует с уже существующими записями в
-
Отладка с помощью журналов Autofs:
- Активируйте детализированный уровень журналирования для Autofs, чтобы получить больше информации о том, проходит ли запрос на монтирование успешно и на каком этапе происходит сбой.
- Решение: Используйте команды
systemctl status autofs
иjournalctl -xe
для анализа журналов на предмет ошибок.
Временное решение
Если предложенные пути не помогают, временным решением может стать ручное монтирование по мере необходимости. Однако это не является идеальным вариантом, учитывая вашу цель автоматизировать процесс.
Заключение
Эта конфигурация действительно сложна, и возможные проблемы требуют внимательной проверки всех аспектов настройки. Настоятельно рекомендую провести тестирование с разными версиями NFS и убедиться, что скрипты корректно генерируют пути для монтирования. Если проблема останется неразрешенной, возможно, стоит пересмотреть подход к структуре общей директории, чтобы повысить надежность системы.