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

როგორ განვაახლოთ OS შვიდ Kubernetes ნოდაზე ისე, რომ ვერავინ შეამჩნიოს

Ubuntu-ს რიგრიგობითი განახლება კლასტერში, რომელიც საკუთარ მდგომარეობას თავად ინახავს. წინასწარმა შემოწმებებმა საშიში სამუშაო მოსაწყენად აქცია, ტემპს კი Longhorn კარნახობდა.

ჩემი სახლის ლაბორატორიის კლასტერი შვიდი VM-ია ერთ Proxmox ჰოსტზე, უწყვეტი კვების გარეშე, და ეს შვიდი ნოდა ყველაფერს ინახავს: Longhorn ტომებს, CloudNativePG-ზე Postgres-ს, სამნოდიან Vault-ს Raft-ზე და Cloudflare-ის ორივე გვირაბს, რომლითაც ჩემი საიტებია გამოქვეყნებული. პაკეტები ჩამორჩებოდა და OS-ის განახლება მინდოდა მანამ, სანამ თავად Kubernetes-ს შევეხებოდი. ნოდების განახლება, რომლებზეც მთელი მდგომარეობაა, სარისკოდ ჟღერს. მოსაწყენი ის წინასწარმა შემოწმებამ გახადა.

რა აჩვენა წინასწარმა შემოწმებამ

რამის გაშვებამდე შევამოწმე, რას შეეხებოდა განახლება სინამდვილეში:

  • ბირთვის განახლება არ იყო, ესე იგი გადატვირთვა ბირთვის გამო არ იყო საჭირო.
  • Kubernetes-ის არცერთი კომპონენტი dpkg პაკეტი არ იყო. kubelet, kubeadm, containerd, runc და etcd თავდაპირველმა განთავსების ხელსაწყომ ბინარებად ჩადო /usr/local/bin-ში, Kubernetes-ის apt რეპოზიტორია კი არ არსებობდა. apt მათ ვერ შეეხებოდა, ამიტომ ცარიელი apt-mark showhold აქ პრობლემა არ იყო.
  • 48 პაკეტს შორის არ იყო libc, OpenSSH და systemd-ის ბირთვი.
  • nftables.service გამორთული იყო, ამიტომ nftables პაკეტის განახლება წესების გადატვირთვას და Calico-ს წესების წაშლას ვერ გამოიწვევდა. kube-proxy ისედაც IPVS რეჟიმში მუშაობდა.
  • უსაფრთხოების განახლებები რიგში არ იყო: unattended-upgrades მათ უკვე თავად აყენებდა.

პროცედურა

თითო ნოდა, კანარით დაწყებული. კანარს მოსაწყენობით ვირჩევდი: ვორკერი, რომელზეც მხოლოდ Grafana, ხელსაწყოები და ერთი Longhorn ტომი იყო. ვორკერი Vault-ის პირით, Postgres-ის წევრით, Argo CD-ის კონტროლერითა და ორივე გვირაბის რეპლიკით ვორკერებს შორის ბოლო იყო. Control-plane ნოდები — ყველა ვორკერის შემდეგ.

თითოეული ნოდისთვის: სნეპშოტი Proxmox-ში, kubectl drain, განახლება NEEDRESTART_MODE=l-ით, გადატვირთვა, სანამ ნოდა ჯერ კიდევ გამოყვანილია, uncordon და ყველაზე მთავარი — დაელოდო, სანამ ყველა Longhorn ტომი healthy გახდება, და მხოლოდ მერე გადახვიდე შემდეგზე.

მთავარი იყო NEEDRESTART_MODE=l დროშა. needrestart არ იყო კონფიგურირებული და apt -y-ის დროს ან კითხვაზე გაიჭედებოდა, ან containerd-ს გადატვირთავდა — ეს კი ნოდაზე ყველა კონტეინერს კლავს. l ნიშნავს „მხოლოდ აჩვენე, მე გადავწყვეტ“. შვიდივე ნოდაზე მან აჩვენა, რომ კონტეინერების გადატვირთვა საჭირო არ იყო.

რამ გამაკვირვა

  • ერთი ნოდის drain-მა სხვა ნოდებზე მიერთებული ტომები დააზიანა, რადგან რეპლიკები გაფანტულია. ერთი drain-ის შემდეგ ექვსი ტომი degraded გახდა, დიდები საერთო დისკზე დაახლოებით ოთხ წუთს აღდგებოდა. ნოდებს შორის healthy-ს ლოდინი სავალდებულოა და არა სიფრთხილე.
  • „არა healthy“-ის გულუბრყვილო დათვლა ტყუის: გათიშულ ტომებს robustness ველი ცარიელი აქვთ და „არა healthy“-ში ხვდებიან. რეალური მნიშვნელობების ნახვა მომიწია.
  • CloudNativePG თავად გადაერთო, როცა primary-ის ნოდა დაგეგმვისთვის მიუწვდომელი გახდა. ასეთ თითო drain-ზე ერთი გადართვა ელოდეთ და გადატვირთვამდე 2/2 healthy შეამოწმეთ.
  • AppArmor-მა reboot-required მხოლოდ განახლების შემდეგ დააყენა, წინასწარ დროშა არ იყო. ყოველი ნოდის გადატვირთვა ნებისმიერ შემთხვევაში დაგეგმეთ.
  • გვირაბების რეპლიკების განლაგება წყვეტდა, დარჩებოდა თუ არა საიტები ხელმისაწვდომი. თითო რეპლიკით სხვადასხვა ვორკერზე საიტები მთელი დროის განმავლობაში 200-ს აბრუნებდნენ. ორივე რეპლიკა ერთ ნოდაზე ნამდვილ შეფერხებას ნიშნავდა.

შედეგი

48 პაკეტი თითო ნოდაზე, Ubuntu 24.04.4, ბირთვი უცვლელი, kubelet ხელუხლებელი, შვიდივე ნოდა Ready, ყველა Longhorn ტომი healthy, etcd 3/3 ერთნაირი raft ინდექსებით, Postgres 2/2, Vault 3/3, Argo CD-ის ყველა აპლიკაცია Synced, ყველა ენდპოინტი პასუხობს. სნეპშოტები შემოწმების შემდეგ წაიშალა.

დასკვნები

  • ჯერ წინასწარი შემოწმება: კონკრეტულად რას შეეხება განახლება და შეუძლია თუ არა კლასტერის საკუთარ კომპონენტებს შეეხოს?
  • კანარი იმით აირჩიეთ, რაც შეიძლება ნაკლები რამ რომ ედოს.
  • ტემპი საცავმა დაადგინოს. შემდეგი ნოდა ტომებს ელოდება და არა საათს.
  • drain-მდე ყველაფერი საჯაროს რეპლიკების განლაგება შეამოწმეთ.