Docker rootless რეჟიმი: sudo ქრება, მაგრამ 80 და 443 რთულდება

|ავტორი: QUASA-ს სარედაქციო გუნდი|5 წთ საკითხავი
Docker rootless რეჟიმი: sudo ქრება, მაგრამ 80 და 443 რთულდება

Docker-ის rootless ინსტრუქცია აღწერს daemon-ისა და კონტეინერების ჩვეულებრივი მომხმარებლის namespace-ში გაშვებას და მოითხოვს newuidmap-ს, newgidmap-სა და მომხმარებლისთვის სულ მცირე 65 536 subordinate UID/GID-ს. დაყენების შემდეგ ყოველდღიურ docker ბრძანებებს sudo აღარ სჭირდება, თუმცა პაკეტებისა და სისტემური სერვისების შეცვლა კვლავ ადმინისტრატორის საქმეა. გადასვლის თანმიმდევრობაა წინაპირობების შემოწმება, ძველი daemon-ის გაჩერება, სამიზნე ანგარიშით დაყენება და CLI-ის კავშირის გადამოწმება.

Docker-ის rootless შეზღუდვების აღწერით, ჰოსტის 80 და 443 პორტების პირდაპირი გამოქვეყნება ნაგულისხმევად ფერხდება, რადგან ისინი 1024-ზე დაბალია; რესურსების cgroup v2 კონტროლს კი systemd სჭირდება. ვებსერვისისთვის წინასწარ აირჩიეთ მაღალი ჰოსტის პორტი და მასთან მომუშავე reverse proxy, ან დაგეგმეთ დაბალ პორტზე მიბმის უფლების მიზნობრივი შეცვლა. იმავე გადაწყვეტილებამდე შეამოწმეთ, ეყრდნობა თუ არა სამუშაო დატვირთვა overlay ქსელს ან ძველ volume-ში შენახულ მონაცემებს.

ჰოსტის წინასწარი შემოწმება

ჯერ ჩაიწერეთ მოქმედი გარემო: sudo docker ps -a, sudo docker network ls და sudo docker volume ls. ცალკე შეინახეთ კონტეინერების გაშვების პარამეტრები, bind mount-ების მისამართები და მონაცემების სარეზერვო ასლის აღდგენის წესი. ახალი daemon საკუთარ საცავს იყენებს, ამიტომ ძველი კონტეინერები და named volume-ები მის სიაში ავტომატურად არ გამოჩნდება.

  • ბრძანება command -v newuidmap newgidmap ორივე პროგრამის გზას უნდა აბრუნებდეს. შემდეგ grep "^$(id -un):" /etc/subuid /etc/subgid-ით შეამოწმეთ, აქვს თუ არა სამიზნე ანგარიშს ორივე ფაილში საკმარისი დიაპაზონი. სხვა ანგარიშისთვის უკვე გამოყოფილი დიაპაზონი ხელახლა არ გამოიყენოთ.
  • გაუშვით uname -r და stat -fc %T /sys/fs/cgroup. rootless რეჟიმში overlay2-ს ბირთვის 5.11 ან ახალი ვერსია სჭირდება; fuse-overlayfs-ისთვის საჭიროა თავსებადი ბირთვი და დაყენებული პროგრამა. პასუხი cgroup2fs მიუთითებს cgroup v2-ზე, მაგრამ კონტროლერების ხელმისაწვდომობა მოგვიანებით ცალკე მოწმდება.
  • მონიშნეთ სერვისები, რომლებსაც ჰოსტის დაბალი პორტი, მრავალჰოსტიანი overlay ქსელი, CPU-ს ან მეხსიერების მკაცრი ლიმიტი სჭირდებათ. თითოეულისთვის გადასვლის გზა მომსახურების გაჩერებამდე განსაზღვრეთ.

დაყენება სამიზნე ანგარიშით

  1. თუ დამხმარე პროგრამები აკლია, Debian-სა და Ubuntu-ზე ადმინისტრატორმა დააყენოს uidmap, dbus-user-session და docker-ce-rootless-extras. მაგალითად: sudo apt-get install uidmap dbus-user-session docker-ce-rootless-extras. შემდეგ command -v dockerd-rootless-setuptool.sh-ით გადაამოწმეთ დაყენების ინსტრუმენტი. სხვა დისტრიბუციაზე პაკეტების სახელები შესაბამის რეპოზიტორიაში შეამოწმეთ.
  2. თუ /etc/subuid ან /etc/subgid-ში ჩანაწერი არ არის, ადმინისტრატორმა გამოყოს თავისუფალი დიაპაზონები. პირობითი მაგალითი, მხოლოდ მაშინ, როცა ორივე დიაპაზონი დაუკავებელია: sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 USERNAME. USERNAME სამიზნე ანგარიშით შეცვალეთ და ჩანაწერები კვლავ grep-ით ნახეთ.
  3. დაგეგმილი შეწყვეტისას გააჩერეთ სისტემური სერვისი: sudo systemctl disable --now docker.service docker.socket. ამით ძველი კონტეინერებიც გაჩერდება; მათი rootless daemon-ზე ხელახლა გაშვება ცალკე სამუშაოა. გადაამოწმეთ, რომ სისტემური socket აქტიური აღარ არის.
  4. სამიზნე ანგარიშში ჩვეულებრივი login სესიით შედით და sudo-ს გარეშე გაუშვით dockerd-rootless-setuptool.sh install. ინსტრუმენტმა უნდა შექმნას მომხმარებლის docker.service და rootless CLI context. თუ systemctl --user სესიას ვერ უკავშირდება, შეამოწმეთ login სესია და dbus-user-session.
  5. გაუშვით systemctl --user enable --now docker და შემდეგ sudo loginctl enable-linger "$(id -un)". პასუხი loginctl show-user "$(id -un)" --property=Linger უნდა იყოს Linger=yes: ასე მომხმარებლის სერვისი logout-ის შემდეგაც შეძლებს მუშაობას.

თუ CLI კვლავ ძველ socket-ს მიმართავს, ნახეთ docker context ls და DOCKER_HOST-ის მნიშვნელობა. სხვა მისამართზე დაყენებულმა DOCKER_HOST-მა შეიძლება არჩეულ context-ს გადააჭარბოს; ასეთ შემთხვევაში გაუშვით unset DOCKER_HOST და docker context use rootless. ეს ცვლილება იმავე shell-ში მომდევნო ბრძანებებზეც გავრცელდება.

UID/GID რუკისა და ლიმიტების შემოწმება

ჯერ გაუშვით docker info. Server-ის Security Options-ში rootless უნდა ჩანდეს; Docker Root Dir ჩვეულებრივ მომხმარებლის ~/.local/share/docker დირექტორიაზე მიუთითებს. მხოლოდ sudo-ს გარეშე შესრულებული docker ბრძანება საკმარისი შემოწმება არ არის, რადგან მომხმარებელს rootful daemon-ის socket-ზეც შეიძლება ჰქონდეს წვდომა.

Stack Harbor-ის UID რუკის შემოწმების მაგალითი აერთიანებს dockerd პროცესის მფლობელის, /proc/PID/uid_map-ისა და bind mount-ში შექმნილი ფაილის შემოწმებას. იპოვეთ სწორედ სამიზნე მომხმარებლის dockerd: pgrep -u "$(id -u)" -x dockerd; არჩეული PID-ით წაიკითხეთ cat /proc/PID/uid_map. პირველ ჩანაწერში namespace-ის UID 0 ჰოსტის ამ მომხმარებლის UID-ს უნდა შეესაბამებოდეს, მომდევნოში კი subordinate დიაპაზონი გამოჩნდება. თუ რამდენიმე PID დაბრუნდა, ps-ით გადაამოწმეთ, რომელი პროცესი ეკუთვნის შესამოწმებელ სერვისს.

ფაილის მფლობელობას ცალკეც შეამოწმებთ: შექმენით mkdir -p "$HOME/rootless-probe", გაუშვით docker run --rm -v "$HOME/rootless-probe:/data" alpine touch /data/from-container და ნახეთ ls -ln "$HOME/rootless-probe". ამ პირობით შემოწმებაში კონტეინერის root-ის შექმნილი ფაილი ჰოსტზე სამიზნე მომხმარებლის UID-ით უნდა ჩანდეს. თუ შედეგი განსხვავდება, აპლიკაციის volume-ების უფლებებზე გადასვლამდე UID/GID რუკა გამოიკვლიეთ.

რესურსების ლიმიტისთვის docker info-ში Cgroup Driver შეამოწმეთ. მნიშვნელობა systemd აუცილებელი წინაპირობაა; none-ის შემთხვევაში cgroup-თან დაკავშირებული docker run პარამეტრები შეიძლება უგულებელყოფილი დარჩეს. შემდეგ cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers აჩვენებს, რომელი კონტროლერები გადაეცა მომხმარებლის სერვისს. თუ workload-ს CPU-ის ლიმიტი სჭირდება, მხოლოდ memory-ის არსებობა საკმარისი არ არის: საჭიროა cpu კონტროლერიც და მისი მოქმედების ცალკე შემოწმება.

რა მოითხოვს ცალკე გადაწყვეტილებას

  • თუ ვებსერვისი საჯარო დაბალ პორტზე უნდა ჩანდეს, rootless კონტეინერი ჯერ მაღალ ჰოსტის პორტზე გამოაქვეყნეთ და მოთხოვნები reverse proxy-დან ან load balancer-იდან გადააგზავნეთ. პირდაპირი მიბმის აუცილებლობისას ადმინისტრატორს შეუძლია rootlesskit პროგრამას CAP_NET_BIND_SERVICE მიანიჭოს და მომხმარებლის docker.service გადატვირთოს. net.ipv4.ip_unprivileged_port_start-ის შემცირებაც შესაძლებელია, მაგრამ ის ჰოსტზე პორტებზე წვდომის საერთო წესს ცვლის.
  • თუ CPU-სა და მეხსიერების ლიმიტები სავალდებულოა, cgroup v2-სა და systemd-თან ერთად შესაბამისი delegated controller-ებიც მოითხოვეთ. დაკარგული კონტროლერისთვის systemd-ის [email protected] კონფიგურაცია უნდა გასწორდეს, რის შემდეგაც მომხმარებლის ახალი სესიიდან გადაამოწმეთ შედეგი. მანამდე ლიმიტი მოქმედად არ ჩათვალოთ მხოლოდ იმიტომ, რომ Docker-მა ბრძანება მიიღო.
  • თუ აპლიკაცია Docker-ის მრავალჰოსტიან overlay network-ს ეყრდნობა, ეს ქსელი rootless რეჟიმში მხარდაჭერილი არ არის. დატვირთვას სხვა ქსელური არქიტექტურა ან მისთვის თავსებადი daemon სჭირდება. საცავის overlay2 დრაივერი სხვა ფუნქციაა: მისი ხელმისაწვდომობა overlay ქსელის შეზღუდვას არ ხსნის.
  • თუ მონაცემები ძველ named volume-შია, შექმენით აპლიკაციისთვის ვარგისი სარეზერვო ასლი და აღადგინეთ იგი ახალი daemon-ის volume-ში. გადართვამდე შეამოწმეთ ფაილების მფლობელობა და აპლიკაციის წვდომა. bind mount-ის შემთხვევაში გზა შეიძლება იგივე დარჩეს, მაგრამ სამიზნე მომხმარებელს ჰოსტის დირექტორიაზე საჭირო უფლება უნდა ჰქონდეს.

უკან დაბრუნება

გადართვამდე შეინახეთ ძველი კონტეინერების გაშვების კონფიგურაცია და მონაცემების აღდგენის გზა. თუ შემოწმება ვერ გაიარა, სამიზნე ანგარიშით შეაჩერეთ rootless daemon: systemctl --user disable --now docker. შემდეგ გააუქმეთ DOCKER_HOST, აირჩიეთ docker context use default და ადმინისტრატორის უფლებებით ხელახლა ჩართეთ docker.service და docker.socket.

ძველი და ახალი daemon-ების საცავები ავტომატურად არ ერთიანდება. თუ აპლიკაციამ rootless გარემოში უკვე ჩაწერა ახალი მონაცემები, ძველი სერვისის ჩართვამდე გადაწყვიტეთ, როგორ გადაიტანთ ამ ცვლილებებს უკან; მხოლოდ context-ის შეცვლა მონაცემებს არ აბრუნებს.

ასევე წაიკითხეთ:

გაზიარება:

გამოიწერეთ ჩვენი ბიულეტენი

მიიღეთ უახლესი ამბები Web3-ის, AI-სა და კრიპტოს შესახებ პირდაპირ თქვენს ელფოსტაზე.

0