kubectl patch --type merge-მა CoreDNS წაშალა, ყველა შემოწმება კი მწვანე დარჩა
იმიჯის ერთხაზიანმა განახლებამ კონტეინერის მთელი სპეციფიკაცია შეცვალა. CoreDNS-მა კონფიგი დაკარგა, ჩუმად whoami პლაგინზე გადავიდა და ყველაფერს NOERROR-ით პასუხობდა პასუხის გარეშე.
ჩემს სახლის ლაბორატორიაში მთელი კლასტერის DNS ახალი მოთხოვნებისთვის მოკვდა, ჯანმრთელობის ყველა სიგნალი კი მწვანე დარჩა. პოდები ნებისმიერ სახელზე bad address-ით ვარდებოდნენ, მაგრამ IP-ით დაკავშირება მუშაობდა. CoreDNS-ის პოდები — 1/1 Running, Ready, ნული გადატვირთვა. Argo CD Synced, Postgres ჯანმრთელი, ყველა საჯარო ენდპოინტი 200-ს აბრუნებს. CoreDNS-ის ლოგები ცოცხალი და ჯანმრთელი ჩანდა: NOERROR-ის თანაბარი ნაკადი. dig კი ამბობდა status: NOERROR და ANSWER: 0.
ყველაფერი, რაც უკვე დაკავშირებული იყო, მუშაობას აგრძელებდა. მხოლოდ ახალი მოთხოვნები ვარდებოდა, ამიტომ პრობლემის დანახვაც კი მაშინვე ვერ მოხერხდა.
ცვლილება, რომელმაც ყველაფერი გამოიწვია
CoreDNS-ის იმიჯი იმით განვაახლე, რაც უწყინარ ერთხაზიანს ჰგავდა:
kubectl -n kube-system patch deploy coredns --type merge \
-p '{"spec":{"template":{"spec":{"containers":[{"name":"coredns","image":"…"}]}}}}'
--type merge არის JSON Merge Patch (RFC 7386), merge patch კი მასივებს მთლიანად ცვლის. ის სიის ელემენტებს სახელით არ აერთიანებს — ამას strategic merge patch აკეთებს. შედეგად მთელი containers მასივი ჩემი ერთელემენტიანი ობიექტით შეიცვალა და ყველაფერი, რაც არ გავიმეორე, წაიშალა: არგუმენტი -conf /etc/coredns/Corefile, ტომების მიმაგრება, პორტები, ორივე probe და რესურსები.
რატომ ჩანდა ჯანმრთელად
-conf-ის გარეშე CoreDNS მიმაგრებულ Corefile-ს არ კითხულობს. ის ჩაშენებულ ნაგულისხმევზე ირთვება — ერთ სერვერულ ბლოკზე whoami პლაგინით.
whoami ყოველ მოთხოვნას NOERROR-ით პასუხობს, კლიენტის საკუთარ მისამართს ADDITIONAL სექციაში დებს, კლიენტის პორტით SRV ჩანაწერს ამატებს და ANSWER-ს ცარიელს ტოვებს. რეზოლვერები ცარიელ პასუხს ხედავდნენ და ვარდებოდნენ; dig +short არაფერს ბეჭდავდა, რაც „პასუხი არ არის“-დ იკითხება; ლოგები ჩვეულებრივ NOERROR ტრაფიკს ჰგავდა. პოდები კი Ready იყო, რადგან readiness probe იმავე პატჩმა წაშალა — probe-ის გარეშე კონტეინერი ყოველთვის მზადაა.
როგორ ვიპოვე
დრო დამაჯერებელ ცრუ კვალს მოვანდომე: Cilium-ის სერვისების eBPF რუკაში გავრცელების შემდეგ ცოტა ხნით CoreDNS-ის ორიდან ერთი ბექენდი იყო, აგენტის გადატვირთვის შემდეგ ენდპოინტები restoring მდგომარეობაში იყო, და Cilium-ის DNS პროქსის პარამეტრიც კი გადავრთე. არცერთი მათგანი მიზეზი არ იყო.
იმუშავა ნოდიდან გაგზავნილმა ნედლმა DNS მოთხოვნამ საკონტროლო წერტილით: იგივე მოთხოვნამ ცნობილად გამართულ რეზოლვერთან ერთი პასუხი დააბრუნა, CoreDNS-მა კი ნული პასუხი და ორი დამატებითი ჩანაწერი. ბაიტების გარჩევამ აჩვენა A ჩანაწერი ჩემი საკუთარი მისამართით და SRV ჩანაწერი TTL 0-ით — whoami-ის ანაბეჭდი. სწრაფმა შემოწმებამ დაადასტურა: ნამდვილი CoreDNS დამატებით /ready-ს 8181-ზე და მეტრიკებს 9153-ზე აბრუნებს, ეს კი მხოლოდ 53-ე პორტს უსმენდა.
გამოსწორება
Deployment ცვლილებამდე აღებული დამპიდან აღვადგინე — წუთების საქმე. კონტეინერის სპეციფიკაციის მეხსიერებით აღდგენა სულ სხვა საქმე იქნებოდა. იმავე დღეს მოგვიანებით განახლება kubectl set image-ით გავიმეორე და ახალი ვერსია სრულიად უპრობლემო აღმოჩნდა.
დასკვნები
--type mergeყველაფრისთვის, სადაც სიაა, დამანგრეველია. კონტეინერები, ტომები, env, პორტები, tolerations — ყველა მასივია. გამოიყენეთkubectl set image, strategic merge patch (ნაგულისხმევიkubectl patch) ან სრული მანიფესტი.Readyიმდენს ნიშნავს, რამდენსაც მის უკან მდგომი probe. თუ კომპონენტი „Ready-ა, მაგრამ არასწორად მუშაობს“, შეამოწმეთ, საერთოდ არსებობს თუ არა probe.dig +shortმალავს პასუხებს, სადაც მხოლოდ ADDITIONAL არის. სანამ გადაწყვეტთ, რომ პასუხი არ ყოფილა, მთლიანად წაიკითხეთ.- დიაგნოსტიკა საკონტროლო წერტილით გააკეთეთ. ცნობილად გამართულ რეზოლვერთან შედარება „ჩემი ხელსაწყო ტყუის“-ს „სერვერი გაფუჭებულია“-სგან ჰყოფს.
- პლატფორმის კომპონენტის ხელით რედაქტირებამდე ობიექტის დამპი აიღეთ და გავრცელებას მანამ ნუ ენდობით, სანამ არ შეამოწმებთ, რომ სპეციფიკაცია გადარჩა.