Un contedor con dúas redes escolle a porta de enlace equivocada
Dúas conexións, unha ruta predeterminada e a rede equivocada gaña sempre. Fixe a saída con Compose gw_priority e confírmeo desde dentro do contedor.
O seu contedor segue respondendo na súa ponte de control, pero cada paquete de saída marcha pola macvlan de oficina. Nada fallou. Dúas conexións achegan cadansúa porta de enlace, e a única ruta predeterminada foi cara á rede que non pretendía, así que o servizo segue funcionando mentres o seu tráfico toma un camiño máis longo. Cando alguén o nota, a evidencia é unha táboa de encamiñamento e non unha mensaxe de erro.
A explicación habitual é que Docker escolleu a rede por accidente. Na práctica, a decisión antiga seguía a orde alfabética dos nomes das redes conectadas, o que convertía o encamiñamento nun efecto secundario dunha etiqueta. gw_priority substitúeo por un número que vostede escolle a propósito, e adoptalo leva aproximadamente un minuto unha vez escrito o esquema.
Por que a ruta predeterminada aterra na rede equivocada
Cada rede á que se une un servizo pode ofrecer a súa propia porta de enlace, e o contedor acaba igualmente con exactamente unha ruta predeterminada. Antes de Compose 2.33.1 o empate resolvíase ordenando os nomes das redes, así que unha etiqueta como control que vén antes de office decidía cara a onde ía o tráfico. Nada dentro do contedor rexistra que a decisión fose arbitraria, e por iso sobrevive á revisión de código e aparece máis tarde como un camiño estraño. Poñer unha política no ficheiro compose é a única forma de facer a escolla inspeccionable.
Dúas cousas cambian de verdade que rede gaña: os valores de gw_priority que asigna e que redes están conectadas. Engada unha terceira rede e o conxunto de candidatas medra; quite a macvlan e non queda nada que compita coa ponte. Ningún dos dous movementos aparece nos rexistros da aplicación, porque unha ruta predeterminada equivocada raramente rompe a conexión de todo. Só fai que as respostas cheguen desde un enderezo que a outra parte quizais non espera.
Fixe a porta de enlace con gw_priority
Compose expón gw_priority en cada conexión servizo-rede desde a versión 2.33.1, e gaña o número máis alto. Non hai unha clave de porta de enlace por servizo, así que o valor vai dentro do bloque networks do servizo. O exemplo de abaixo entrega a ruta predeterminada a control mentres office segue accesible para a súa LAN directamente conectada.
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
Lea o bloque como dous controis distintos: gw_priority decide a ruta predeterminada e a sección ipam decide o direccionamento. Cambiar só a subnet deixa intacta a escolla de saída, e esa é a forma máis habitual de que esta corrección se aplique a medias. Manteña as prioridades xunto á rede que gobernan para que o seguinte lector non teña que buscar a decisión.
Non confunda gw_priority coa propiedade priority simple que ten ao lado. Ese ordena a creación de conexións e non di nada sobre encamiñamento, así que non pode escoller unha porta de enlace predeterminada nin arranxa os nomes das interfaces. Se alguén recomenda subir priority para dirixir o tráfico, a recomendación é errónea aínda que a orde resultante pareza correcta por casualidade.
Verifique que rede transporta realmente a ruta predeterminada
Compróbeo dentro do contedor en execución, porque a táboa de encamiñamento do host describe o host e non o espazo de nomes que usa o servizo. Execute primeiro a comprobación de configuración para que unha errata falle antes dun reinicio, e despois lea a ruta que o contedor instalou de verdade.
docker compose config --quiet
docker exec vpn ip -4 route show default
docker exec vpn cat /proc/net/route
Un resultado correcto nomea o dispositivo ponte e 172.30.50.1; un equivocado nomea 192.168.120.1 e o dispositivo macvlan. Se a imaxe non inclúe o paquete iproute2, o ficheiro /proc segue informando da ruta predeterminada, con destino 00000000 e os bytes da porta de enlace investidos. Compare a columna de interface con docker inspect cando os nomes dos dispositivos non estean claros.
Macvlan é un porto físico, non un clon da ponte
Macvlan dá ao contedor unha segunda identidade no cable, e iso é xusto o que fai funcionar o acceso aos dispositivos locais. Tamén significa que o porto do conmutador e o hipervisor deben aceptar un enderezo MAC extra, e moitas redes de nube rexéitano en silencio. Probe un contedor antes de planificar unha frota, porque unha MAC rexeitada adoita aparecer como unha ligazón que está levantada e non pasa nada.
O axuste macvlan_mode: bridge é un modo do controlador macvlan, non a ponte de software de Docker, e passthru é un modo especializado á parte e non un valor por defecto. Linux tamén impide que un contedor macvlan alcance o seu propio host a través do mesmo pai, e esa é a razón de manter a ponte de control en lugar de esperar que unha soa conexión faga as dúas tarefas.
Nomee o pai VLAN antes de que Compose o vexa
Docker trata un pai con punto como eno1.120 como unha subinterface 802.1Q e crea el mesmo o dispositivo VLAN. Esa comodidade ten límites: o nome derivado depende do nome da interface física, e os nomes longos poden empurrar o resultado máis aló do que esperan as ferramentas da contorna. Crear unha interface VLAN con nome na configuración de rede do host e apuntar parent cara a ela mantén os dous extremos previsibles.
Lembre que a clave baixo networks é un nome de Compose, non un dispositivo Linux. Buscar no host unha interface chamada office fallará, porque o núcleo só ve a interface pai e o par veth detrás do contedor.
Faga sitio para a VPN por riba
Un cliente VPN conéctase despois de que existan estas redes, así que pode engadir rutas máis específicas, regras de política e filtros con independencia de gw_priority. Planifique os prefixos remotos contra as dúas subredes locais, incluídas as respostas que necesita o camiño de control. Cando un prefixo remoto se solape coa LAN de oficina, corrixa o plan de enderezos en lugar de arrincar todo un rango privado do túnel.
Volva comprobar enderezos, rutas e o camiño do servizo despois de que arrinque a VPN e outra vez despois de que se reconecte, porque é nunha reconexión onde desaparece unha ruta engadida a man. Escriba a táboa esperada antes da primeira proba para que a comparación posterior sexa un diff e non un exercicio de memoria. Manteña a propiedade persistente da rede en Compose e deixe que a configuración da VPN posúa só a súa propia política.