Այս խնդրի գրեթե բոլոր նկարագրությունները մեղադրում են ծավալը, և հենց դրա պատճառով ուղղումը այդքան երկար է տևում։ Դուք ունեիք աշխատող bind mount, կորպորատիվ VPN-ը միացավ, և docker compose up այժմ ձախողվում է բացակայող աղբյուրի ուղով, դատարկ պանակով կամ միացմամբ, որը շարժիչը հրաժարվում է ստեղծել։ Այն միջավայրերում, որոնք ես մաքրել եմ, Compose ֆայլը չէր փոխվել, և ուղին ճիշտ էր։ Փոխվել էր այն, թե որ դեմոնը ստացավ հարցումը, և միացման սխալը պարզապես առաջին տեղն էր, որտեղ այդ տարբերությունը տեսանելի դարձավ։

Ծավալը երբեք չշարժվեց. հարցումը շարժվեց

Այն -v /srv/app:/app դրոշակը պանակի պատճեն չէ, որ կատարում է ձեր shell-ը։ Հաճախորդն այն վերածում է API հարցման, և պատասխանող դեմոնը լուծում է /srv/app ը իր սեփական ֆայլային համակարգի նկատմամբ։ Երբ երկու կողմերն աշխատում են նույն միջուկում, այդ ուղին այն է, ինչ տեսնում եք ֆայլերի կառավարչում։ Երբ endpoint-ը փոխվում է, նույն տողը որոնվում է մի մեքենայում, որը երբեք չի լսել ձեր նախագծի պանակի մասին, և դեմոնը կամ աղբյուրը բացակայող է հայտարարում, կամ լուռ դրա փոխարեն դատարկ պանակ ստեղծում։

Սա է նաև պատճառը, որ անվանված ծավալը շարունակում է աշխատել, իսկ bind mount-ը՝ ոչ։ -v appdata:/app ը անվանում է պահոց, որը պատկանում է դեմոնին, ուստի ոչ մի հոսթի ուղ պետք չէ գոյություն ունենալ որոշակի տեղում։ Եթե մի ծառայություն bind mount-ից անվանված ծավալի փոխելը վերացնում է սխալը, դուք խնդիրը չեք լուծել։ Դուք հաստատել եք, որ հաճախորդն ու դեմոնը համաձայն չեն, թե որ ֆայլային համակարգին է պատկանում ուղին, և այդ տարաձայնությունը վերադառնում է այն պահին, երբ նորից իրական հոսթի պանակ է պետք։

Տպեք endpoint-ը նախքան միացմանը դիպչելը

Մի քանի կարգավորում կարող են հաճախորդին ուղղել դեպի endpoint, և դրանք միշտ չեն համաձայնում. --context դրոշակը, DOCKER_CONTEXT, DOCKER_HOST ընթացիկ shell-ում, և հաճախորդի կազմաձևում պահված կոնտեքստը։ Առաջնահերթության մասին մտածելու փոխարեն տպեք բոլորը և համեմատեք պատասխանները։

docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"

Հաճախորդի կազմաձևը գտնվում է ~/.docker/config.json ում Linux-ում և macOS-ում և %USERPROFILE%\.docker\config.json ում Windows-ում, և ընթացիկ տերմինալում արտահանված արժեքը փոխարինում է պահվածը միայն այդ սեսիայի համար։ Եթե endpoint-ը հոսթի անուն է, այլ ոչ տեղական socket, ապա անվան լուծումը և երթուղիներն են որոշում, թե որտեղ այն կիջնի, և հենց դրանք է վերագրում VPN հաճախորդը։ Թունելը, որը ավելացնում է երթուղի կամ փոխում է լուծիչը, կարող է ուղարկել մի անուն, որ նախկինում նշանակում էր այս նոթբուքը, կորպորատիվ ցանցի ներսում գտնվող հասցեին։

Համեմատեք վիճակը, ոչ թե կազմաձևը։ Գործարկեք docker ps -a և docker images թունելը փակ վիճակում, ապա նորից բաց վիճակում։ Կոնտեյներների տարբեր ցանկն ավելի ուժեղ ապացույց է, քան ցանկացած կազմաձևի ֆայլ, որովհետև ցույց է տալիս, որ ձեր հարցմանը պատասխանել է այլ դեմոն։

Հարցրեք դեմոնին՝ արդյոք ուղին այնտեղ գոյություն ունի

Երբ իմանաք, թե որ դեմոնին եք հասել, թող նա նայի պանակին։ --mount ձևը ձախողվում է ավելի պարզ հաղորդագրությամբ, քան կարճ դրոշակը, որովհետև այն ստուգում է աղբյուրը նախքան կոնտեյները գործարկելը.

docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app

Եթե այն աղբյուրը բացակայող է հայտարարում, ստեղծեք այն այն մեքենայում, որը պատասխանել է, կամ ծառայությունը ուղղեք անվանված ծավալի և տվյալները պատճենեք այնտեղ։ Ինչ չպետք է անեք՝ ծավալները վերստեղծել և շարժիչը վերատեղադրել այս ստուգումից առաջ։ Այդ գործողությունները բավականաչափ փոխում են միջավայրը, որպեսզի թաքցնեն անհամապատասխանությունը՝ թողնելով այն տեղում։

Եվս մեկ ուղ անցնում է բոլորովին այլ տեղ. image-ի ներբեռնումը դեմոնի աշխատանք է, ոչ հաճախորդի։ Հաջող ներբեռնումը միայն ապացուցում է, որ դեմոնը կարող է հասնել registry-ին, իսկ աշխատող bind mount-ը՝ միայն որ ուղին լուծվել է։ Ստուգեք յուրաքանչյուր ուղ այնտեղ, որտեղ այն իրականում կատարվում է, այլապես կեսօրը կանցկացնեք սխալի վրա։

Ինտրանետի անունները ձախողվում են այլ պատճառով

Նույն հաշվետվության երկրորդ կեսը սովորաբար այն է, որ կոնտեյները չի կարողանում հասնել intranet.corp.exampleին։ Դա առանձին մեխանիզմ է, ոչ երկրորդ ծավալի խնդիր։ Կոնտեյները ստանում է իր /etc/resolv.conf ը գործարկվելիս՝ գեներացված դեմոնի լուծիչի կարգավորումներից, ուստի DNS սերվերը, որը VPN-ն ավելացրել է կոնտեյները ստեղծելուց հետո, այնտեղ չի հայտնվի, մինչև կոնտեյները նորից չստեղծվի։

Docker-ի ներկառուցված լուծիչը օգտատիրոջ կողմից սահմանված ցանցում արտաքին հարցումները փոխանցում է հոսթի կարգավորված սերվերներին, ինչը օգնում է, երբ VPN-ը վերագրում է հոսթի լուծիչը, և վնասում է, երբ split DNS-ը ներքին գոտին ուղարկում է մի սերվերի, որը դեմոնն այլևս չի տեսնում։ Նեղ, բացահայտ քարտեզագրումը շրջանցում է վեճը այն անունների համար, որոնք երբեք չեն փոխվում.

services:
  web:
    extra_hosts:
      - "intranet.corp.example:10.20.30.40"

Սա գրառում է ավելացնում կոնտեյների hosts ֆայլում, ուստի կոնտեյները ոչինչ չի իմանում թունելի մասին, և այն նաև սառեցնում է հասցեն։ Երբ ներքին հոսթը տեղափոխվում է, գրառումը մնում է սխալ, մինչև ինչ-որ մեկը խմբագրի Compose ֆայլը։ Օգտագործեք այն ֆիքսված սարքի կամ ամրացված տվյալների բազայի համար, և շարժվող անունները թողեք DNS-ին։

Ինչ է իրականում փոխում վերատեղադրումը

Docker Desktop-ի վերատեղադրումը վերստեղծում է VM-ը, socket-ը և կոնտեքստների ցանկը, և միացումը նորից սկսում է աշխատել։ Այդ արդյունքն իրական է և ոչինչ չի սովորեցնում, դրա համար էլ նույն խափանումը վերադառնում է հաջորդ VPN թարմացումից հետո։ Վերատեղադրումը փոխարինեց այն endpoint-ը, որն օգտագործում էր հաճախորդը. այն չհամաձայնեցրեց ձեր նախագծի անվանած ուղին այն ֆայլային համակարգի հետ, որը դեմոնն իրականում կարդում է։

Իմ աշխատանքի հերթականությունը կարճ է։ Հաստատեք, թե որ endpoint-ն է օգտագործելու հաճախորդը։ Համեմատելով կոնտեյներների ցանկերը՝ հաստատեք, թե որ դեմոնն է պատասխանել։ Խնդրեք այդ դեմոնին թվարկել աղբյուրի ուղին։ Միայն դրանից հետո խմբագրեք միացումը, ավելացրեք hosts գրառում կամ փոխեք ծավալի տեսակը։ Եթե Compose ֆայլը պահպանում եք VPN-ով աշխատող թիմի համար, նախընտրեք անվանված ծավալներ այն տվյալների համար, որոնք պետք է պատկանեն դեմոնին, որպեսզի հոսթի ուղը երբեք պայմանագրի մաս չդառնա։

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