Docker контейнерлерінің трафигі хост VPN-ін айналып өтеді: қалай тексеру керек
Хост VPN-і тек хосттың желілік атаулар кеңістігін қамтиды. Осы тексерулер арқылы көпірдегі контейнерлер трафигінің туннельге кіретінін немесе тікелей шығатынын анықтаңыз.
Хосттағы браузеріңіз VPN-нің шығу мекенжайын көрсетеді, контейнер үй байланысыңыз туралы хабарлайды, ал біреу мұны ағу деп атайды. Ештеңе ақпаған. Хост туннелі — хосттың желілік атаулар кеңістігіне жататын интерфейстер, маршруттар мен ережелер жиынтығы, ал көпірдегі контейнер — өзінің әдепкі маршруты бар басқа атаулар кеңістігі. Мен VPN клиенті апталар бойы қосылып тұрған, бірақ бірде-бір контейнер пакеті оған ешқашан кірмеген Compose стекінде отырдым.
Атаулар кеңістігін трей белгішесінен бұрын тексеріңіз
Атаулар кеңістіктері — бүкіл дәйек. Docker көпірлі желіде контейнерді іске қосқанда, ол желілік атаулар кеңістігін жасайды, veth жұбының бір ұшын оның ішіне қосады және бұл кеңістікке мекенжай мен әдепкі маршрут береді. Туннель интерфейсі, қалай аталса да, хосттың атаулар кеңістігінде өмір сүреді. Контейнер ішіндегі трафик оны көре алмайды, және ешбір клиент параметрі мұны сырттан өзгертпейді.
Оқшаулаудан шығаратын екі қолдау көрсетілген қадам бар. --network host контейнерді хосттың атаулар кеңістігіне орналастырады, сондықтан ол хосттың маршруттарын және сол арқылы туннельді мұраға алады. --network container:vpn басқа контейнердің атаулар кеңістігін бөліседі, және sidecar конструкцияларының көбі жүктемені VPN контейнері арқылы осылай жібереді. Екеуі де айқын таңдау; әдетте олардың тек біреуі ғана орналастырушының ойлағаны.
Хост режимі тегін жаңарту емес. Контейнер өз мекенжайын иеленуді тоқтатады, порттарды жариялау қолданылудан қалады, және онда NET_ADMIN ұстаған процесс хосттың маршруттауын қайта жаза алады. Мұны қабылдау дұрыс шешім болуы мүмкін. Ол әлдеқашан қосылған деп болжау — адамдардың жолда ешқашан болмаған туннельді кеш бойы жөндеуінің себебі.
Пакетті көпірден шығарып бақылаңыз
Көпірдегі контейнер пакетін өзінің әдепкі қақпасына жібереді, ол хосттағы көпір интерфейсі. Содан кейін хост пакетті жібереді және әдепкі конфигурацияда пакет шықпай тұрып, бастапқы мекенжайды өзінің мекенжайына аударады. Дәл осы аудару қадамы саясатты үнсіз жояды.
Пакет туннельдің соңғы нүктесіне жеткенде, ол хосттың мекенжайын алып жүреді. Контейнердің бастапқы мекенжайына негізделген кез келген ереже, саясат маршруты немесе бөлінген туннель шешімі сәйкестігін тоқтатады, және әртүрлі шығу жолдарынан шығуға арналған екі контейнерді тек бастапқы мекенжай бойынша ажырату мүмкін емес. Егер контейнер сайын маршруттау қажет болса, шешім аударуға дейін немесе өзіңіз бақылайтын атаулар кеңістігінде қабылдануы керек.
Docker бұл ережелерді өзі ұстайды, daemon конфигурацияланған қандай firewall backend арқылы болсын. Жіберілетін трафик үшін қолдау көрсетілген ілгектен тыс қолмен жазылған ережелер, DOCKER-USER, daemon қайта іске қосылғанда немесе хост жаңартылғанда қайта реттелуі немесе жойылуы мүмкін. Docker-дың пакеттерді сүзу туралы құжаттамасы тізбектердің ретін көрсетеді; практикалық мәселе — әр ережеге ие және шынымен сынаған қайта жүктеу жолы қажет.
Екі жүйені бөлек сынаңыз
Бір атаулар кеңістігінен алынған дәлел екіншісі туралы ештеңе айтпайды. VPN контейнерінің ішінде орындалған сұрау туннельдің сол контейнер үшін жұмыс істейтінін дәлелдейді. Бұл хост туралы дәлел емес, және --network host контейнерінен орындалған сол бұйрық көпір туралы дәлел емес.
# 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'
Содан кейін сынақты ұқсас имидждің орнына нақты қолданба контейнерінің ішінде қайталаңыз. Қолданба қосымша маршрут, прокси ортасының айнымалысы немесе басқа шешуші алып жүруі мүмкін, және олардың әрқайсысы жауапты өзгертеді. Аттарды шешуді және мекенжайлардың екінші тобын әр жолы тексеріңіз: пайдаланушы анықтаған көпірлердегі контейнерлер Docker-дың кіріктірілген шешушісі арқылы 127.0.0.11 мекенжайында шешіледі, ал көпірдегі IPv6 әдепкі маршруты сіз тек IPv4 туннелін сынаумен айналысып жатқанда трафикті сыртқа шығара алады.
Тіркелгі деректерін ұстамас бұрын үлгіні оқыңыз
Хост жұмыс істеп, контейнер істемегенде, себеп әрдайым дерлік құрылымдық, және кілттерді айналдыру немесе клиентті қайта орнату жарты күнді жоғалтады. Алдымен симптомды реттеңіз, түзету әдетте өзі аталады.
| What you see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop the tunnel with a request in flight |
Қабаттасу жолы өз сөйлеміне лайық. 172.17.0.0/16 үшін немесе көпір префиксіңізді кездейсоқ қамтитын 10.0.0.0/8 үшін маршрутты итеретін VPN профилі туннельді контейнер ішкі желісіне талап қоюға мәжбүр етеді, және аударылған мекенжайларға баратын жауаптар қате бағытқа кетеді немесе жоғалады. Docker желісін қайта нөмірлеу әдетте ерекшеліктерді жинақтаудан тазарақ.
Қамтуды айқын етіңіз, содан кейін оны әдейі бұзыңыз
Екі конструкция қарауға төтеп береді. VPN контейнерінің атаулар кеңістігін бөлісіңіз, сонда қамтылған әрбір жүктеме бір қайта іске қосу шекарасы бар бір туннельді пайдаланады, бұл бір қызметке басқа шығу немесе өзінің DNS жолы қажет болғанша қарапайым. Немесе контейнерлер желісін хосттағы VPN қақпасына бағыттаңыз: жіберу қосылған, көпір префиксі туннельге бағытталған, қайтарылатын трафик айқын өңделген. Бұл әр желіге бақылау сатып алады және daemon мен клиент жаңартулары барысында ұстауға тиіс ережелер жиынтығын қымбатқа түсіреді.
Қалай болғанда да, маңызды сынақ — істен шығу жағдайы. Контейнер сұрауы ұшу үстінде тұрғанда туннельді тоқтатыңыз және пакеттің қайда кететінін қараңыз. Егер ол тікелей жолға қайта оралса, қамту ешқашан орындалмаған, себебі клиенттің kill switch-і клиенттің өз трафигін басқарады, көпірден жіберілетін пакеттерді емес. Содан кейін daemon мен хостты қайта іске қосып, нәтижені екінші рет растаңыз; қолмен жазылған ережелер жоғалатын дәл сол сәт.
Оны аяқталды деп атамас бұрын төрт нәрсені растаңыз: туннель интерфейсі трафикпен бір атаулар кеңістігінде, контейнер сынағы нақты контейнердің ішінде өтті, аттарды шешу және екі мекенжай тобы тексерілді, және туннельдің істен шығу сынағы әлі де жабық түрде сәтсіз аяқталады. Содан кейін firewall backend, клиент нұсқасы және әр ереженің иесін жазыңыз. Дәл осы жазба келесі жаңартудың ескі болжамдардың құжатталмаған қоспасын қалдыруына жол бермейді.