Дата и время публикации:
Проблемы и решение
1. Суть проблемы
Использование NFS-соединений позволяет разрешить доступ гостевой ВМ, запущенной на эмуляторе Qemu на гипервизоре KVM, к директориям на хозяйской и/или иной системе.
В случае, если речь идет об локальном использовании гостевой ВМ, то таким образом можно сократить размер создаваемого образа и сэкономить денюжку на покупку носителей информации, если речь идет о расширении мест хранения избыточной информации. А также увеличить быстродействие за счет оптимизации стека TCP/IP.
2. Решение
2.1 Настройка серверной стороны
Конечно, в создании NFS-соединения участвует клиентская сторона и серверная на самой хозяйской системе, о настройке которой пойдет здесь речь.
Прежде всего, на серверной стороне устанавливаем нужные пакеты программного обеспечения, как показано в дампе 2.1.1
Дамп 2.1.1
apt-get install nfs-kernel-server nfs-common
В файле /etc/default/nfs-kernel-server запрещаем использование nfs версии 4, как показано в дампе 2.1.2 и выделено жирным.
Дамп 2.1.2
root@home:~# nano /etc/default/nfs-kernel-server # Number of servers to start up #RPCNFSDCOUNT=8 RPCNFSDCOUNT="8 --no-nfs-version 4" ...
Запрет поддержки 4-й версии целесообразно включать, если Вам придется на гостевой ВМ разворачивать старую версию дистрибутива Linux, например Debian-9
Редактируем в файл /etc/exports, как показано в дампе 2.1.3
Дамп 2.1.3
# nano /etc/exports ... /path/to/source 10.0.2.0/24(rw,insecure,no_root_squash,no_subtree_check) ...
В нем указываем, что всем клиентам внутренней сети эмулятора Qemu c IP-адресом 10.0.2.0/24 позволено монтировать у себя директорию /path/to/source по чтению и записи (rw), без создания резервного порта (insecure), в режиме подавления доступа (no_root_squash) и проверки вложенных деревьев файловой системы, что приводит к незначительным последствиям для безопасности, но повышает надежность в некоторых случаях.
Кстати, отсутствие опции insecure на Debian-9 приводило к отказу удаленного монтирования на гостевой ВМ с печатью сообщения "mount.nfs: access denied by server while mounting 10.0.2.2/path/to/source # This is fatal.". При этом экспорт на серверной стороне проходил без каких-либо сообщений об ошибок в сделанной записи в файл /etc/exports, как показано в дампе 2.1.4
Дамп 2.1.4
root@home:~# exportfs -rav
На завершающем этапе настройки, на серверной стороне перезапускаем сервис nfs-kernel-server, как показано в дампе 2.1.5
Дамп 2.1.5
# service nfs-kernel-server restart
Запрашиваем статус запуска сервиса nfs-kernel-server, как показано в дампе 2.1.6
Дамп 2.1.6
service nfs-kernel-server status Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2018-02-19 13:32:23 MSK; 1min 41s ago . . . фев 20 11:09:18 home systemd[1]: Starting NFS server and services... фев 20 11:09:18 home systemd[1]: Started NFS server and services.
2.2 На клиентской стороне
В директории пользователя создаем точку монтирования /path/to/target куда будем монтировать открытую для экспорта директорию /path/to/source на серверной стороне.
Затем, пробуем смонтироваться, как показано в дампе 2.2.1
Дамп 2.2.1
# mount -t nfs -o vers=3,hard,intr,nolock,port=2049,tcp 192.168.1.1:/path/to/source /path/to/target
После нормального завершения делаем запись в файле /etc/fstab, как показано в дампе 2.2.2, для использования точки монтирования без титанического ввода каждый раз, как это делали в дампе 2.2.1
Дамп 2.2.2 фрагмент файла /etc/fstab
# # <file system> <mount point> <type> <options> <dump> <pass> # ... 10.0.2.2:/path/to/source /path/to/target vers=3,hard,intr,nolock,port=2049,tcp,user,noauto,async 0 0 ...
Соответственно указываем адрес IP шлюза эмулятора Qemu, далее используем точку монтирования /path/to/target , как показано в дампе 2.2.3
Дамп 2.2.4
$ mount path/to/target
2.3 Оптимизация соединения NFS
2.3.1 Оптимизация сети
На обоих сторонах клиента и сервера NFS необходимо увеличить размер выделяемой памяти под очереди ввода/вывода сокетов tcp/ip, чтобы позволить передавать клиентам и серверу больше данных через соединение NFS чем это позволено по умолчанию.
Для увеличения размера очередей ввода необходимо прописать значения rmem_default, rmem_max на очередях ввода, а для очередей вывода установить значения wmem_default и wmem_max. Ниже приводится скрипт, который производит данные изменения, как показано в дампе 2.3.1а
Дамп 2.3.1a
#!/bin/sh FRAMESIZE=31457280 echo $FRAMESIZE > /proc/sys/net/core/rmem_default echo $FRAMESIZE > /proc/sys/net/core/rmem_max echo $FRAMESIZE > /proc/sys/net/core/wmem_default echo $FRAMESIZE > /proc/sys/net/core/wmem_max
Но, лучше эти изменения реализовать через соответствующие опции в файле /etc/sysctl.conf , как показано в листинге 2.3.1б
Листинг 2.2.4 Фрагмент файла /etc/sysctl.conf
... ### TUNING NETWORK PERFORMANCE ### # Default Socket Receive Buffer net.core.rmem_default = 31457280 # Maximum Socket Receive Buffer net.core.rmem_max = 33554432 # Default Socket Send Buffer net.core.wmem_default = 31457280 # Maximum Socket Send Buffer net.core.wmem_max = 33554432 # Increase number of incoming connections net.core.somaxconn = 65535 # Increase number of incoming connections backlog net.core.netdev_max_backlog = 65536 # Increase the maximum amount of option memory buffers net.core.optmem_max = 25165824 # Increase the maximum total buffer-space allocatable # This is measured in units of pages (4096 bytes) net.ipv4.tcp_mem = 786432 1048576 26777216 net.ipv4.udp_mem = 65536 131072 262144 # Increase the read-buffer space allocatable net.ipv4.tcp_rmem = 8192 87380 33554432 net.ipv4.udp_rmem_min = 16384 # Increase the write-buffer-space allocatable net.ipv4.tcp_wmem = 8192 65536 33554432 net.ipv4.udp_wmem_min = 16384 # Increase the tcp-time-wait buckets pool size to prevent simple DOS attacks net.ipv4.tcp_max_tw_buckets = 1440000 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1
Кроме того, были установлены некоторые опции ядра, которые позволяют повысить значительно быстродействие стека TCP/IP за счет повышения количество исходящих соединений, выделяемой памяти под буферы на вводе и выводе, а также обезопасить себя от DOS-атак.
2.3.2 Установка асинхронного режима ввода/вывода носителя
По умолчанию на серверной стороне NFS доступ к носителю осуществляется в синхронном режиме, т.е. после каждой записи производится сброс очередей носителя информации, что весьма замедляет работу приложений на клиентской стороне.
Поэтому, чтобы избежать проблем со снижением производительности во многих статьях по этой проблеме предлагается в файле списка экспортных директорий установить async постоянно или временно через команду exportfs, как показано в дампе 2.3.2а
Дамп 2.3.2
/usr/sbin/exportfs -o rw,async *:/path/to/target
Или в самом файле экспорта, где прописаны экспортируемые директории через NFS, как показано в листинге 2.3.2б
Листинг 2.3.2б
# /etc/exports: the access control list for filesystems which may be exported # to NFS clients. See exports(5). # ... /path/to/target *(rw,async,insecure,no_root_squash,no_subtree_check)
3. Библиография
3.1 Linux NFS-HOWTO. 5.Optimizing NFS Performance
3.2 Sysctl configuration for high performance
3.3 HPC. Optimizing Your NFS Filesystem