Docker: encamiña un contedor pola VPN e mantén outro directo
Dálle ao túnel o seu propio contedor, deixa que só os servizos que o necesitan compartan ese espazo de nomes e despois ten en conta o que segue o propietario: portos, localhost, DNS.
Unha máquina, dúas cargas de traballo e un requisito que as separa: un cliente de descargas que debe saír por unha VPN comercial e unha interface de administración que debe seguir usando a conexión da máquina. Instalar o cliente VPN na máquina incumpre o requisito de inmediato, porque entón ambas as cargas comparten unha soa saída. O patrón que si funciona é trasladar o túnel ao seu propio contedor e permitir que só as cargas que o necesitan se unan ao espazo de nomes de rede dese contedor. Todo o demais mantén o camiño habitual de Docker, e os detalles que seguen son consecuencias de quen posúe o espazo de nomes.
Por que un espazo de nomes compartido cambia as regras
Un contedor que se une ao espazo de nomes doutro non obtén a súa propia pila de rede. Ve as mesmas interfaces, a mesma táboa de encamiñamento e o mesmo loopback que o contedor ao que se uniu, e precisamente por iso o patrón é útil: a carga resolve e conecta con normalidade, e o túnel de debaixo captura o tráfico sen que a aplicación o saiba. O custo é que cada axuste de rede ten agora un só propietario, e o contedor que se une non o é.
Esa regra de propiedade responde a maioría das preguntas de configuración antes de que se formulen. Se un axuste vive na pila de rede, pertence ao contedor lateral. Se describe o proceso, queda coa carga.
O loopback é a parte que sorprende a xente. Dentro do contedor que se une, localhost resólvese ao loopback do contedor lateral, non a un privado propio, así que un servizo que se liga a 127.0.0.1 esperando illamento agora comparte ese enderezo co contedor do túnel.
Publica os portos no contedor que posúe o espazo de nomes
A asignación de portos pertence ao propietario do espazo de nomes mesmo cando o proceso que escoita se executa no outro contedor. Declara a asignación no contedor lateral e deixa que a carga conserve a súa propia configuración de proceso intacta. Unha asignación no servizo que se une non pode surtir efecto, xa sexa porque o motor a rexeita ou porque a ignora en silencio segundo como se inicie o contedor, e por iso unha interface que era accesible hai un momento desaparece en canto se aplica o patrón.
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"]Le ese bloque como tres decisións en lugar de tres servizos. O contedor lateral posúe o túnel e o porto publicado; o cliente que se une non declara ningunha rede; o cliente directo conserva unha asignación propia na rede predeterminada. A capacidade NET_ADMIN é o que permite ao contedor lateral crear interfaces e alterar rutas, e é a razón pola que este contedor necesita máis privilexios que as cargas ás que serve.
O servizo que queda directo conserva a súa propia rede
A carga que non debe pasar polo túnel conserva a ponte predeterminada ou unha rede definida polo usuario propia, co seu propio porto publicado e a súa propia saída. É tentador conectala á rede do contedor lateral para que os dous contedores poidan falar por nome, pero ese único paso traslada o seu tráfico ao túnel sen avisar. Se necesitan alcanzarse, constrúe unha rede definida polo usuario á parte, conecta ambos a ela e deixa o contedor lateral como a única vía de saída.
Mantén as dúas preguntas separadas: que contedores poden alcanzarse e cal sae por onde. Fusionalas é a forma máis habitual de que este deseño volva converterse nunha VPN para toda a máquina.
Unha matriz de fallos para a primeira hora
A maioría dos primeiros intentos fallan dunha de catro maneiras, e cada unha ten unha causa distinta. Compróbaas nesta orde, porque as dúas primeiras explican case todos os informes.
| Symptom | Likely cause |
|---|---|
| Web UI unreachable after the change | Port mapping declared on the joining container instead of the sidecar |
| Both containers show the provider's exit address | The direct service was attached to the sidecar network |
| Internal names stop resolving | Resolver settings live on the host, not in the shared namespace |
| Health check fails but the app works | The check probes localhost, which now means the sidecar |
A cuarta fila é a que a xente diagnostica mal como un fallo da aplicación. Unha sonda escrita contra o loopback propio da carga agora está a probar o contedor do túnel, así que ou falla ou informa dun servizo completamente equivocado.
Cando un só nome de máquina necesita o túnel
Ás veces un túnel completo é demasiado: un nome interno debe pasar por unha VPN corporativa mentres un socket local ou unha conexión de pantalla segue funcionando. Un túnel completo dentro do contedor rompe esa ruta e todo o dirixido á máquina, así que encamiña só o prefixo que o necesita. Un envoltorio de encamiñamento dividido arredor do cliente fai iso, enviando o nome de máquina indicado polo túnel e deixando a ruta anterior intacta para todo o demais.
Escolle isto cando só necesitas alcanzar un servizo e non intentas mover todo o tráfico do contedor. É unha ferramenta distinta do contedor lateral e responde a unha pregunta distinta.
Verifica e logo fai que sobreviva a un reinicio
Pregunta a cada contedor de que enderezo parece vir. O do túnel debería imprimir o enderezo do provedor e o directo a saída da máquina. Respostas idénticas significan que o servizo directo herdou o espazo de nomes equivocado ou que unha VPN a nivel de máquina segue capturándoo todo, e esas dúas correccións son distintas. Volve executar a comprobación despois de cada edición de compose, porque un só bloque de servizo copiado abonda para reintroducir o problema.
Tres cousas adoitan romper máis adiante. O DNS segue o propietario do espazo de nomes, así que os axustes de resolutor e de dominio de busca pertencen ao contedor lateral e non á máquina. Unha VPN con reenvío de portos cambia o seu porto de escoita ao reconectar, así que o porto reenviado do provedor e o porto de escoita do lado do contedor deben volver escribirse na configuración do cliente ou na asignación de portos, normalmente mediante un pequeno actualizador que le a API do provedor. E calquera sonda escrita contra localhost agora pregunta ao contedor do túnel e non á carga.
Escribe o patrón, incluído que contedor posúe o espazo de nomes e que portos lle pertencen. A seguinte persoa engadirá un servizo, copiará o bloque equivocado e reproducirá o primeiro fallo deste artigo.