Ձեր Compose ծառայությունը ժամկետանցվում է այն API-ի դիմաց, որը նույն մեքենայի բրաուզերը բացում է առանց բողոքելու։ Այդ տարբերությունն է հուշումը. աշխատող հարցումը դուրս է գալիս VPN թունելով հոսթից, իսկ կախված հարցումը՝ սեփական ցանցային կույտով կոնտեյներից։ Կոնտեյների ներսում ոչինչ չգիտի թունելի երթուղիները, ուստի մասնավոր նպատակակետը մնում է անհասանելի, ինչպես էլ գրվի անունը։ Լուծումը հոսթի միջով դիտավորյալ ցատկ է, ոչ թե ավելի խելացի երթուղային աղյուսակ։

Սկսեք նրանից, թե ինչու են երկու ուղիները տարբեր, ապա որոշեք, թե որտեղ պետք է ապրի թունելը։

Ինչու է հոսթն աշխատում, իսկ կոնտեյները՝ ոչ

Թունելը վեր բարձրացնելը հոսթին տալիս է ինտերֆեյս, երթուղիների հավաքածու և սովորաբար VPN-ի տրամադրած լուծիչի գրառում։ Կոնտեյները դրանից ոչինչ չի ժառանգում. այն սկսում է մեկ ինտերֆեյսով շարժիչի կամրջի վրա և լռելյայն երթուղով, որը ցույց է տալիս այդ կամուրջին։ Հոսթի վրա տեղադրված երթուղիները անտեսանելի են այդ անվանատարածքի ներսում աշխատող ամեն ինչի համար։

Այդ պատճառով ախտանիշները անհամապատասխան են թվում, այլ ոչ թե պարզապես կոտրված։ Հոսթը լուծում է մասնավոր անունը և միանում, որովհետև այնտեղ կան և՛ անունը, և՛ երթուղին։ Կոնտեյները իր փաթեթը ուղարկում է մասնավոր հասցե, ուր ոչինչ չի կարող հասնել կամրջի ճանապարհով, և հարցումը ժամկետանցվում է։ Անունը կոնտեյների hosts ֆայլին ավելացնելը ոչինչ չի փոխում, որովհետև հասցեն ինքնին անհասանելի է այնտեղից, որտեղ նստած է կոնտեյները։

Հասեք հոսթին կոնտեյների ներսից

Կոնտեյների ներսում գործընթացը, որը զանգահարում է localhost, զանգահարում է կոնտեյնին։ Docker Desktop-ը հրապարակում է host.docker.internal անունը, որը հետ է ցույց տալիս շարժիչը վարող մեքենային. Linux շարժիչները այն թողնում են չսահմանված, եթե ծառայությունը չի խնդրում, և հենց դա է անում ներքևի քարտեզագրումը։ Դրանով հավելվածը թիրախավորում է անուն և պորտ՝ մասնավոր հասցեի փոխարեն։

services:
  app:
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      INTERNAL_API_HOST: "host.docker.internal:8666"

Թունելը մնում է ցատկի հոսթի կողմում, և այդ փոփոխականի պորտը այն է, որի վրա պրոքսին կլսի։ Թունելը կորցրած կոնտեյներն այժմ ձախողվում է մեկ հայտնի ցատկի վրա՝ փորձելու փոխարեն երթուղի, որը երբեք չի ունեցել։

Ընտրեք, թե որտեղ է ապրում թունելը

Մասնավոր API-ի կարիք ունեցող Compose ծառայության համար հնարավոր են երեք ձևեր, և դրանք տարբերվում են նրանով, թե որ գործընթացն է տիրապետում թունելին։ VPN հաճախորդը կարող է աշխատել կոնտեյների պատկերի ներսում, ինչը պահանջում է թունելի սարքի բացահայտում և դրա հետ եկող ցանցային կառավարման հնարավորության տրամադրում։ Հավելվածը կարող է կիսել առանձին թունել-կոնտեյների ցանցային անվանատարածքը, այնպես որ երկու գործընթացներն էլ տեսնեն մեկ կույտ և մեկ երթուղային աղյուսակ։ Կամ թունելը կարող է մնալ հոսթի վրա՝ հոսթից կոնտեյներ նեղ փոխանցիչով։

Առաջին երկուսը պրոֆիլային ֆայլեր, վերամիացման վարք և լուծիչի քաղաքականություն են քաշում նախագծի մեջ և ֆայլի յուրաքանչյուր ծառայություն կախված են դարձնում թունելի առողջությունից։ Սա մեկ API կանչի համար չափազանց շատ կապ է։ Մեկ ներքին վերջնակետ կարդացող զարգացման կույտի համար հոսթի կողմի փոխանցիչը ամենափոքր փոփոխությունն է, որը դեռ պահում է հավատարմագրերը այնտեղ, որտեղ պլատֆորմի թիմը կառավարում է դրանք։

Հրապարակեք մեկ նեղ ուղի հոսթի վրա

Սկսեք նրանից, ինչ ժառանգում է փոխանցիչը. գործարկեք այն հաշվով, որը տիրապետում է թունելին, և նրա ելքային սոքեթները կվերցնեն հոսթի երթուղիները և հոսթի լուծիչը։ nginx-ի մեկ location բլոկը ծածկում է մեկ ուղի։

server {
    listen 8666;
    location /search/ {
        proxy_pass http://10.20.30.40:8090/;
        proxy_set_header Host internal-api.example;
        proxy_read_timeout 60s;
    }
}

Վերաբերվեք հասցեին և պորտին որպես ժամանակավոր փոխարինողների և դրեք այն զույգը, որի վրա API-ն իրականում լսում է։ Յուրաքանչյուր լրացուցիչ upstream արժանի է իր location բլոկին, և յուրաքանչյուր բլոկ պետք է թույլ տա միայն այն ուղիները, որոնք այս ծառայությունը կանչում է, որպեսզի պրոքսին չդառնա մասնավոր ցանցի ընդհանուր դուռ։ Կապեք լսողին կամրջի հասցեին host-gateway-ով եկող հաճախորդների համար, loopback-ին միայն այն դեպքում, երբ հաճախորդը կիսում է հոսթի ցանցային անվանատարածքը, և երբեք 0.0.0.0-ին։ Ընտրեք նաև դեռ ազատ պորտ. արդեն զբաղեցված համարը թողնում է պրոքսին չլսող, մինչ կոնտեյները շարունակում է ժամկետանցվել, ինչը չի տարբերվում այն ցանցային խափանումից, որով սկսել էիք։

Պորտեր, անուններ և TLS որոշումը

Անունների լուծումը բաժանվում է այնպես, ինչպես երթուղավորումը։ Կոնտեյների հանրային հարցումներն անցնում են շարժիչի լուծիչով, ուստի հոսթի վրա լուծվող մասնավոր անունը կոնտեյների ներսում չի լուծվի։ Պրոքսին այն բաղադրիչն է, որը լուծում է մասնավոր անունը, որովհետև ժառանգում է հոսթի լուծիչը։

TLS-ը որոշումն է, որը հետաձգվում է և հետո բացատրում հաջորդ ձախողումը։ Եթե պրոքսին բայթերը փոխանցում է անձեռնմխելի, կոնտեյները տեսնում է API-ի սեփական վկայագիրը և կարիք ունի ներքին CA-ի իր վստահության պահոցում։ Եթե պրոքսին ավարտում է TLS-ը, այդ վստահությունը տեղափոխվում է հոսթ, և հավելվածը սկսում է հղումներ կառուցել ստացված host վերնագրից։ Ընտրեք մեկ դասավորություն և կիրառեք այն յուրաքանչյուր ռեսուրսի վրա, որովհետև մյուսի տրամադրած վերահղումը ցույց է տալիս հոսթի անուն, որը կոնտեյները չի կարող լուծել։

Ստուգեք ծառայության ներսից

Ուղարկեք հարցումը կոնտեյներից, ոչ հոսթից. սովորական curl պրոքսի ուղու վրա, ապա հավելվածի սեփական առողջության ստուգումը։ Երբ պրոքսին պատասխանում է, բայց հավելվածը դեռ ձախողվում է, համեմատեք երեք բան. այն բազային URL-ը, որը նա կառուցում է, նրա միջավայրում ցանկացած պրոքսի փոփոխական, և այն CA-ն, որին վստահում է։ Բոլորը գտնվում են կոնտեյների միջավայրում և մատյաններում, և դրանցից ցանկացածի ուղղումը VPN-ին անվնաս է թողնում։

Գրեք ընտրված դասավորությունը նախագծի README-ում, քանի դեռ այն թարմ է։ Հակառակ դեպքում հաջորդ մարդը, ով կհանդիպի այս ժամկետանցմանը, նույն կեսօրն կանցկացնի նորից բացահայտելով, որ թունելն ապրում է հոսթի վրա։

Առնչվող հոդվածներ