ხუთი დღე 1/3-ზე მწვანე დაშბორდებით: როცა CRD-ის სტატუსი ცრუობს
MySQL InnoDB Cluster ხუთი დღე HA-ს გარეშე მუშაობდა, რესურსის სტატუსი, პოდების ფაზა და readiness gate კი ჯანმრთელობას აჩვენებდნენ. სამივე სიგნალი ერთი გაჭედილი ოპერატორიდან მოდიოდა.
Optimacros-ში MySQL InnoDB Cluster-ზე დგას კლასტერი, რომელიც კომპანიის მარკეტინგულ საიტებს ემსახურება. ის სამ წევრზეა გათვლილი, რომ ერთის დაკარგვას გაუძლოს. დაახლოებით ხუთი დღე ის სამიდან ერთ წევრზე მუშაობდა — ყოველგვარი მდგრადობის გარეშე — და ყველა დაშბორდი მწვანე იყო.
სამი სიგნალი, ერთი ტყუილი
როცა ბოლოს კარგად დავაკვირდი, სამი ერთი შეხედვით დამოუკიდებელი სიგნალი ერთხმად ამბობდა „ჯანმრთელია“:
InnoDBClusterრესურსი აჩვენებდაONLINE-ს დაonlineInstances: 3-ს;- პოდები
Running-ში იყვნენ: გატეხილ მეორად კვანძებს ცოცხალი sidecar კონტეინერი რჩებოდათ; - ოპერატორის მიერ დაყენებული readiness gate იყო
True.
კლასტერის UI ამ .status-ს აქტუალურად აჩვენებდა, ამიტომ ნებისმიერი სწრაფი მზერა სამ ჯანმრთელ წევრს ხედავდა, თუმცა ორი მათგანი მკვდარი იყო.
რატომ დაემთხვა სამივე
ისინი სულაც არ იყვნენ დამოუკიდებლები. სამივეს ერთი და იგივე MySQL ოპერატორი წერდა, მისი reconciler კი გაიჭედა. ის .status.cluster.lastProbeTime ველმა გასცა: რამდენიმე დღის წინანდელ თარიღზე იყო გაყინული.
კონტროლერის მიერ დაწერილი სტატუსი იმდენად ახალია, რამდენადაც თავად კონტროლერია ცოცხალი. როცა კონტროლერი იჭედება, ბოლო მნიშვნელობა ადგილზე რჩება და მოძველებულად კი არ გამოიყურება — ავტორიტეტულად გამოიყურება. ეს მონაცემების არქონაზე უარესია: ეს აქტიური დეზინფორმაციაა. ჩვენი მონიტორინგი სწორედ ამ სიგნალებზე იყო მიბმული — მათზე, რომლებიც გაფუჭებულ კომპონენტზეა დამოკიდებული, — ამიტომ ტყუილს არაფერი ეწინააღმდეგებოდა.
ვკითხულობთ ground truth-ს
გამოსავალი იყო სიგნალების ყურება, რომლებიც ოპერატორზე არ გადის:
- StatefulSet-ის
readyReplicas: kube-state-metrics მას პირდაპირ API სერვერიდან კითხულობს; - Group Replication-ის წევრების რაოდენობა mysqld-exporter-იდან;
- MySQL Router-ის საკუთარი წარმოდგენა ცოცხალ წევრებზე, რომელიც მის ლოგებში ჩანს.
სამივე ერთმანეთს დაემთხვა და რესურსს დაშორდა. ოპერატორის rollout restart-მა ის გაალღო და დაახლოებით 30 წამში სტატუსმა ახალი პრობის დრო და რეალური სურათი აჩვენა. ოპერატორის გადატვირთვა უსაფრთხოა: ის მხოლოდ ორკესტრირებას აკეთებს, Group Replication თავისით მუშაობს. მკვდარ წევრს ის, რა თქმა უნდა, არ ასწორებს — ეს ცალკე აღდგენა იყო.
ნდობის ჯაჭვი
ახლა ამ სიგნალებს ფაქტიდან ჭორამდე ჯაჭვად აღვიქვამ:
containerStatuses[].ready → StatefulSet.status.readyReplicas → pod.status.phase → CustomResource.status
ალერტი ყველაზე მარცხენა სიგნალზე დააყენეთ, რომლის შეგროვებაც იაფია, და არასოდეს — ყველაზე მარჯვენაზე. ჩვენ დავამატეთ PrometheusRule kube_statefulset_status_replicas_ready < 3-ზე ხუთი წუთის განმავლობაში. ის გაჭედილი ოპერატორის აღმოჩენას არ ცდილობს — Prometheus-იდან ეს რთულია, CR-ის სტატუსი მეტრიკა არ არის. ის უბრალოდ წყვეტს იმ სიგნალზე დამოკიდებულებას, რომელიც შეიძლება გაიჭედოს.
დასკვნები
- კონტროლერის მიერ დაწერილი
.statusმინიშნებაა და არა ფაქტი. თუ მასში პრობის ან heartbeat-ის დრო ძველია, ძველია ყველაფერი დანარჩენიც. - თუ რამდენიმე „დამოუკიდებელი“ ჯანმრთელობის სიგნალი ერთი კომპონენტიდან მოდის, გაქვთ ერთი სიგნალი და არა რამდენიმე.
- ალერტი ground truth-ზე დააყენეთ, რომელსაც დაკვირვების ობიექტთან საერთო მარცხის დომენი არ აქვს.
- იგივე ეხება ოპერატორის მიერ მართულ ნებისმიერ რესურსს: მონაცემთა ბაზებს, Vault-ს, cert-manager-ის სერტიფიკატებს, Argo CD-ის აპლიკაციების ჯანმრთელობას.