Вопрос или проблема
Это работало вчера, но после перезагрузки базового оборудования перестало работать.
Мой docker-compose.yml
;
version: '3.8'
services:
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=pia
- VPN_TYPE=openvpn
- OPENVPN_USER=user
- OPENVPN_PASSWORD=pass
- SERVER_REGIONS="Netherlands"
- TZ=Europe/London
restart: unless-stopped
При запуске с docker-compose up -d
, я получаю ошибку:
ERROR checking TUN device: TUN device is not available: open /dev/net/tun: no such device
.
Я пытался воссоздать устройство tun;
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun
но это не помогло.
Запуск нового контейнера для проверки доступа к устройству работает, как ожидалось:
docker run --rm --privileged alpine ls /dev/net/tun
>>> /dev/net/tun
Добавление флага privileged: true
в docker-compose.yml
также не помогло.
Я также пытался заново скачать образ gluetun, перезапустить Docker и перезагрузить само оборудование.
Оборудование — это Synology NAS с установленной DSM6 (DSM7 не поддерживается). Версия Docker 20.10.3
.
Если кто-то еще столкнется с этим, мне удалось исправить это следующим образом.
- Удалите ранее созданное устройство tun:
rm -rf /dev/net
- Загрузите устройство tun с помощью:
insmod /lib/modules/tun.ko
- Проверьте, что устройство туннеля отображается:
lsmod | grep tun
>>> tun 18856 2
- При перезагрузке модуль не загружается автоматически (по-видимому, в DSM7 это происходит автоматически, но не в DSM6), поэтому я сделал это постоянным при перезагрузках, добавив скрипт запуска в
/usr/local/etc/rc.d/
:
vi /usr/local/etc/rc.d/tun.sh
#!/bin/sh
case "$1" in
start)
insmod /lib/modules/tun.ko
;;
stop)
rmmod tun
;;
esac
exit 0
Затем сделайте скрипт исполняемым:
chmod +x /usr/local/etc/rc.d/tun.sh
Ответ или решение
В описанной ситуации, проблема с невозможностью найти TUN-устройство в docker-контейнере Gluetun после перезагрузки оборудования связана с особенностями конфигурации Synology NAS на базе DSM6. Рассмотрим подробно причины проблемы, шаги её решения и дальнейшие рекомендации для предотвращения подобных ситуаций в будущем.
Теория (Theory)
При использовании VPN внутри Docker-контейнера обычно требуется доступ к устройству туннелирования TUN, которое является виртуальным сетевым интерфейсом. Оно позволяет пакетам данных перемещаться между узлами через защищённое соединение. Docker предоставляет гибкие возможности управления устройствами, которые могут быть подключены к контейнерам, однако это может потребовать дополнительной настройки со стороны операционной системы хоста.
Основные шаги, необходимые для успешного создания и использования TUN-устройства в контейнере включают:
- Подключение устройства к контейнеру с помощью docker-compose.
- Корректное управление модулями ядра, которые отвечают за функциональность TUN-устройства.
Пример (Example)
В рассмотренном случае ошибка указывает на отсутствие устройства /dev/net/tun
, несмотря на то, что оно было явно указано в конфигурации docker-compose.yml
. Варианты устранения, такие как ручное создание устройства с помощью mknod
, не привели к успеху, так как основная проблема заключалась в том, что модуль ядра для TUN-устройства не был загружен. Это характерное поведение для DSM6, где ручная загрузка модулей в ядро не выполняется при старте системы, в отличие от более новых версий, таких как DSM7.
Применение (Application)
-
Удаление ранее созданного TUN-устройства:
Для начала необходимо удалить любые ранее созданные устройства, чтобы избежать конфликтов. Это выполняется командой:rm -rf /dev/net
-
Загрузка модуля ядра TUN:
Загрузка модуля ядра является ключевым шагом. Это делается с помощью команды:insmod /lib/modules/tun.ko
После успешной загрузки модуля необходимо проверить, что он действительно загружен:
lsmod | grep tun
-
Автоматизация загрузки модуля:
Поскольку DSM6 не поддерживает автоматическую повторную загрузку модуля после перезагрузки, создание скрипта для автоматической загрузки модуля при старте системы позволяет исключить необходимость ручных действий в будущем. Скрипт создается в директории/usr/local/etc/rc.d/
:-
Создание скрипта:
vi /usr/local/etc/rc.d/tun.sh
-
Содержание скрипта должно включать в себя команды для загрузки и выгрузки модуля:
#!/bin/sh case "$1" in start) insmod /lib/modules/tun.ko ;; stop) rmmod tun ;; esac exit 0
-
Сделать скрипт исполняемым:
chmod +x /usr/local/etc/rc.d/tun.sh
-
Заключение
Подводя итоги, важно помнить, что эффективная работа контейнеров Docker с устройствами уровня ядра может требовать дополнительной настройки конфигурации системы. В данном случае это включало манипуляции с модулями ядра для обеспечения работы TUN-устройства. Предпринимая шаги для автоматизации этих действий, вы можете значительно снизить количество ручных операций при последующих перезапусках системы, что сделает ваше решение более стабильным и надежным.
Также рекомендуется регулярно проверять обновления DSM и связанных пакетов, так как новые версии могут предложить улучшения в управлении сетью и поддержке контейнеров, упрощая решение подобных задач.