En värd, två arbetsbelastningar och ett krav som skiljer dem: en nedladdningsklient som måste gå ut genom en kommersiell VPN, och ett administrationsgränssnitt som måste fortsätta använda värdens anslutning. Att installera VPN-klienten på värden bryter kravet direkt, eftersom båda arbetsbelastningarna då delar en enda utgång. Mönstret som faktiskt fungerar är att flytta tunneln till sin egen container och bara låta de arbetsbelastningar som behöver den ansluta till den containerns nätverksnamnutrymme. Allt annat behåller den vanliga Docker-vägen, och detaljerna som följer är konsekvenser av vem som äger namnutrymmet.

Varför ett delat namnutrymme ändrar reglerna

En container som ansluter till en annans namnutrymme får inte sin egen nätverksstack. Den ser samma gränssnitt, samma routingtabell och samma loopback som containern den anslöt till, och det är just därför mönstret är användbart: arbetsbelastningen slår upp och ansluter normalt, och tunneln under fångar trafiken utan att applikationen vet om det. Priset är att varje nätverksinställning nu har en enda ägare, och containern som ansluter är inte den ägaren.

Den ägarregeln svarar på de flesta konfigurationsfrågor innan de ställs. Om en inställning lever i nätverksstacken hör den till sidocontainern. Om den beskriver processen stannar den hos arbetsbelastningen.

Loopback är den del som förvånar folk. Inuti containern som ansluter slås localhost upp till sidocontainerns loopback, inte till en egen privat, så en tjänst som binder till 127.0.0.1 och förväntar sig isolering delar nu den adressen med tunnelcontainern.

Publicera portar på containern som äger namnutrymmet

Portmappningen tillhör ägaren av namnutrymmet, även när den lyssnande processen körs i den andra containern. Deklarera mappningen på sidocontainern, och låt arbetsbelastningen behålla sin egen processkonfiguration orörd. En mappning på tjänsten som ansluter kan inte träda i kraft, antingen motorn avvisar den eller tyst ignorerar den beroende på hur containern startas, och därför försvinner ett gränssnitt som var nåbart för en stund sedan så snart mönstret tillämpas.

services:
  gluetun:
    image: qmcgaw/gluetun
    cap_add: [NET_ADMIN]
    ports: ["8080:8080"]
  client-vpn:
    image: example/client
    network_mode: "service:gluetun"
  client-direct:
    image: example/client
    ports: ["8081:8080"]

Läs det blocket som tre beslut i stället för tre tjänster. Sidocontainern äger tunneln och den publicerade porten; klienten som ansluter deklarerar inget nätverk alls; den direkta klienten behåller en egen mappning på standardnätverket. Förmågan NET_ADMIN är det som låter sidocontainern skapa gränssnitt och ändra rutter, och det är anledningen till att den här containern behöver fler privilegier än arbetsbelastningarna den betjänar.

Tjänsten som förblir direkt behåller sitt eget nätverk

Arbetsbelastningen som inte får gå genom tunneln behåller standardbryggan eller ett eget användardefinierat nätverk, med sin egen publicerade port och sin egen utgång. Det är frestande att koppla den till sidocontainerns nätverk så att de två containrarna kan prata vid namn, men det enda steget flyttar tyst dess trafik in i tunneln. Om de måste nå varandra, bygg ett separat användardefinierat nätverk, koppla båda till det och låt sidocontainern vara den enda vägen ut.

Håll de två frågorna åtskilda: vilka containrar som kan nå varandra, och vilken som går ut var. Att slå ihop dem är det vanligaste sättet som den här designen blir en VPN för hela värden igen.

En felmatris för den första timmen

De flesta första försök misslyckas på ett av fyra sätt, och varje sätt har en annan orsak. Kontrollera dem i den här ordningen, eftersom de två första förklarar nästan varje rapport.

SymptomLikely cause
Web UI unreachable after the changePort mapping declared on the joining container instead of the sidecar
Both containers show the provider's exit addressThe direct service was attached to the sidecar network
Internal names stop resolvingResolver settings live on the host, not in the shared namespace
Health check fails but the app worksThe check probes localhost, which now means the sidecar

Den fjärde raden är den som folk felaktigt diagnostiserar som en programvarubugg. En kontroll skriven mot arbetsbelastningens egen loopback testar nu tunnelcontainern, så den misslyckas antingen eller rapporterar en helt fel tjänst.

När ett enda värdnamn behöver tunneln

Ibland är en full tunnel för mycket: ett internt namn måste gå genom en företags-VPN medan en lokal socket eller skärmanslutning fortsätter att fungera. En full tunnel inuti containern bryter den vägen och allt som är adresserat till värden, så rutta bara det prefix som behöver det. Ett split-routing-omslag runt klienten gör det, skickar det namngivna värdnamnet genom tunneln och låter den tidigare rutten vara orörd för allt annat.

Välj detta när du bara behöver nå en tjänst och inte försöker flytta all trafik i containern. Det är ett annat verktyg än sidocontainern, och det svarar på en annan fråga.

Verifiera och gör det sedan motståndskraftigt mot omstart

Fråga varje container vilken adress den ser ut att komma från. Den tunnlade bör skriva ut leverantörens adress och den direkta värdens utgång. Identiska svar betyder att den direkta tjänsten ärvde fel namnutrymme eller att en VPN på värdnivå fortfarande fångar allt, och de två åtgärderna är olika. Kör kontrollen igen efter varje compose-ändring, eftersom ett enda kopierat tjänsteblock räcker för att återinföra problemet.

Tre saker brukar gå sönder senare. DNS följer namnutrymmets ägare, så inställningar för resolver och sökdomän hör till sidocontainern och inte till värden. En VPN med portvidarebefordran ändrar sin lyssnande port vid återanslutning, så leverantörens vidarebefordrade port och containerns lyssnande port måste skrivas tillbaka i klientkonfigurationen eller portmappningen, vanligtvis av en liten uppdaterare som läser leverantörens API. Och varje kontroll som är skriven mot localhost, frågar nu tunnelcontainern i stället för arbetsbelastningen.

Skriv ned mönstret, inklusive vilken container som äger namnutrymmet och vilka portar som hör till det. Nästa person kommer att lägga till en tjänst, kopiera fel block och återskapa det första felet i den här artikeln.

Relaterade artiklar