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, რომელიც ბაზის მიგრაციებს ისე ასრულებს, რომ არავინ უყურებს, შაბათ-კვირის დაკარგვის ჩუმი გზაა.