← ყველა სტატია

GitLab-ის განახლება და ორი სიგნალი, რომლებიც ტყუოდნენ

self-hosted GitLab-ის ჩვეულებრივი მინორული განახლება Docker-ში. წინასწარმა შემოწმებამ 32 დაუსრულებელი მიგრაცია დაითვალა, კონტეინერი კი healthy გახდა ისე, რომ არაფერს ემსახურებოდა.

სახლის ლაბორატორიაში GitLab Docker-ში მაქვს. ეს ჩემი მთელი GitOps-ის ჭეშმარიტების წყაროა, ამიტომ მინორულ განახლებასაც (19.1.2 → 19.2.2) სხვათა შორის არ ვაკეთებ. ეს გეგმიური სამუშაო იყო და არა ინციდენტი, მაგრამ ორმა რამემ კინაღამ ჩაშალა — და ორივე იმის საპირისპიროდ გამოიყურებოდა, რაც სინამდვილეში იყო.

პირველი სიგნალი: 32 დაუსრულებელი მიგრაცია

GitLab განახლების საშუალებას არ მოგცემთ, სანამ batched background migrations სრულდება. ჩემმა წინასწარმა მოთხოვნამ 32 დაუსრულებელი მიგრაცია აჩვენა — ეს მკაცრი ბლოკერი იქნებოდა.

ეს გაზომვის შეცდომა იყო. status სვეტს ორი საბოლოო მნიშვნელობა აქვს: 3 — finished და 6 — finalized. ფილტრი status != 3 ყველა ფინალიზებულ მიგრაციას დაუსრულებლად თვლის. დოკუმენტირებული კრიტერიუმია status NOT IN (3, 6) და მისით რეალური რიცხვი ნული იყო. თან: პირდაპირი მოთხოვნა Postgres-ში მყისიერად პასუხობდა, gitlab-rails runner-ის ანალოგიურ გამოძახებას კი ორ წუთზე მეტი სჭირდებოდა.

მეორე სიგნალი: healthy 60 წამში

გადატვირთვის შემდეგ Docker-მა კონტეინერი დაახლოებით ერთ წუთში healthy-დ მონიშნა. ის არაფერს ემსახურებოდა.

იმიჯის health check სტეკის ვიწრო ნაწილს ფარავს. Chef ჯერ Postgres-ს, Redis-ს, Gitaly-ს და კიდევ რამდენიმე კომპონენტს უშვებს, სქემის მიგრაციებს ასრულებს და მხოლოდ ამის შემდეგ ვებ-ფენას რთავს. ამიტომ healthy მაშინ ამოქმედდა, როცა Puma, Nginx, Workhorse და Sidekiq ჯერ არ არსებობდნენ. როცა Nginx მაინც ჩაირთო, ორ წუთს 502-ს აბრუნებდა — ასე რომ, TCP პორტის შემოწმებაც შეფერხების შუაგულში წარმატებას გვაცნობებდა.

პროცედურა

ფიქსირებული რიგით მივდიოდი: შემოწმება → ბექაპი → ჩამოტვირთვა → შეცვლა → გამოყენება → შემოწმება.

  • ლოგიკური ბექაპი gitlab-backup create-ით და კონფიგურაციის კატალოგის არქივი, რომელსაც ბექაპი შეგნებულად არ შეიცავს (იქ არის gitlab-secrets.json).
  • ბექაპის ასლი ჰოსტის გარეთ, ორივე მხარეს sha256sum-ით შემოწმებული.
  • ახალი 3,9 GB იმიჯის docker pull ძველი კონტეინერის გაჩერებამდე — ამან შეფერხება 5 წუთსა და 59 წამში შეინარჩუნა 10–25 წუთის პროგნოზის ნაცვლად.
  • compose ფაილში მიმაგრებული ტეგის შეცვლა, docker compose down && up -d.
  • ლოგებში დასრულების ნამდვილი მარკერის ლოდინი და არა „Chef Client finished“-ის.

შედეგს მხოლოდ მომხმარებლისთვის ხილული სიგნალებით ვიღებდი: შესვლის გვერდი 200-ს აბრუნებს, ssh -T git@… მესალმება. არა ვენდორის ჯანმრთელობის დროშით.

რატომ ტოვებს ბექაპი ჰოსტს პირველი

დაბრუნება ასიმეტრიულია. სანამ ახალი კონტეინერი მიგრაციებს შეასრულებს, დაბრუნებას წამები სჭირდება: ძველი compose ფაილის აღდგენა და ძველი იმიჯის გაშვება. მიგრაციების შემდეგ ტეგის დაბრუნება შეუძლებელია: 19.2 სქემას გადაწერს და 19.1 მას ვერ წაიკითხავს. ერთადერთი გზა უკან ძველ იმიჯში სრული აღდგენაა — საათები. სწორედ ამ ასიმეტრიის გამო ტოვებს ბექაპი ჰოსტს ჩამოტვირთვამდე.

დასკვნები

  • იცოდეთ, რასაც ითვლით, მისი საბოლოო მდგომარეობები. != finished იგივე არ არის, რაც not in (finished, finalized).
  • კონტეინერის health check ვენდორის აზრია. განახლება იმით მიიღეთ, რასაც მომხმარებლები ხედავენ: HTTP 200 და მომუშავე git SSH-ით.
  • ჩამოტვირთეთ გაჩერებამდე. შეფერხება გადატვირთვაა და არა ჩამოტვირთვა.
  • დაიცავით განახლების გზა. GitLab-ს სავალდებულო გაჩერებები აქვს; გაჩერება ჭერია და არა მიზანი: შემდეგ გაჩერებაზე დაბალი ნებისმიერი ვერსია ერთი ნაბიჯით მიიღწევა.
  • ასეთი განახლებები არასოდეს გაუშვათ ზედამხედველობის გარეშე. cron, რომელიც ბაზის მიგრაციებს ისე ასრულებს, რომ არავინ უყურებს, შაბათ-კვირის დაკარგვის ჩუმი გზაა.