Docker-ის მოცულობის მიმაგრება VPN-ის დაკავშირების შემდეგ ვერ ხერხდება: შეამოწმეთ დემონი
თქვენი bind mount რიგზეა. VPN ცვლის, რომელი დემონი პასუხობს კლიენტს, ამიტომ დაბეჭდეთ endpoint, დაამტკიცეთ გზა იქ და შეწყვიტეთ მოცულობის რედაქტირება.
ამ პრობლემის თითქმის ყველა აღწერა მოცულობას ადანაშაულებს და სწორედ ამიტომ გრძელდება გამოსწორება ასე დიდხანს. გქონდათ მომუშავე 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 ჰოსტის რეზოლვერს გადაწერს, და ზიანს აყენებს, როცა გაყოფილი 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-ით მუშაობს, უპირატესობა მიანიჭეთ დასახელებულ მოცულობებს იმ მონაცემებისთვის, რომლებიც დემონს უნდა ეკუთვნოდეს, რათა ჰოსტის გზა არასდროს გახდეს ხელშეკრულების ნაწილი.