როგორ განვაახლოთ 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-მდე ყველაფერი საჯაროს რეპლიკების განლაგება შეამოწმეთ.