In een container achter een bedrijfs-VPN wordt DNS opgelost, laadt de inlogpagina, antwoordt een health-endpoint, en dan blijft een HTTPS-verzoek hangen tot het in een time-out loopt. De image opnieuw bouwen en proxyvariabelen wijzigen verandert niets, want het falende deel zit niet in de image. De client authenticeert over het ene transport en verplaatst bulkdata over het andere, en alleen het tweede is stuk.

Twee transporten, één verwarrend symptoom

Een bedrijfsclient op basis van TLS authenticeert meestal over een gewone TLS-verbinding en onderhandelt daarna een tweede, op UDP gebaseerd datakanaal voor de sessie. Als die tweede poot werkt, verbeteren doorvoer en latentie. Als hij wordt gefilterd of niet door het pad past, slaagt alles vóór de bulkoverdracht en stopt de overdracht zelf, wat precies het patroon hierboven is.

Een container verandert die onderhandeling niet; hij verandert het pad dat de buitenste pakketten nemen. De host vertaalt de containerstroom, dus de UDP-datagrammen vertrekken vanaf een andere bronpoort dan de lokale socket van de client en komen terug via een vertaalregel die veel sneller verloopt dan een gevestigde TCP-stroom. Als de tunnel op de host werkt en in de container faalt, vergelijk dan die twee stromen voordat je de applicatie de schuld geeft. Die vergelijking beslecht meer dan welke herbouw van de image dan ook.

Beslis door experiment, niet op gevoel

Het goedkoopste experiment schakelt het UDP-datakanaal uit en herhaalt het verzoek. Gebruik de opdrachtregelclient in plaats van de desktopwrapper, zodat de flag echt wordt toegepast: openconnect vpn.example.net --user=you --interface=tun0 --no-dtls. Als het verzoek dat hing nu voltooit, was de DTLS-poot het probleem en de rest ruis.

Bevestig het resultaat in beide richtingen vanuit dezelfde container, één bulkverzoek met de flag en één zonder. Een gedragsverandering die de flag volgt is bewijs; een pagina die uiteindelijk laadt niet.

Als de flag het oplost, beslis waarom

Drie omstandigheden geven hetzelfde symptoom en vragen om verschillende reacties. Het pad kan UDP volledig filteren, waardoor de flag het juiste permanente antwoord voor dat netwerk is. Het pad kan UDP toestaan maar grote datagrammen laten vallen, wat op MTU wijst en niet op filtering. Of het pad kan zo verliesrijk zijn dat de UDP-poot slechter presteert dan TCP, wat een capaciteitsbeslissing is en geen bereikbaarheidsbeslissing.

Onderscheid ze voordat je een omweg documenteert. Filtering overleeft elke pakketgrootte, MTU-problemen verschijnen pas boven een drempel, en verlies uit zich als hertransmissie en wisselende vertraging in plaats van een schone hang. Elke test vernauwt de oorzaak zonder de clientconfiguratie te wijzigen.

Controleer de pakketgrootte voordat je de omweg houdt

Als de grootte de oorzaak is, accepteert de tunnelinterface pakketten die het pad niet kan dragen, en het probleem komt terug op elk transport zodra de payload groeit. Vergelijk de interfaces: ip link show tun0 op de host, dan docker network inspect bridge om de MTU te lezen die in de netwerkopties staat. Een containerbridge die nog op 1500 byte staat onder een tunnel die minder draagt, is de gebruikelijke vondst.

Peil omhoog vanaf een bekend goede grootte met een do-not-fragment-test in de tunnel, verlaag dan de MTU van het containernetwerk of knijp de TCP MSS op de tunnel. Beide correcties maken het UDP-pad vaak weer bruikbaar en nemen de flag weg, wat het betere resultaat is wanneer filtering niet de oorzaak is.

Beslis wat je bereid bent te ruilen

Met het datakanaal uitgeschakeld draagt de tunnel zijn lading in een TCP-verbinding. Op een schoon pad is dat alleen langzamer; op een verliesrijk pad vertraagt één verloren segment alles erachter en concurreert de buitenste hertransmissie met de binnenste. Die ruil past bij interactieve ontwikkeling en kleine API-aanroepen, en past slecht bij bulkoverdrachten of lange sessies over mobiele verbindingen.

Welke optie je ook kiest, leg vast welk transport de tunnel uiteindelijk gebruikte en waarom. Een container die stilzwijgend afhangt van een flag die iemand maanden geleden toevoegde, is de volgende storing, en wie die debugt weet niet of de flag een omweg voor filtering was of een restje van een MTU-experiment.

Gerelateerde artikelen