← ყველა სტატია

„ბირთვების დრეიფი“ აპტაიმის დრეიფი აღმოჩნდა: პატჩები დგებოდა, გადატვირთვა — არა

შვიდ ნოდაზე სამი სხვადასხვა ბირთვი დაუსრულებელ პატჩების ტალღებს ჰგავდა და გამოძიება ცრუ კვალზე წაიყვანა. პატჩები ყველა ნოდაზე ერთნაირი იყო, განსხვავდებოდა მხოლოდ აპტაიმი.

Optimacros-ში შვიდნოდიანი self-managed Kubernetes სამ სხვადასხვა ბირთვზე მუშაობდა. ძველი ინტერპრეტაცია, ჩაწერილი ჩვენს გარემოს ჩანაწერებში, იყო „დაუსრულებელი პატჩების ტალღები“. ყველაზე ძველ ბირთვზე მყოფი ნოდები დაუკავშირებელ ინციდენტში მთავარ ეჭვმიტანილებად ითვლებოდნენ.

ეს ინტერპრეტაცია მცდარი იყო და გამოძიება ცრუ კვალზე წაიყვანა.

რა ხდებოდა სინამდვილეში

პატჩები ყველა ნოდამდე ერთნაირად მივიდა. unattended-upgrades მთელ პარკში ჩართული იყო:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade  "1";

Unattended-Upgrade::Automatic-Reboot მითითებული არ იყო, ნაგულისხმევად კი false-ია. ამიტომ ახალი ბირთვები ყველა ნოდაზე დგებოდა და არასოდეს აქტიურდებოდა. ნოდებს შორის მხოლოდ ბოლო გადატვირთვიდან გასული დრო განსხვავდებოდა:

მომუშავე ბირთვი უახლესი დაყენებული ნოდები აპტაიმი
6.8.0-101 6.8.0-137 3 152 დღე
6.8.0-124 6.8.0-137 2 69 დღე
6.8.0-134 6.8.0-137 2 29 დღე

„დრეიფი“ უბრალოდ ჩანაწერი იყო იმისა, თუ როდის გადაიტვირთა თითოეული ნოდა ბოლოს რაიმე სხვა მიზეზით. libc6 ასევე ყველგან განახლდა, ესე იგი glibc-ის შესწორებები არცერთ მომუშავე პროცესში არ მოქმედებდა და /var/run/reboot-required შვიდივე ნოდაზე იდო.

ორი რამ შემაშფოთებლად გამოიყურებოდა, მაგრამ არ იყო. /boot 11%-ით იყო შევსებული, იქ მხოლოდ ორი ბირთვი იყო, ძველები ავტომატურად იშლებოდა. reboot-required.pkgs კი ბირთვის ათამდე პაკეტს ჩამოთვლიდა, რაც „ათი ბირთვია დაყენებული“-დ იკითხება — სინამდვილეში ეს იმ პაკეტების დაგროვილი ისტორიაა, რომლებიც წინა გადატვირთვის შემდეგ გადატვირთვას ითხოვდნენ.

შემოწმება, რომელიც პასუხობს კითხვას „დაპატჩული ვართ?“

ნოდებს შორის მომუშავე ბირთვების შედარება არასწორი კითხვაა. სწორი კითხვა თითოეული ნოდისთვის ისმება: მომუშავე უახლესი დაყენებულის წინააღმდეგ, პლუს აპტაიმი.

uname -r
ls -1 /boot/vmlinuz-* | sed 's|.*vmlinuz-||' | sort -V | tail -1
awk '{print int($1/86400)}' /proc/uptime
[ -f /var/run/reboot-required ] && echo reboot-required

გამოსწორება

შვიდივე ნოდის რიგრიგობითი გადატვირთვა — drain, გადატვირთვა, uncordon, საცავის ჯანმრთელობის ლოდინი, — შემდეგ კი მეორე გავლა 31 გადადებული სამომხმარებლო განახლებისთვის. ამის შემდეგ ყველა ნოდა 6.8.0-137-ზე მუშაობდა, reboot-required გაქრა, apt-მა კი აჩვენა, რომ განსაახლებელი აღარაფერი დარჩა. kubelet და containerd ხელუხლებელი დარჩა.

გზაში ნაპოვნი ხაფანგები

  • apt-mark showhold ცარიელი იყო. არაფერი იცავდა kubelet-ს, kubeadm-სა და containerd-ს apt upgrade-ისგან. ყოველთვის ჯერ განახლებების სია ნახეთ: გამოპარული Kubernetes კომპონენტი კლასტერს ვერსიების შეუსაბამობით ამტვრევს.
  • kubeconfig პირდაპირ ერთ control-plane ნოდაზე მიუთითებდა, HA ენდპოინტის გარეშე. ამ ნოდის გადატვირთვამ kubectl პროცედურის შუაში გაწყვიტა, თუმცა თავად კლასტერი წესრიგში იყო. control plane-ის HA არ არის მასზე წვდომის HA.
  • პაკეტები „kept back“-ად რჩება უბრალოდ იმიტომ, რომ apt upgrade ახალ დამოკიდებულებებს არ აყენებს. შეამოწმეთ apt-get -s full-upgrade და გააგრძელეთ მხოლოდ მაშინ, თუ ის არაფერს შლის.
  • ნუ ავტომატიზირებთ გადატვირთვებს, სანამ Vault-ს auto-unseal არ აქვს. ყოველი გადატვირთვა, რომელიც Vault-ის პოდს გადაიტანს, მას დალუქულს ტოვებს, ამიტომ ზედამხედველობის გარეშე გადატვირთვები ჩუმ შეფერხებებს ქმნის.

დასკვნები

  • ნოდებზე სხვადასხვა ბირთვი, როგორც წესი, სხვადასხვა აპტაიმს ნიშნავს და არა პატჩების სხვადასხვა დონეს.
  • „დაყენებული“ არ არის „მომუშავე“. პატჩების შესაბამისობა თითოეულ ნოდაზე ამ ორის შედარებაა.
  • unattended upgrades გადატვირთვების გარეშე პატჩინგის პოლიტიკის ნახევარია.
  • ჩაიწერეთ, რაც იცით, და გადახედეთ. გარემოს ჩანაწერებში ერთმა მცდარმა ხაზმა უფრო მეტი დრო წაიღო, ვიდრე თავად გადატვირთვებმა.