სტატიები
ჩანაწერები პროდაქშენიდან და სახლის ლაბორატორიიდან: განახლებები, მიგრაციები, ინციდენტები.
- AI აგენტი ჩემს ოპერაციულ სამუშაოში: შეზღუდვები, რომლებიც მას უსაფრთხოს ხდისოპერაციული სამუშაოს დიდ ნაწილს AI აგენტთან ერთად ვაკეთებ ტერმინალში: kubectl, ლოგები, მანიფესტები, git, ღრუბლოვანი API-ები. სისწრაფე მარტივი ნაწილია. აი წესები, რომლებიც ამას უსაფრთხოს ხდის, და შეცდომები, რომლებიც მათ დაიჭირეს.
- RDS კავშირებზე უარს ამბობდა 10% CPU-ზე: ნაგულისხმევი პულები, გამრავლებული რეპლიკებზედატვირთვის ტესტები ~420 კავშირის ბრტყელ პლატოზე ჩერდებოდა და „უფრო დიდ ბაზას" ითხოვდნენ. ნამდვილი ჭერი იყო max_connections Npgsql-ის ნაგულისხმევი პულების წინააღმდეგ.
- Calico Ready-ში იყო შეცდომების გარეშე, ყოველი ახალი პოდი კი ნახევარი წუთი მიუწვდომელი იყოCalico-ს განახლების შემდეგ ახალი პოდები 15–42 წამი შავ ხვრელში იყვნენ. Felix XDP resync-ის ციკლში იყო ჩარჩენილი, რომელიც მხოლოდ ნოდებს შორის ახალი პოდების ტესტმა აჩვენა.
- Kubernetes 1.32-დან 1.37-მდე ერთ დღეში, ხუთი ჰოპი, იმ kubespray-ის გარეშე, რომლითაც კლასტერი აიწყოEOL ვერსიაზე მყოფი bare-metal კლასტერი, დაკარგული kubespray ინვენტარი და ბინარები პაკეტების მენეჯერის გარეთ. როგორ გავიდა kubeadm-ის ხუთი ჰოპი ერთ დღეში და ხაფანგები, რომლებიც არც ერთ გეგმაში არ იყო.
- ერთი წუთი მუშაობდა, მერე ტაიმაუტები: MetalLB L2 და kube-proxy ipvs strictARP-ის გარეშეჰოსტების ახალ LoadBalancer IP-ზე გადაყვანა ცოტა ხანს მუშაობდა, მერე გარე ბალანსერმა L4 ტაიმაუტები დაინახა. ერთსა და იმავე IP-ზე ARP-ს ყველა ნოდი პასუხობდა.
- სერტიფიკატებს ვადა გრაფიკით გაუვიდა. ალერტი ერთი კვირა ყვიროდა — სიცარიელეშიkubeadm კლასტერმა control plane დაკარგა ინსტალაციიდან ზუსტად ერთი წლის შემდეგ. ალერტი შვიდი დღე იწვოდა, მაგრამ Alertmanager-ს მხოლოდ null მიმღები ჰქონდა.
- ალერტი ჩაირთო და ვერავინ დაინახა: cluster ლეიბლი აგრეგაციაში დაიკარგანოდი ოთხი საათი 90–98% CPU-ზე იჯდა და OOM kill-ით დასრულდა. CPU ალერტი ჩაირთო, მაგრამ avg by(instance)-მა ის ლეიბლი გადააგდო, რომლითაც ყველა მარშრუტი და დაშბორდი ირჩევდა.
- Kubernetes 1.33 → 1.36 და Calico → Cilium ერთ დღეშირეპეტიცია სახლის ლაბორატორიაში: Kubernetes-ის სამი ნაბიჯი, CNI-ის შეცვლა Cilium-ით kube-proxy-ის გარეშე და ingress-nginx-ის ნაცვლად Gateway API — რატომ აჯობა კონტროლირებადმა big-bang-მა ცოცხალ მიგრაციას და რა ხაფანგები უნდა იცოდეთ.
- საბრძოლო სერტიფიკატს ვადა გაუვიდა და არავინ შეამჩნია: გარე პროქსიმ ავარია საკუთარი თავით დაფარაყველა საჯარო ჰოსტი 200-ს აბრუნებდა, კლასტერი კი ვადაგასულ wildcard-ს აძლევდა. საკუთარი TLS-ის მქონე პროქსიმ ავარია დამალა; ნამდვილი მიგნება ვადის ალერტის არარსებობა იყო.
- multipathd-მა Longhorn-ის ტომი მიითვისა: „mount point busy“, თუმცა არაფერია დამონტაჟებულიპოდი ხუთი დღე Init-ში იდგა, 2413 მონტაჟის მცდელობა, სრულმა რებუტმა არ უშველა. multipathd-მა Longhorn-ის iSCSI მოწყობილობაზე რუკა ააგო და ღიად ეჭირა.
- რებალანსის შტორმი ჩვეულებრივი დეპლოი აღმოჩნდა: ზღვარი, რომელიც ჯგუფთან ერთად იზრდებაKafka-ს რებალანსის ალერტი ყოველ რელიზზე საათში 60-ზე ირთვებოდა. მეტრიკა 40 კონსიუმერზე ჯამდებოდა და მოცურავე საათით საშუალოვდებოდა — ალერტი წარსულს აღწერდა.
- Argo CD აჩვენებდა Synced-ს, API სერვერმა კი ჩუმად გადააგდო ჩემი შესწორებათვეობით არ იყო მეტრიკები, შესწორება უკვე git-ში იდო და სტატუსი მწვანე Synced იყო. ველი CRD-ის სქემაში არ არსებობდა, API სერვერმა მოჭრა და არავინ იჩივლა.
- Liveness პრობა, მიბმული სხვის ქსელზე: 330 რესტარტი, რომლებმაც არაფერი შეაკეთესcloudflared-ის ორი იდენტური რეპლიკა — 330 და 13 რესტარტი. Liveness ამოწმებდა გვირაბს edge-მდე, ამიტომ აპლინკის ყოველი შეფერხება SIGKILL-ად იქცეოდა.
- ჩატვირთვის ეკრანი retry-ციკლი იყო და არა გაჭედვა — გადატვირთვა საჭირო არ ყოფილათამაში ჩემს Linux-კომპიუტერზე ჩატვირთვის ეკრანზე იჭედებოდა, ცნობილი წამალი კი სრული გადატვირთვა იყო. /proc-ის მთვლელების ხუთმა წამმა აჩვენა ციკლი, რომელიც ერთი SIGTERM-ით სრულდება.
- ალერტინგის სამი გაუმართაობა ერთი ფესვიდან: სახელი იქ, სადაც ID უნდა ყოფილიყოვიღაცამ Slack-ის არხს სახელი გადაარქვა და პროდაქშენ-სისტემის ალერტების მიწოდება ჩუმად მოკვდა. ეს იგივე იდენტიფიკატორზე მესამე გაუმართაობა იყო.
- Kafka 94 %-ით სავსე დისკზე, 17 საათის მარაგი და retention, რომელიც ორჯერ მეტს ინახავდატრაფიკი 150-ჯერ გაიზარდა, ტომები კი არავის გადაუხედავს. უარესი: სეგმენტების ნაგულისხმევი როლინგის დროს 7-დღიანი retention სინამდვილეში 7–14 დღეს ნიშნავდა.
- Basic auth გაქრა 80-ე პორტზე Ingress-იდან Gateway API-ზე გადასვლის შემდეგყველა სტატუსი მწვანე იყო, ჩემი curl 401-ს აბრუნებდა. WordPress-ის შესვლა კი ყველასთვის ღია იყო: Gateway API პოლიტიკას ერთ listener-ს აბამს, Ingress-ის ანოტაციები კი ყველა პორტს ფარავდა.
- ექვსი საათი NotReady-ში, ნოდა კი მთელი ამ დროის განმავლობაში ცოცხალი იყოყველა სიგნალი ამბობდა, რომ ნოდა მკვდარია. სინამდვილეში მეხსიერება აკლდა, ხოლო აშკარა გამოსავალი — ნოდის წაშლა და ტომის იძულებითი მოხსნა — ერთი ბრძანებით იყო დაშორებული ბაზის დაზიანებისგან.
- ვარსკვლავი Vault-ის გზის შუაში wildcard არ არისვადაგასულმა ტოკენმა საიდუმლოებების ოპერატორი გააჩერა. მისმა ხელახლა გაცემამ უფრო ძველი ბაგი გამოავლინა: Vault-ის 27 პოლიტიკა * სიმბოლოთი გზის შუაში ჩუმად კრძალავდა იმას, რასაც აცხადებდა.
- Postgres-ის რეპლიკა 23 საათი pg_rewind-ის ციკლში ტრიალებდა: ხელახლა შექმენით და ნუ შეაკეთებთfailover-ის შემდეგ CloudNativePG-ის რეპლიკამ rewind ვერ გააკეთა: მისი WAL-სეგმენტები ნულოვანი ზომის იყო, მონაცემთა კატალოგი კი primary-ზე ათჯერ პატარა. 23 საათი ვერავინ შეამჩნია, რადგან ოპერატორის მეტრიკები არ გროვდებოდა.
- Error budget VictoriaMetrics-ში: recording rules, burn-rate ალერტები და ერთი პატიოსანი პანელიროგორ ავაწყეთ error budget პირველი დონის სერვისებისთვის უკვე არსებული მეტრიკებიდან: SLO-მიზნები სერვისების მიხედვით, multi-window burn-rate ალერტები, რიგი Grafana-ში — და რატომ არ იყო უარყოფითი ბიუჯეტი გაშვებისთანავე ინციდენტი.
- ერთი p99 ალერტი, ხუთი ნელი მარშრუტი, ხუთი სხვადასხვა მიზეზისერვისის დონის ლატენტობის ალერტი არც ერთ endpoint-ს არ ასახელებდა. მარშრუტების მიხედვით დაყოფამ აჩვენა გარე შლუზი, captcha-ს შემოწმება, პროვაიდერის გამოძახება — და გაზომვის ხაფანგები, რომლებიც არასწორი გზით წაგვიყვანდა.
- პროდაქშენის Postgres-ის გადატანა RDS Multi-AZ instance-დან Multi-AZ DB cluster-ზედაგეგმილი cutover თითქმის მონაცემების დაკარგვის გარეშე — და სამი ხაფანგი: „ტექსამუშაოები“, რომლებმაც ჩაწერა ვერ შეაჩერეს, პაროლები, რომელთა კოპირებასაც RDS არ იძლევა, და დამპი 25 წუთში VPN-ით 31 წამის წინააღმდეგ VPC-ში.
- ლაგი ნულზე ჩამოვიდა, მაგრამ არაფერი გამოსწორებულა: Kafka-ს გაჭედილი კონსიუმერი, დამალული group.id-ის გადარქმევითკონსიუმერის ლაგი ხუთ დღეს იზრდებოდა, შემდეგ ნულზე ჩამოვიდა და იქ დარჩა. თითქოს თავისით გამოსწორდა. სინამდვილეში კონსიუმერი გაჭედილი იყო, მეტრიკა გაქრა, ალერტი კი თავისით დაიხურა.
- Python-ის მეხსიერების გაჟონვის პროფილირება პროდაქშენზე memray-ით — და ავარია, რომელიც გზაში მოვაწყვეთბექენდი ყოველ 10–15 საათში OOM-ით ეცემოდა. ცოცხალ პოდზე memray-ის საათობრივმა ანაბეჭდებმა გაჟონვა ბიბლიოთეკის middleware-ში იპოვა და არა აპლიკაციის კოდში — მას შემდეგ, რაც პირველმა მცდელობამ პროდაქშენი შვიდი წუთით გათიშა.
- საწარმოო კლასტერის გადატანა Longhorn-იდან LINSTOR-ზე — და მოლოდინი, რომელიც არ ახდარატომ შევცვალეთ Longhorn LINSTOR/DRBD-ით self-managed კლასტერზე, როგორ გადავიდა თითოეული დატვირთვა თავისი გზით და რა წავიდა გზაში ცუდად.
- ingress-nginx-დან Envoy Gateway-ზე დაუნთაიმის გარეშე: 27 Ingress, 39 HTTPRouteingress-nginx გადამდგარია და Kubernetes-ის განახლებებს ბლოკავს. როგორ გადავიყვანეთ 16 საჯარო ჰოსტი Envoy Gateway-ზე: ახალი შესასვლელი ძველის გვერდით ავამუშავეთ და ბოლოს მხოლოდ მისამართი შევცვალეთ.
- CloudNativePG-ის გადაყვანა Barman Cloud პლაგინზე არქივის გაწყვეტის გარეშეCNPG barmanObjectStore-ის ჩაშენებულ მხარდაჭერას აუქმებს. გადართვას ვალიდური შუალედური მდგომარეობა არ აქვს, ბაზას არც ერთი საბაზისო ბექაპი არ ჰქონდა, ერთი გზა კი წყვეტს, იმუშავებს თუ არა point-in-time recovery.
- ოთხი შემოწმება, რომელიც ტყუოდა, სანამ სისტემა ჯანსაღი იყოპლატფორმის მიგრაციების ერთ დღეში ოთხი შემოწმება შეცდომას აცხადებდა, თუმცა ყველაფერი რიგზე იყო. როცა ერთი სიგნალი ყველა დანარჩენს ეწინააღმდეგება, პირველ რიგში თავად სიგნალს ეჭვობდეთ.
- ალერტები, რომლებიც ვერ ამოქმედდებიან: ბრმა ServiceMonitor და მკვდარი მიწოდების არხიVault-ის პირი 32 საათი sealed იყო, საიდუმლოებები კი კვირაზე მეტი არ სინქრონიზდებოდა — რეპოზიტორიაში VaultSealed ალერტით და ჯანმრთელი Alertmanager-ით. ინციდენტი ორმა დამოუკიდებელმა შეფერხებამ დამალა.
- „ბირთვების დრეიფი“ აპტაიმის დრეიფი აღმოჩნდა: პატჩები დგებოდა, გადატვირთვა — არაშვიდ ნოდაზე სამი სხვადასხვა ბირთვი დაუსრულებელ პატჩების ტალღებს ჰგავდა და გამოძიება ცრუ კვალზე წაიყვანა. პატჩები ყველა ნოდაზე ერთნაირი იყო, განსხვავდებოდა მხოლოდ აპტაიმი.
- kubectl patch --type merge-მა CoreDNS წაშალა, ყველა შემოწმება კი მწვანე დარჩაიმიჯის ერთხაზიანმა განახლებამ კონტეინერის მთელი სპეციფიკაცია შეცვალა. CoreDNS-მა კონფიგი დაკარგა, ჩუმად whoami პლაგინზე გადავიდა და ყველაფერს NOERROR-ით პასუხობდა პასუხის გარეშე.
- MetalLB-ის შეცვლა Cilium LB IPAM-ით ისე, რომ არც ერთი მოთხოვნა არ დაკარგულაკლასტერში მხოლოდ ერთი LoadBalancer IP იყო და ყველა მარშრუტი მასზე იყო დამოკიდებული. როგორ გადავეცი ის MetalLB-დან Cilium-ს შეცდომების გარეშე — ორივე კონტროლერს ერთდროულად ვამუშავებდი.
- Vault-ის გადაყვანა Shamir-დან transit auto-unseal-ზე და ოთხი ხაფანგი გზაზეVault-ის პოდის ყოველი გადატვირთვა დალუქული საცავით და გაყინული საიდუმლოებების სინქრონიზაციით სრულდებოდა. როგორ დავამატეთ transit პროვაიდერი, გადავიყვანეთ სამნოდიანი raft კლასტერი და სად წავიბორძიკეთ.
- Vault თავისით ილუქებოდა. მიზეზი კლასტერის ქვემოთ VM-ის 15-წუთიანი გაყინვა იყოVault-ის ოთხი seal სამ კვირაში, თითოეული ცალკე ინციდენტად განიხილებოდა. journald-ის პაუზების ანალიზმა აჩვენა, რომ ჰიპერვიზორი ბექაპისას VM-ს ყინავს, Longhorn კი ამას კასკადად აქცევს.
- GitLab-ის განახლება და ორი სიგნალი, რომლებიც ტყუოდნენself-hosted GitLab-ის ჩვეულებრივი მინორული განახლება Docker-ში. წინასწარმა შემოწმებამ 32 დაუსრულებელი მიგრაცია დაითვალა, კონტეინერი კი healthy გახდა ისე, რომ არაფერს ემსახურებოდა.
- როგორ განვაახლოთ OS შვიდ Kubernetes ნოდაზე ისე, რომ ვერავინ შეამჩნიოსUbuntu-ს რიგრიგობითი განახლება კლასტერში, რომელიც საკუთარ მდგომარეობას თავად ინახავს. წინასწარმა შემოწმებებმა საშიში სამუშაო მოსაწყენად აქცია, ტემპს კი Longhorn კარნახობდა.
- ერთმა დავიწყებულმა DHCP ოფციამ მთელი Kubernetes კლასტერი გათიშაჰოსტის გადატვირთვის შემდეგ ორმოცდაათამდე პოდი CrashLoop-ში წავიდა, თუმცა ყველა ნოდა Ready იყო. მიზეზი დავიწყებული DHCP classless routes ოფცია იყო, რომელმაც ნაგულისხმევი შლუზი ჩუმად წაშალა.
- დამერჯილი, დასინქრონებული, მიმაგრებული — და მაინც არ ალერტავს: vmalert hot reload-ის გარეშეKafka-ს ახალმა წესებმა Git-ისა და Argo CD-ის გავლით ConfigMap-მდე მიაღწიეს, მაგრამ vmalert-მა მათი შეფასება ასე და ვერ დაიწყო. GitOps კონვეიერი ბოლო ნაბიჯზე გაწყდა.
- Grafana-ს პანელი, რომელიც გეუბნება, როდის დაეცემა პოდი OOM-ითროგორ ვაქციოთ მეხსიერების ტრენდი ETA-დ OOM-მდე და დისკის შევსებამდე PromQL-ით, ორი ხარვეზი, რის გამოც პანელი ცრუობდა, და გაჟონვა, რომელიც პირველივე დღეს დაიჭირა.
- ONLINE_UNCERTAIN: როცა MySQL ოპერატორი და ბაზა ვერ თანხმდებიანRouter ციმციმებს, ოპერატორი ორი დღეა ბლოკირებაშია, CRD 2/3-ზე გაიყინა — თან InnoDB Cluster-ის სამივე წევრი ჯანმრთელია. გამოსავალი მეტამონაცემების ერთი rescan იყო.
- Vault Secrets Operator seal-ის შემდეგ გაჩუმდა — და გადატვირთვამ ვერ გააღვიძა43-დან 38 VaultStaticSecret ორი დღე გაყინული შეცდომით იდგა. Vault-ის unseal-მა და ოპერატორის გადატვირთვამ არაფერი მისცა; spec-ის ერთი ველის შეცვლამ უშველა.
- WordPress-ში შესვლის მარყუჟი, რომელიც მხოლოდ ზოგჯერ ხდებოდაwp-admin შესვლის გვერდზე reauth=1-ით აბრუნებდა, მაგრამ არა ყოველთვის. მიზეზი იყო ყოველ პოდში გენერირებული შემთხვევითი auth salt-ები sticky სესიების გარეშე ბალანსერის უკან.
- სამი ინციდენტი, რომელიც ერთი აღმოჩნდა: კონფიგში ჩაწერილი მონაცემთა ბაზის IP500 შესვლისას, CrashLoopBackOff-ში მყოფი ბექენდები და გაჭედილი დეპლოი სამ პრობლემად გამოიყურებოდა. სამივე pgbouncer-ის კონფიგში ჩაწერილი ერთი IP აღმოჩნდა.
- „დისკის შეცდომები“ OOM აღმოჩნდა: როგორ დაკარგეს Longhorn-ის ტომებმა ბექენდიEIO, read-only ext4, დაზიანებული MySQL datadir და დალუქული Vault მომაკვდავ დისკს ჰგავდა. ჰოსტის dmesg-მა მთელი ნოდის OOM აჩვენა, რომელმაც პირველად Longhorn-ის instance-manager მოკლა.
- „Vault თავად ილუქება“ — არა, ის უბრალოდ არასოდეს იხსნებაVault-ის პოდი დღეობით იდგა Ready 0/1-ზე, raft-ის კვორუმი კი ჩუმად ორ პირზე ინარჩუნებდა თავს. მას არავინ ლუქავდა: Shamir auto-unseal-ის გარეშე ყოველ რესტარტს დალუქულს ტოვებს.
- Longhorn-ის ტომი, რომელსაც გაზრდა არ სურდა: ცუდ ნოდაზე მიმაგრებული attachment ticketPVC დაუსრულებლად იდგა Resizing-ში, Longhorn კი ყოველ ხუთ წამში იმეორებდა გაფართოებას ერთი შეცდომის გარეშე. მოძველებული attachment ticket ტომს ერთ არაჯანსაღ ნოდაზე აკავებდა.
- StatefulSet-ის უცვლელი ველის შეცვლა ერთი პოდის გადატვირთვის გარეშეGit-ში 20 GiB, ცოცხალ StatefulSet-ში 6 GiB-იანი შაბლონები, Argo CD კი Synced-ს აჩვენებს. როგორ გადააწყო orphan წაშლამ და OnDelete-მა შაბლონი დაუნთაიმის გარეშე.
- ხუთი დღე 1/3-ზე მწვანე დაშბორდებით: როცა CRD-ის სტატუსი ცრუობსMySQL InnoDB Cluster ხუთი დღე HA-ს გარეშე მუშაობდა, რესურსის სტატუსი, პოდების ფაზა და readiness gate კი ჯანმრთელობას აჩვენებდნენ. სამივე სიგნალი ერთი გაჭედილი ოპერატორიდან მოდიოდა.
- Helm წერს „another operation is in progress“, თუმცა არაფერი მიმდინარეობსგაუქმებულმა CI ჯობმა ორი Helm რელიზი pending-upgrade-ში დატოვა და ყველა დეპლოი დაბლოკა. როგორ ვიპოვოთ lock, უსაფრთხოდ მოვხსნათ და მთელი namespace ერთბაშად შევამოწმოთ.
- როგორ ვუყურებ პლატფორმასინფრასტრუქტურა პროდუქტად, GitOps, CI/CD, DevSecOps — პროგნოზირებადი რელიზები და უსაფრთხოება პაიპლაინში.