De VPN staat aan, de browser bereikt interne sites, en de container kan dezelfde namen nog steeds niet oplossen. Een pakketinstallatie sterft met een naamresolutiefout zoals EAI_AGAIN, of een applicatie vindt geen databasehost die de hostmachine zonder enige klacht oplost. De container gebruikt niet de resolver die de VPN heeft geïnstalleerd. Docker kopieerde de resolverconfiguratie van de host toen de container werd aangemaakt, en daarna heeft niets hem opnieuw gekopieerd.

Twee resolverbeelden op één machine

Op Linux geeft Docker elke container bij het aanmaken een kopie van de resolverconfiguratie van de host, filtert loopbackadressen eruit en draait een ingebouwde DNS-server op 127.0.0.11 die query's naar buiten doorstuurt. Een VPN-client die /etc/resolv.conf herschrijft nadat de container is gestart, verandert daarbinnen niets. De container opnieuw starten helpt alleen als de resolver van de host op dat moment toevallig correct is.

Docker Desktop op macOS of Windows voegt een laag toe, omdat de daemon in een virtuele machine woont. De VPN-resolver van de host is misschien nooit zichtbaar voor die VM, dus opnieuw starten verandert helemaal niets. Vergelijk de twee beelden voordat je een oplossing kiest: docker exec mycontainer cat /etc/resolv.conf naast de resolverlijst van de host.

Een container die een publieke resolver vermeldt terwijl de host een interne vermeldt, lost publieke namen op en faalt op interne. Die splitsing is de signatuur van dit probleem.

Optie A: de tunnelresolver per container meegeven

Docker accepteert DNS-instellingen per container, en dat is de kleinste wijziging die werkt. Lees eerst de resolveradressen van de VPN: scutil --dns op macOS, resolvectl status of de eigen statusuitvoer van de client op Linux. Start de container daarna met die adressen, bijvoorbeeld docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. In Compose is dezelfde instelling een lijst onder de service, waar hij in versiebeheer woont in plaats van in iemands shellgeschiedenis.

Een dns-array in /etc/docker/daemon.json geldt voor elke nieuwe container, wat netter klinkt dan het is. Het geldt ook als de tunnel plat ligt, en een resolver die alleen via de VPN bereikbaar is, breekt dan gewone image-pulls. Instellingen per container zijn makkelijker te beargumenteren en makkelijker ongedaan te maken.

Optie B: de container het hostnetwerk laten delen

Hostnetwerken omzeilt de kopie volledig, omdat de container de resolver van de host en de tunnel van de host gebruikt. Het haalt ook de netwerkisolatie weg die je waarschijnlijk wilde, en het gedraagt zich niet hetzelfde onder Docker Desktop. Op Linux is het de pragmatische keuze voor een eenmalig hulpmiddel dat interne namen moet oplossen.

Voor builds geldt geen van beide opties, omdat buildstappen geen runtime-flags erven. Bouw met hostnetwerken waar het platform dat toestaat, of houd de installatie van afhankelijkheden in een fase die de tunnel niet nodig heeft.

Wat geen van beide opties oplost

Een DNS-adres is nutteloos als de container er geen route naartoe heeft. De VPN-resolver zit meestal binnen de adresruimte van de tunnel, dus de container heeft een pad naar dat prefix nodig. De standaardbrug van Docker routeert normaal via de host naar buiten, en dat is genoeg wanneer de host de tunnelroute heeft en doorsturen aan staat. Aangepaste brugnetwerken met eigen adrespoelen kunnen botsen met het VPN-subnet, en dan gaan query's heel ergens anders heen.

Controleer het subnet van het Dockernetwerk tegen het subnet van de VPN voordat je de resolver zelf debugt. Overlap levert een storing op die er precies uitziet als een kapotte DNS-server.

Verifieer binnen de container

Test met getent hosts db.internal binnen de container in plaats van met een browser of een taalruntime, omdat die hun eigen DNS-beleid en hun eigen cache toepassen. Als getent de naam oplost en de applicatie faalt nog steeds, is de resolver nu correct en zit het resterende probleem op applicatieniveau. Lost hij hem niet op, dan is de DNS-stap niet afgerond.

Maak de container opnieuw aan nadat je zijn DNS-instellingen hebt gewijzigd. Het bewerken van /etc/resolv.conf in een draaiende container verdwijnt ermee en verbergt het configuratieprobleem precies zo lang als iemand nodig heeft om hem opnieuw te starten.

Gerelateerde artikelen