OpenVPN в Docker не може да отвори /dev/net/tun: какво липсва
TUN възелът и мрежовото право са две отделни разрешения. Отворете и двете, след което прочетете следващата грешка при нейните собствени условия, вместо да повтаряте същата поправка.
Контейнерните образи могат да носят всеки нужен OpenVPN двоичен файл и конфигурационен файл и пак да се провалят при първото мрежово извикване. Грешката посочва /dev/net/tun, защото приложението е поискало от ядрото TUN интерфейс, а контейнерът не е имал нито възела на устройството, нито правото да създаде такъв. Това са две отделни разрешения и поправянето на едното оставя другото точно където си е било.
Разделянето им изисква по една команда за всяко. Съобщението за грешка след това ви казва на коя граница всъщност сте стояли.
Възелът на устройството и правото са две врати
Възелът на устройството е обект на файловата система, затова контейнерът трябва да го вижда в собственото си пространство от имена за монтиране. Правото е разрешение, затова процесът се нуждае от CAP_NET_ADMIN в пространството от имена, където ще бъде създаден интерфейсът. Предаването на устройството без правото ви дава възел, който се отваря, и ioctl, който се проваля. Даването на правото без устройството оставя приложението неспособно да отвори каквото и да е, поради което двете обикновено се появяват заедно в примерите.
Настройката devices на Docker съпоставя устройството на хоста в контейнера, докато cap_add коригира набора от права. Bind mount на същия път показва файла, без да прилага семантиката за достъп до устройство.
Възпроизведете го извън Compose файла
Преди да редактирате услугата, проверете дали хостът има устройството и дали гол контейнер може да създаде интерфейс. Командата по-долу е умишлено минимална и единствената ѝ цел е да отдели проблем на хоста от проблем на compose. Ако се провали, никаква промяна в compose няма да помогне.
ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun:/dev/net/tun alpine sh -c 'apk add -q iproute2 && ip tuntap add dev tun9 mode tun && ip link show tun9'
Липсващ възел на хоста означава, че модулът tun не е наличен, което е поправка от страна на хоста, а не на контейнера. Възел, който съществува, но не може да бъде отворен в контейнера, сочи към достъп до устройството и съобщението ще казва permission denied, а не no such file. Редът на тези две повреди е целият диагноз. Запишете коя от тях сте видели, преди да промените флаг.
Грешките след TUN са различни проблеми
Щом интерфейсът се появи, следващият провал има друг собственик. Грешките при удостоверяване означават, че тунелът е достигнал до сървъра и идентификационните данни са отхвърлени, така че промените в правата няма да помогнат. Тунел, който се установява, докато приложенията все още се провалят, сочи към маршрути, препращане, DNS резолюция вътре в контейнера или собствената мрежова схема на контейнера. Всяко от тях е обикновен мрежов въпрос, на който разрешението за TUN не може да отговори. Повтарянето на първоначалния тест след всяка промяна не позволява на провалите да се слеят в едно впечатление.
Копирането на всяка настройка от работещ пример е начинът, по който минимална поправка се превръща в неразбираема дефиниция на услуга. Прехвърлете само онези, които това внедряване изисква, и запишете защо е всяка.
Проверете интерфейса вътре в контейнера
Проверете интерфейса и набора от права отвътре в работещия контейнер, а не от хоста. Командите по-долу показват възела на устройството, списъка с права и дали изобщо може да се създаде интерфейс. Изпълнете ги в същия контейнер, който изпълнява клиента, и инсталирайте инструментите, ако образът е минимален.
ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9
Право, налично в bounding set, но отсъстващо от effective set, се държи различно от такова, което никога не е било давано, и capsh показва и двете. Ако възелът съществува и правото е налице, а създаването все още се проваля, средата за изпълнение налага нещо друго, например seccomp профил или AppArmor политика, която ограничава операцията. Това е трета граница, документирана от средата за изпълнение, а не от приложението.
Запишете флаговете на контейнера, образа и точната грешка от всеки опит. Следващият човек, който прочете тази бележка, може да каже коя врата е била затворена, без да повтаря цялото разследване.