× К оглавлению На главную Об авторе

   Дата и время публикации:

Проблемы и решение

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

3.4 [SOLVED] Access denied by the host

3.5 exports(5) - Linux man page