Ինչու Docker կոնտեյները չի հասնում VPN-ի հետևի հոսթերին
Կամուրջ կոնտեյներներն ունեն իրենց անվանատարածքը, ուստի հոսթի թունելը նրանց համար անտեսանելի է։ Նախքան DNS-ը փոխելը համեմատեք հոսթի ցանցը, tun սարքը և macvlan-ը։
Կոնտեյները, որը ոչնչի չի հասնում կորպորատիվ VPN-ի հետևում, սովորաբար ապրում է թունելից տարբերվող ցանցային անվանատարածքում։ Հոսթի հաճախորդի երթուղիները, DNS սերվերները և ֆայրվոլի նշանները պատկանում են հոսթի սթեքին. կամուրջ ցանցի կոնտեյներն ունի իր սեփականը։ Այս մեկ փաստը բացատրում է պլատֆորմի թիմին հասնող հաշվետվությունների մեծ մասը, և դա է նաև պատճառը, որ «VPN-ը կոտրված է» և «Docker-ը շրջանցում է VPN-ը» կարող են միաժամանակ սխալ լինել։ Մեկ ախտանիշի հետևում թաքնված են երկու շատ տարբեր կարգավորումներ, ուստի պարզեք, թե որն ունեք, նախքան որևէ կարգավորում փոխելը։
Պարզեք, թե ում անվանատարածքին է պատկանում թունելը
macOS-ի կամ Windows-ի Docker Desktop-ում կոնտեյներները աշխատում են Linux վիրտուալ մեքենայի ներսում։ Աշխատանքային սեղանին տեղադրված VPN հաճախորդը թունել է ստեղծում աշխատանքային սեղանի օպերացիոն համակարգում, և վիրտուալ մեքենան երբեք չի տեսնում այն։ Ոչ մի կոնտեյների կարգավորում չի ուղղում դա, քանի որ այն ինտերֆեյսը, որը կոնտեյներին պետք կլիներ, ընդհանրապես գոյություն չունի նրա ցանցային անվանատարածքում։
Linux հոսթում թունելը ապրում է հոսթի անվանատարածքում, և կամուրջ կոնտեյներները սովորաբար հասնում են դրան հոսթի երթուղային աղյուսակի միջոցով՝ ելքի վրա կիրառված աղբյուրի NAT-ով։ Երբ այդ ուղին ձախողվում է, պատճառը սովորաբար փոխանցման քաղաքականությունը, հակադարձ ուղու զտումը կամ համընկնող ենթացանցը է, այլ ոչ թե բացակայող երթուղին։ Հաստատեք, թե երկու աշխարհներից որում եք, նախքան հետագա ընթերցելը:
docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5
Այդ երկու երթուղային աղյուսակների տարբերությունը մեկ էկրանում ամբողջ խնդիրն է։ Եթե հոսթի տեսքը պարունակում է թունելի ինտերֆեյսը, իսկ կամրջի տեսքը՝ ոչ, դուք տեսնում եք անվանատարածքների մեկուսացում, և մնացած ամեն ինչ ընտրություն է, թե ինչպես անցնել այն։
Հոսթի ցանցը փորձարկում է, ոչ թե ձևավորում
Կոնտեյները հոսթի ցանցով գործարկելը, որը Docker-ը փաստաթղթավորում է որպես հոսթի ցանցային անվանատարածքի համօգտագործում, ստիպում է նրան ուղղակիորեն ժառանգել թունելի ինտերֆեյսը և դրա երթուղիները։ Եթե նույն հարցումը դրանից հետո հաջողվի, երթուղիների տեսությունը հաստատված է, և ձախողումը անվանատարածքների մեկուսացում է, ոչ թե հավատարմագրեր, DNS կամ մուտքի կանոն։
docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health
Պահեք այն որպես ախտորոշում։ Հոսթի ցանցը հրաժարվում է պորտի հրապարակումից և այն մեկուսացման մեծ մասից, որը դուք ուզում էիք կոնտեյներից, և Docker Desktop-ում «host»-ը նշանակում է վիրտուալ մեքենա, ոչ թե աշխատանքային սեղան, ուստի այնտեղ հաջողությունը կամ ձախողումը կարող է մոլորեցնել ձեզ, եթե մոռանաք, թե որ հոսթին էիք դիմում։
tun սարքը և դրա հետ եկող արտոնությունները
Կոնտեյների ներսում VPN հաճախորդին պետք է թունելի սարք և դրա կարգավորման թույլտվություն։ Սովորական կրճատումը --privileged է, որը տալիս է բոլոր սարքերը և թուլացնում անվտանգության քաղաքականությունը ամբողջ կոնտեյներում։ Դա շատ ավելին է, քան այս աշխատանքը պահանջում է, և դժվար է արդարացնել վերանայման ժամանակ։
sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client
Ավելի նեղ ձևը քարտեզագրում է մեկ սարքի հանգույցը և ավելացնում միայն ցանցի կառավարման հնարավորությունը։ Նախ բեռնեք մոդուլը հոսթում, որպեսզի հանգույցը գոյություն ունենա։ Եթե կոնտեյները մեկնարկում է, և հաճախորդը հայտնում է, որ չի կարող բացել թունելի սարքը, ստուգեք քարտեզագրումը նախքան պրոֆիլին կասկածելը, քանի որ այդ սխալը սովորաբար բառացի է։
Այս ձևավորումը նաև նշանակում է, որ հաճախորդը աշխատում է յուրաքանչյուր կոնտեյների համար։ Սա ճիշտ պատասխանն է, երբ յուրաքանչյուր աշխատանքային բեռի պետք է սեփական թունել, և սխալ պատասխանը, երբ դուք պարզապես ուզում էիք, որ հոսթի թունելը տեսանելի լինի, ինչը պլատֆորմի թիմը հավանաբար ենթադրել էր, որ դուք անում եք։
Կամրջի NAT-ը փոխում է այն աղբյուրը, որը տեսնում է VPN-ը
Լռելյայն կամրջի դեպքում կոնտեյների ելքային երթևեկությունը թարգմանվում է հոսթի հասցեի։ Այսպիսով, VPN-ի հետևում կորպորատիվ կողմը տեսնում է հոսթի թունելի հասցեն, ոչ թե կոնտեյներինը, աղբյուրով պայմանավորված մուտքի կանոնները վարվում են այնպես, կարծես հարցումն ուղարկել է հոսթը, և երկու կոնտեյներ դառնում են անտարբերելի VPN սերվերի համար։
macvlan-ը կամ ipvlan-ը փոխարենը կոնտեյներին տալիս է LAN հասցե, ինչը օգնում է LAN-ում հայտնաբերմանը և կոնտեյները ցույց է տալիս որպես սեգմենտի հավասարը։ Այն նաև ամբողջությամբ շրջանցում է հոսթի թունելը, ուստի նման կոնտեյնը չի հասնի միայն-VPN նախածանցներին, քանի դեռ VPN-ը հասանելի չէ նաև այդ LAN-ից։
Երկու ձևերն էլ օրինական են. դրանք պատասխանում են տարբեր պահանջների։ Եթե պահանջն է «այս կոնտեյնը պետք է հասնի միայն-VPN ծառայության», դուք ընտրում եք հոսթի միջով երթուղավորումը և կոնտեյների ներսում թունելի ավարտը։ Գրեք այդ ընտրությունը տեղակայումից առաջ, ոչ թե առաջին ձախողված հարցումից հետո։ Ինչ էլ ընտրեք, գրանցեք աղբյուրի հասցեն, որը կտեսնի հեռավոր կողմը, քանի որ հենց այն կցուցադրեն նրա մուտքի կանոններն ու մատյանները։ Ձևավորումը, որը չի կարող նշել այդ հասցեն, ավարտված չէ։
DNS-ը հետևում է դեմոնին, ոչ թե թունելին
Կոնտեյնը ստանում է իր լուծիչի կարգավորումը մեկնարկելիս՝ պատճենված դեմոնից կամ պատկերից։ Այն հասցեները, որ VPN-ը հրում է միացումից հետո, շատ ուշ են հասնում այդ պատճենի համար, և դրանք հրում են հոսթի լուծիչին, ոչ թե կոնտեյների մեջ։
Սահմանեք լուծիչը բացահայտ ծառայության համար, կամ ուղղեք այն ներքին լուծիչի, որը հասանելի է թունելի միջոցով։ Կոնտեյնը, որը մասնավոր անունը լուծում է հանրային հասցեի, սովորաբար օգտագործում է հանրային լուծիչ, ոչ թե տուժում է կոտրված երթուղուց, և ուղղումը պատկանում է compose ֆայլին կամ դեմոնի կարգավորմանը։
Նույն տրամաբանությունը վերաբերում է ելքի հասցեի հարցին։ Եթե յուրաքանչյուր կոնտեյն պետք է երևա տարբեր VPN հասցեից, մեկ հոսթի թունել չի կարող դա ապահովել, քանի որ NAT-ը դրանք սեղմում է մեկ աղբյուրի մեջ։ Աշխատունակ ձևերն են յուրաքանչյուր կոնտեյնի անվանատարածքում հաճախորդը կամ sidecar, որը տիրապետում է թունելին և կիսում իր սթեքը, և երկուսն էլ փոխում են, թե ինչպես է հասցեագրվում հավելվածը։
Ստուգաթերթ նախքան տոմսը փակելը. բացահայտեք թունելին տիրացող անվանատարածքը, ապացուցեք ուղին հոսթի ցանցով, քարտեզագրեք միայն անհրաժեշտ tun սարքը, հիշեք աղբյուրի հասցեն NAT-ից հետո, սահմանեք լուծիչը բացահայտ և վերաբերվեք յուրաքանչյուր կոնտեյնի ելքի հասցեներին որպես ճարտարապետական որոշում, ոչ թե դրոշակ։