Kontejnerové obrazy mohou nést všechny binární soubory a konfigurační soubory OpenVPN, které potřebují, a přesto selhat při prvním síťovém volání. Chyba uvádí /dev/net/tun, protože aplikace požádala jádro o rozhraní TUN a kontejner neměl ani uzel zařízení, ani schopnost jej vytvořit. To jsou dvě oddělená oprávnění a oprava jednoho nechá druhé přesně tam, kde bylo.

Jejich oddělení vyžaduje jeden příkaz pro každé. Následná chybová zpráva vám řekne, na které hranici jste skutečně stáli.

Uzel zařízení a schopnost jsou dvoje dveře

Uzel zařízení je objekt souborového systému, takže jej kontejner musí vidět ve svém vlastním jmenném prostoru připojení. Schopnost je oprávnění, takže proces potřebuje CAP_NET_ADMIN ve jmenném prostoru, kde bude rozhraní vytvořeno. Předání zařízení bez schopnosti vám dá uzel, který se otevře, a ioctl, který selže. Udělení schopnosti bez zařízení nechá aplikaci neschopnou otevřít vůbec nic, a proto se obě obvykle objevují společně v příkladech.

Nastavení devices v Dockeru mapuje zařízení hostitele do kontejneru, zatímco cap_add upravuje sadu schopností. Bind mount stejné cesty umístí soubor do zorného pole, aniž by použil sémantiku přístupu k zařízení.

Reprodukujte to mimo soubor Compose

Před úpravou služby ověřte, že hostitel má zařízení a že holý kontejner dokáže vytvořit rozhraní. Níže uvedený příkaz je záměrně minimální a jeho jediným účelem je oddělit problém hostitele od problému compose. Pokud selže, žádná změna compose nepomůže.

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'

Chybějící uzel na hostiteli znamená, že modul tun není k dispozici, což je oprava na straně hostitele, nikoli kontejneru. Uzel, který existuje, ale nelze jej v kontejneru otevřít, ukazuje na přístup k zařízení a zpráva řekne permission denied namísto no such file. Pořadí těchto dvou selhání je celá diagnóza. Zapište, které jste viděli, než změníte příznak.

Chyby po TUN jsou jiné problémy

Jakmile se rozhraní objeví, má další selhání jiného vlastníka. Chyby ověřování znamenají, že tunel dosáhl serveru a přihlašovací údaje byly odmítnuty, takže změny schopností nepomohou. Tunel, který se naváže, zatímco aplikace stále selhávají, ukazuje na trasy, přesměrování, překlad DNS uvnitř kontejneru nebo vlastní síťové uspořádání kontejneru. Každé z toho je běžná síťová otázka, na kterou oprávnění TUN nedokáže odpovědět. Opakování původního testu po každé změně brání tomu, aby se selhání slila v jeden dojem.

Kopírování každého nastavení z funkčního příkladu je způsob, jak se z minimální opravy stane nečitelná definice služby. Přeneste jen ta, která toto nasazení potřebuje, a poznamenejte, proč je každé tam.

Ověřte rozhraní uvnitř kontejneru

Zkontrolujte rozhraní a sadu schopností z nitra běžícího kontejneru, nikoli z hostitele. Níže uvedené příkazy ukazují uzel zařízení, seznam schopností a zda lze rozhraní vůbec vytvořit. Spusťte je ve stejném kontejneru, který spouští klienta, a nainstalujte nástroje, pokud je obraz minimální.

ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9

Schopnost přítomná v bounding set, ale chybějící v effective set, se chová jinak než ta, která nebyla nikdy udělena, a capsh ukazuje obě. Pokud uzel existuje a schopnost je k dispozici, zatímco vytváření stále selhává, runtime prosazuje něco jiného, například profil seccomp nebo zásadu AppArmor, která operaci omezuje. To je třetí hranice, kterou dokumentuje runtime, nikoli aplikace.

Zapište příznaky kontejneru, obraz a přesnou chybu každého pokusu. Další člověk, který tuto poznámku přečte, pozná, které dveře byly zavřené, aniž by opakoval celé vyšetřování.

Související články