Docker: encamina un contenidor pel VPN i mantén un altre directe
Dona al túnel el seu propi contenidor, deixa que només els serveis que el necessiten comparteixin aquest espai de noms i després tingues en compte què segueix el propietari: ports, localhost, DNS.
Un amfitrió, dues càrregues de treball i un requisit que les separa: un client de descàrrega que ha de sortir per un VPN comercial i una interfície de gestió que ha de continuar utilitzant la connexió de l'amfitrió. Instal·lar el client VPN a l'amfitrió incompleix el requisit immediatament, perquè llavors les dues càrregues comparteixen una sola sortida. El patró que sí que funciona és traslladar el túnel al seu propi contenidor i permetre que només les càrregues que el necessiten s'uneixin a l'espai de noms de xarxa d'aquell contenidor. Tota la resta manté el camí habitual de Docker, i els detalls que segueixen són conseqüències de qui posseeix l'espai de noms.
Per què un espai de noms compartit canvia les regles
Un contenidor que s'uneix a l'espai de noms d'un altre no obté la seva pròpia pila de xarxa. Veu les mateixes interfícies, la mateixa taula d'encaminament i el mateix loopback que el contenidor al qual s'ha unit, i precisament per això el patró és útil: la càrrega resol i es connecta amb normalitat, i el túnel de sota captura el trànsit sense que l'aplicació ho sàpiga. El cost és que cada paràmetre de xarxa té ara un sol propietari, i el contenidor que s'hi uneix no ho és.
Aquesta regla de propietat respon la majoria de preguntes de configuració abans que es facin. Si un paràmetre viu a la pila de xarxa, pertany al contenidor lateral. Si descriu el procés, es queda amb la càrrega.
El loopback és la part que sorprèn la gent. Dins del contenidor que s'hi uneix, localhost es resol al loopback del contenidor lateral, no a un de privat propi, així que un servei que s'enllaça a 127.0.0.1 esperant aïllament ara comparteix aquesta adreça amb el contenidor del túnel.
Publica els ports al contenidor que posseeix l'espai de noms
La mapació de ports pertany al propietari de l'espai de noms fins i tot quan el procés que escolta s'executa a l'altre contenidor. Declara la mapació al contenidor lateral i deixa que la càrrega mantingui la seva pròpia configuració de procés intacta. Una mapació al servei que s'uneix no pot tenir efecte, tant si el motor la rebutja com si la ignora en silenci segons com s'inicia el contenidor, i per això una interfície que era accessible fa un moment desapareix quan s'aplica el patró.
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"]Llegeix aquest bloc com tres decisions i no com tres serveis. El contenidor lateral posseeix el túnel i el port publicat; el client que s'uneix no declara cap xarxa; el client directe conserva una mapació pròpia a la xarxa per defecte. La capacitat NET_ADMIN és el que permet al contenidor lateral crear interfícies i alterar rutes, i és la raó per la qual aquest contenidor necessita més privilegis que les càrregues a què serveix.
El servei que es queda directe conserva la seva pròpia xarxa
La càrrega que no ha de passar pel túnel conserva el pont per defecte o una xarxa definida per l'usuari pròpia, amb el seu propi port publicat i la seva pròpia sortida. És temptador connectar-la a la xarxa del contenidor lateral perquè els dos contenidors es puguin parlar pel nom, però aquest sol pas mou el seu trànsit cap al túnel sense avisar. Si s'han d'abastar, construeix una xarxa definida per l'usuari a part, connecta-hi tots dos i deixa el contenidor lateral com a única via de sortida.
Mantingues les dues preguntes separades: quins contenidors es poden abastar i quin surt per on. Fusionar-les és la manera més habitual que aquest disseny torni a convertir-se en un VPN per a tot l'amfitrió.
Una matriu de fallades per a la primera hora
La majoria dels primers intents fallen d'una de quatre maneres, i cadascuna té una causa diferent. Comprova-les en aquest ordre, perquè les dues primeres expliquen gairebé tots els 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 |
La quarta fila és la que la gent diagnostica malament com un error de l'aplicació. Una sonda escrita contra el loopback propi de la càrrega ara està provant el contenidor del túnel, així que o falla o informa d'un servei completament equivocat.
Quan un sol nom d'amfitrió necessita el túnel
De vegades un túnel complet és massa: un nom intern ha de passar per un VPN corporatiu mentre un sòcol local o una connexió de pantalla continua funcionant. Un túnel complet dins del contenidor trenca aquest camí i tot el que s'adreça a l'amfitrió, així que encamina només el prefix que ho necessita. Un embolcall d'encaminament dividit al voltant del client ho fa, enviant el nom d'amfitrió indicat pel túnel i deixant la ruta anterior intacta per a tota la resta.
Tria això quan només necessites arribar a un servei i no intentes moure tot el trànsit del contenidor. És una eina diferent del contenidor lateral i respon una pregunta diferent.
Verifica, i després fes que sobrevisqui a un reinici
Pregunta a cada contenidor de quina adreça sembla que ve. El del túnel hauria d'imprimir l'adreça del proveïdor i el directe hauria d'imprimir la sortida de l'amfitrió. Respostes idèntiques volen dir que el servei directe ha heretat l'espai de noms equivocat o que un VPN a nivell d'amfitrió encara ho captura tot, i aquestes dues correccions són diferents. Torna a executar la comprovació després de cada edició de compose, perquè un sol bloc de servei copiat n'hi ha prou per reintroduir el problema.
Tres coses solen trencar-se més endavant. El DNS segueix el propietari de l'espai de noms, així que els paràmetres de resolutor i de domini de cerca pertanyen al contenidor lateral i no a l'amfitrió. Un VPN amb reenviament de ports canvia el seu port d'escolta en tornar a connectar, així que el port reenviat del proveïdor i el port d'escolta del costat del contenidor s'han d'escriure de nou a la configuració del client o a la mapació de ports, normalment amb un petit actualitzador que llegeix l'API del proveïdor. I qualsevol sonda escrita contra localhost ara pregunta al contenidor del túnel i no a la càrrega.
Escriu el patró, incloent-hi quin contenidor posseeix l'espai de noms i quins ports li pertanyen. La següent persona afegirà un servei, copiarà el bloc equivocat i reproduirà la primera fallada d'aquest article.