Ang browser mo sa host ay nagpapakita ng exit address ng VPN, ang container ay nag-uulat ng iyong koneksyon sa bahay, at may tumatawag nito na pagtagas. Walang nagtagas. Ang tunnel ng host ay isang grupo ng mga interface, ruta at patakaran na kabilang sa network namespace ng host, at ang container sa bridge ay ibang namespace na may sariling default na ruta. Nakaupo ako sa isang Compose stack kung saan ang VPN client ay nakakonekta nang ilang linggo at wala kahit isang packet ng container ang pumasok doon.

Suriin ang namespace bago ang icon sa tray

Ang mga namespace ang buong argumento. Kapag naglunsad ang Docker ng container sa isang bridge network, gumagawa ito ng network namespace, ikinakabit ang isang dulo ng veth pair sa loob nito, at binibigyan ang namespace na iyon ng address at default na ruta. Ang interface ng tunnel, anuman ang itawag dito, ay naninirahan sa namespace ng host. Hindi ito nakikita ng trapiko sa loob ng container, at walang setting ng client ang nagbabago nito mula sa labas.

Dalawang sinusuportahang hakbang ang naglalabas sa iyo mula sa paghihiwalay. Inilalagay ng --network host ang container sa loob ng namespace ng host, kaya namamana nito ang mga ruta ng host at dahil dito ang tunnel. Ibinabahagi ng --network container:vpn ang namespace ng ibang container, at ganoon din ang ginagawa ng karamihan sa mga disenyong sidecar upang ipadala ang workload sa isang container ng VPN. Pareho silang malinaw na pagpipilian; karaniwang isa lamang sa kanila ang tunay na intensyon ng taong nagde-deploy.

Ang host mode ay hindi libreng upgrade. Nawawalan ang container ng sariling address, hindi na nalalapat ang paglalathala ng port, at ang prosesong may hawak ng NET_ADMIN doon ay maaaring mag-rewrite ng routing ng host. Ang tanggapin iyon ay maaaring tamang desisyon. Ang ipagpalagay na nakabukas na ito ang dahilan kung bakit may mga taong gumugugol ng isang gabi sa pag-debug ng tunnel na hindi kailanman nasa landas.

Sundan ang packet palabas ng bridge

Ang container sa bridge ay nagpapadala ng packet nito sa default na gateway, na siyang interface ng bridge sa host. Pagkatapos ay ipinapasa ng host ang packet at, sa default na configuration, isinasalin ang source address sa sarili nito bago lumabas ang packet. Ang hakbang na iyon ng pagsasalin ang tahimik na tumatalo sa patakaran.

Pagdating ng packet sa endpoint ng tunnel, dala na nito ang address ng host. Anumang patakaran, ruta ng patakaran o desisyon sa split tunnel na nakabatay sa orihinal na address ng container ay hindi na tumutugma, at dalawang container na dapat lumabas sa magkaibang exit ay hindi matutukoy sa source lamang. Kung kailangan mo ng routing kada container, ang desisyon ay dapat mangyari bago ang pagsasalin o sa loob ng namespace na kinokontrol mo.

Ang Docker mismo ang nagpapanatili ng mga patakarang ito, sa pamamagitan ng alinmang firewall backend na ginamit sa daemon. Ang mga patakarang isinulat sa kamay sa labas ng sinusuportahang hook para sa forwarded na trapiko, DOCKER-USER, ay maaaring muling ayusin o alisin kapag nag-restart ang daemon o nag-upgrade ang host. Ang dokumentasyon ng Docker sa pag-filter ng packet ay nagpapakita ng pagkakasunod-sunod ng mga chain; ang praktikal na punto ay kailangan ng bawat patakaran ng may-ari at ng landas ng muling pag-load na talagang sinubukan mo.

Subukan ang dalawang sistema nang hiwalay

Ang ebidensya mula sa isang namespace ay walang sinasabi tungkol sa isa pa. Ang kahilingang pinatakbo sa loob ng container ng VPN ay nagpapatunay na gumagana ang tunnel para sa container na iyon. Hindi ito ebidensya tungkol sa host, at ang parehong utos na pinatakbo mula sa container ng --network host ay hindi ebidensya tungkol sa bridge.

# host namespace
ip route get 1.1.1.1
ip -brief addr show

# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'

Pagkatapos ay ulitin ang pagsubok sa loob ng tunay na container ng application at hindi sa kahawig na image. Maaaring may dalang karagdagang ruta, environment variable ng proxy o ibang resolver ang app, at bawat isa sa mga iyon ay nagbabago ng sagot. Suriin ang resolution ng pangalan at ang pangalawang pamilya ng address sa bawat pagkakataon: ang mga container sa mga bridge na tinukoy ng user ay niresolba sa pamamagitan ng built-in na resolver ng Docker sa 127.0.0.11, at ang default na rutang IPv6 sa bridge ay maaaring magdala ng trapiko palabas habang abala ka sa pagsubok ng tunnel na IPv4 lamang.

Basahin ang pattern bago hawakan ang mga kredensyal

Kapag gumagana ang host at hindi ang container, ang sanhi ay halos palaging estruktural, at ang pag-ikot ng mga susi o muling pag-install ng client ay nagsasayang ng isang hapon. Ayusin muna ang sintomas at karaniwang pinangalanan ng pagwawasto ang sarili nito.

What you seeUsual causeFirst check
Host exits through the VPN, container shows the ISP addressThe container never entered the tunnelDefault route inside the container
Container works until the daemon restarts, then stopsRules outside the supported hook, or a changed backendDaemon's reported firewall backend and DOCKER-USER
Container loses internal hosts after the tunnel comes upVPN prefix overlaps the Docker bridge subnetip route on the host, then docker network inspect
Small replies arrive, large ones hangTunnel MTU or missing MSS clampingLink MTU on both ends of the tunnel
Container falls back to the ISP address when the tunnel dropsNothing enforces the kill switch for forwarded trafficStop the tunnel with a request in flight

Ang hilera ng overlap ay may karapatan sa sariling pangungusap. Ang profile ng VPN na nagtutulak ng ruta para sa 172.17.0.0/16, o para sa 10.0.0.0/8 na nagkataong naglalaman ng prefix ng iyong bridge, ay nagpipilit sa tunnel na angkinin ang subnet ng container, at ang mga sagot sa isinaling address ay pupunta sa maling direksyon o mawawala. Ang muling pag-numero ng network ng Docker ay karaniwang mas malinis kaysa sa pag-iipon ng mga eksepsyon.

Gawing malinaw ang saklaw, pagkatapos ay sadyang sirain ito

Dalawang disenyo ang nananatili sa pagsusuri. Ibahagi ang namespace ng container ng VPN at bawat sakop na workload ay gumagamit ng isang tunnel na may isang hangganan ng restart, na simple hanggang sa isang serbisyo ang mangailangan ng ibang exit o sariling landas ng DNS. O iruta ang network ng container papunta sa gateway ng VPN sa host: bukas ang forwarding, nakaturo ang prefix ng bridge sa tunnel, tahasang hinawakan ang trapikong pabalik. Binibili niyan ang kontrol kada network at nagkakahalaga sa iyo ng isang set ng patakarang dapat mong panatilihin sa mga upgrade ng daemon at client.

Anuman ito, ang pagsubok na mahalaga ay ang kaso ng pagkabigo. Ihinto ang tunnel habang nasa hangin ang isang kahilingan ng container at tingnan kung saan pupunta ang packet. Kung bumabalik ito sa direktang landas, hindi kailanman naipatupad ang saklaw, dahil ang kill switch ng client ay namamahala sa sariling trapiko ng client at hindi sa mga forwarded na packet mula sa bridge. Pagkatapos ay i-restart ang daemon at ang host at kumpirmahin ang resulta sa pangalawang pagkakataon; iyon ang sandaling nawawala ang mga patakarang isinulat sa kamay.

Bago mo sabihing tapos na, kumpirmahin ang apat na bagay: ang interface ng tunnel ay nasa parehong namespace ng trapiko, ang pagsubok ng container ay tumakbo sa loob ng tunay na container, sinuri ang resolution ng pangalan at ang dalawang pamilya ng address, at ang pagsubok ng pagkabigo ng tunnel ay nabibigo pa rin nang sarado. Pagkatapos ay isulat ang backend ng firewall, bersyon ng client at may-ari ng bawat patakaran. Ang rekord na iyon ang pumipigil sa susunod na upgrade na mag-iwan ng hindi dokumentadong halo ng lumang mga palagay.

Kaugnay na mga artikulo