Liveness პრობა, მიბმული სხვის ქსელზე: 330 რესტარტი, რომლებმაც არაფერი შეაკეთეს
cloudflared-ის ორი იდენტური რეპლიკა — 330 და 13 რესტარტი. Liveness ამოწმებდა გვირაბს edge-მდე, ამიტომ აპლინკის ყოველი შეფერხება SIGKILL-ად იქცეოდა.
ჩემს სახლის ლაბორატორიაში ერთი cloudflared Deployment-ის ორ რეპლიკას — ერთი იმიჯი, ერთი კონფიგი — სრულიად განსხვავებული ისტორია ჰქონდა: ერთს 330 რესტარტი, მეორეს 13. Exit code 137, reason Error, არა OOMKilled.
ასიმეტრია მინიშნებაა
25:1 სხვაობა იდენტურ რეპლიკებს შორის მაშინვე გამორიცხავს იმიჯსა და კონფიგს. ის, რაც მათ კლავს, ნოდზე ან ქსელის გზაზეა დამოკიდებული და არა კოდზე. 137 reason: Error-ით კი kubelet-ის SIGKILL-ია — პრაქტიკაში ჩავარდნილი პრობა.
რას ეკითხებოდა პრობა სინამდვილეში
Liveness /ready-ს ამოწმებდა. ვიფიქრე, რომ ეს „პროცესი მზადაა“ ნიშნავდა, და შემდგომი ვარაუდების ნაცვლად თავად ენდპოინტს ვკითხე port-forward-ით:
/ready -> {"status":200,"readyConnections":4}
cloudflared-ში /ready გვირაბის Cloudflare edge-თან კავშირების მდგომარეობას აჩვენებს და არა იმას, ცოცხალია თუ არა პროცესი. ამიტომ გარე ქსელის ყოველი შეფერხებისას კავშირები ეცემოდა, /ready ვარდებოდა და kubelet სრულიად ჯანსაღ პროცესს კლავდა. ლოგები ამას პირდაპირ ამბობდნენ:
failed to accept QUIC stream: timeout: no recent network activity
პოდის რესტარტი სხვის WAN-ს ვერ შეაკეთებს. საბოლოო მტკიცებულება, რომ მიზეზი ყოველთვის გარეთ იყო: რესტარტები თავისით შეწყდა იმ დღეს, როცა სახლის აპლინკი შეაკეთეს, Deployment-ში ყოველგვარი ცვლილების გარეშე.
შესწორება
- Liveness ახლა
/metrics-ს ამოწმებს — ის პასუხობს, სანამ თავად პროცესი HTTP-ს ემსახურება. - Readiness
/ready-ზე დარჩა: იქ „ამაღლებულია თუ არა გვირაბი“ ზუსტად სწორი კითხვაა. მოუმზადებელი პოდი ტრაფიკს აღარ იღებს, მაგრამ მას არ კლავენ. timeoutSeconds1-დან 5-მდე გავზარდე. ერთი წამი აგრესიულია QUIC I/O-თი დაკავებული პროცესისთვის.
გადართვამდე ახალი გზა ცოცხალ პოდზე შევამოწმე. Liveness 404-ის დამბრუნებელ გზაზე ერთდროულად კლავს ყველა რეპლიკას — ეს გაცილებით უარესი ავარიაა, ვიდრე ის, რასაც აკეთებ.
დასკვნები
- Liveness ერთ კითხვას პასუხობს: „პროცესი გაიჭედა და დაეხმარება თუ არა რესტარტი?“
- თუ პასუხი ქსელზე, ბაზაზე ან მესამე მხარეზეა დამოკიდებული, მისი ადგილი readiness-ში ან ალერტშია და არა liveness-ში.
- Liveness გარე დამოკიდებულებაზე სხვის ავარიას შენს CrashLoop-ად აქცევს, რესტარტების მთვლელი კი შემდეგ ნამდვილ მიზეზს მალავს.
- იდენტური რეპლიკების ძალიან განსხვავებული რესტარტები გარემოზე მიუთითებს და არა კოდზე.