El vostre contenidor encara respon al seu pont de control, però cada paquet de sortida marxa per la macvlan d'oficina. No ha fallat res. Dos enllaços aporten cadascun una passarel·la, i l'única ruta per defecte va anar a la xarxa que no volíeu, així que el servei continua funcionant mentre el seu trànsit pren un camí més llarg. Quan algú se n'adona, l'evidència és una taula d'encaminament i no un missatge d'error.

L'explicació habitual és que Docker va triar la xarxa per accident. A la pràctica, la decisió antiga seguia l'ordre alfabètic dels noms de les xarxes enllaçades, cosa que convertia l'encaminament en un efecte secundari d'una etiqueta. gw_priority ho substitueix per un número que trieu a propòsit, i adoptar-ho costa aproximadament un minut un cop l'esquema està escrit.

Per què la ruta per defecte cau a la xarxa equivocada

Cada xarxa a què s'uneix un servei pot oferir la seva pròpia passarel·la, i el contenidor acaba igualment amb exactament una ruta per defecte. Abans de Compose 2.33.1 l'empat es resolia ordenant els noms de les xarxes, així que una etiqueta com control que ve abans que office decidia on anava el trànsit. Res dins del contenidor no registra que la decisió fos arbitrària, i per això sobreviu a la revisió del codi i apareix més tard com un camí estrany. Posar una política al fitxer compose és l'única manera de fer l'elecció inspeccionable.

Dues coses canvien de veritat quina xarxa guanya: els valors de gw_priority que assigneu i quines xarxes hi ha enllaçades. Afegiu una tercera xarxa i el conjunt de candidates creix; traieu la macvlan i no queda res que competeixi amb el pont. Cap de les dues maniobres no apareix als registres de l'aplicació, perquè una ruta per defecte equivocada poques vegades trenca la connexió del tot. Només fa que les respostes arribin des d'una adreça que l'altra part potser no espera.

Fixeu la passarel·la amb gw_priority

Compose exposa gw_priority a cada enllaç servei-xarxa des de la versió 2.33.1, i guanya el número més alt. No hi ha cap clau de passarel·la per servei, així que el valor va dins del bloc networks del servei. L'exemple de sota dona la ruta per defecte a control mentre deixa office accessible per a la seva LAN directament connectada.

services:
  vpn:
    networks:
      control:
        gw_priority: 1
      office:
        gw_priority: 0

networks:
  control:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.50.0/24
  office:
    driver: macvlan
    driver_opts:
      parent: eno1.120
      macvlan_mode: bridge
    ipam:
      config:
        - subnet: 192.168.120.0/24
          ip_range: 192.168.120.192/27
          gateway: 192.168.120.1

Llegiu el bloc com dos controls separats: gw_priority decideix la ruta per defecte i la secció ipam decideix l'adreçament. Canviar només la subnet deixa intacta l'elecció de sortida, i aquesta és la manera més habitual que aquesta correcció s'apliqui a mitges. Manteniu les prioritats al costat de la xarxa que governen perquè el proper lector no hagi de caçar la decisió.

No confongueu gw_priority amb la propietat priority simple que té al costat. Aquella ordena la creació de connexions i no diu res sobre encaminament, així que no pot triar una passarel·la per defecte ni arregla el nom de les interfícies. Si algú recomana apujar priority per dirigir el trànsit, la recomanació és errònia encara que l'ordre resultant sembli correcte per casualitat.

Verifiqueu quina xarxa porta realment la ruta per defecte

Comproveu-ho dins del contenidor en execució, perquè la taula d'encaminament de l'amfitrió descriu l'amfitrió i no l'espai de noms que fa servir el servei. Executeu primer la comprovació de configuració perquè una errata falli abans d'un reinici, i després llegiu la ruta que el contenidor ha instal·lat de debò.

docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route

Un resultat correcte anomena el dispositiu de pont i 172.30.50.1; un d'equivocat anomena 192.168.120.1 i el dispositiu macvlan. Si la imatge no porta el paquet iproute2, el fitxer /proc encara informa de la ruta per defecte, amb destinació 00000000 i els bytes de la passarel·la invertits. Compareu la columna d'interfície amb docker inspect quan els noms dels dispositius no estiguin clars.

Macvlan és un port físic, no un clon del pont

Macvlan dona al contenidor una segona identitat al cable, i és exactament això el que fa funcionar l'accés als dispositius locals. També vol dir que el port del commutador i l'hipervisor han d'acceptar una adreça MAC extra, i moltes xarxes de núvol ho refusen en silenci. Proveu un contenidor abans de planificar una flota, perquè una MAC refusada sol aparèixer com un enllaç que està aixecat i no passa res.

El paràmetre macvlan_mode: bridge és un mode del controlador macvlan, no el pont de programari de Docker, i passthru és un mode especialitzat a part i no un valor per defecte. Linux també impedeix que un contenidor macvlan arribi al seu propi amfitrió a través del mateix pare, i aquesta és la raó de mantenir el pont de control en lloc d'esperar que un sol enllaç faci les dues feines.

Anomeneu el pare VLAN abans que Compose el vegi

Docker tracta un pare amb punt com eno1.120 com una subinterfície 802.1Q i crea ell mateix el dispositiu VLAN. Aquesta comoditat té límits: el nom derivat depèn del nom de la interfície física, i els noms llargs poden empènyer el resultat més enllà del que esperen les eines del voltant. Crear una interfície VLAN amb nom a la configuració de xarxa de l'amfitrió i apuntar-hi parent manté els dos extrems predictibles.

Recordeu que la clau sota networks és un nom de Compose, no un dispositiu Linux. Buscar a l'amfitrió una interfície anomenada office fallarà, perquè el nucli només veu la interfície pare i el parell veth darrere del contenidor.

Feu lloc per a la VPN a sobre

El client VPN s'enllaça després que existeixin aquestes xarxes, així que pot afegir rutes més específiques, regles de política i filtres independentment de gw_priority. Planifiqueu els prefixos remots contra les dues subnets locals, incloent-hi les respostes que necessita el camí de control. Quan un prefix remot se superposi amb la LAN d'oficina, arregleu el pla d'adreces en lloc d'arrencar tot un rang privat del túnel.

Torneu a comprovar adreces, rutes i el camí del servei després que arrenqui la VPN i un cop més després que es reconecti, perquè és en una reconnexió on desapareix una ruta afegida a mà. Escriviu la taula esperada abans de la primera prova perquè la comparació posterior sigui un diff i no un exercici de memòria. Manteniu la propietat persistent de la xarxa a Compose i deixeu que la configuració de la VPN només posseeixi la seva pròpia política.

Articles relacionats