WordPress-ში შესვლის მარყუჟი, რომელიც მხოლოდ ზოგჯერ ხდებოდა
wp-admin შესვლის გვერდზე reauth=1-ით აბრუნებდა, მაგრამ არა ყოველთვის. მიზეზი იყო ყოველ პოდში გენერირებული შემთხვევითი auth salt-ები sticky სესიების გარეშე ბალანსერის უკან.
Optimacros-ში მარკეტინგული საიტები Kubernetes-ზე ცხრა WordPress-ის ფლოტია, თითოეულს ორიდან ხუთ რეპლიკამდე HPA-ს ქვეშ. საჩივარი პაროლის პრობლემას ჰგავდა: „პაროლი სწორია, ერთხელ შევედი და მერე მარყუჟი იწყება“.
basic auth-ის შემდეგ /wp-admin/-ის გახსნა მომხმარებელს wp-login.php?...&reauth=1-ზე აბრუნებდა. ზოგჯერ შესვლა ცოტა ხნით ნარჩუნდებოდა; შემდეგი მოთხოვნა ისევ აგდებდა. ყველა საიტი დაზარალდა.
სიტყვა, რომელმაც ყველაფერი გასცა: ზოგჯერ
proxy-ს უკან WordPress-ის ნებისმიერ მარყუჟში პირველი ეჭვმიტანილი TLS-ია: WordPress მოთხოვნას ჩვეულებრივ HTTP-დ თვლის და უსასრულოდ ამისამართებს. მაგრამ საიტები უკვე გადაჰყავდათ X-Forwarded-Proto $_SERVER['HTTPS']-ში და აყენებდნენ FORCE_SSL_ADMIN-ს. უფრო მნიშვნელოვანი კი ის არის, რომ TLS-ის შეცდომა მარყუჟს ყოველ ჯერზე იწვევს. მარყუჟი, რომელიც დროდადრო ხდება, იმაზე მიუთითებს, რაც რეპლიკებს შორის განსხვავდება.
მიზეზი: თითოეულ პოდს საკუთარი გასაღებები ჰქონდა
WordPress ავთენტიფიკაციის cookie-ს wp-config.php-ის რვა salt კონსტანტით აწერს ხელს: AUTH_KEY, SECURE_AUTH_KEY და სხვები. ამ დეპლოიში ისინი არსად იყო განსაზღვრული — არც გარემოში, არც დამატებით კონფიგში. ოფიციალური იმიჯის entrypoint ასეთ შემთხვევაში თითოეულ პოდში შემთხვევით salt-ებს აგენერირებს.
Service-ს sessionAffinity: None ჰქონდა და ბალანსერი მოთხოვნებს რეპლიკებზე ანაწილებდა. A პოდის მიერ ხელმოწერილ cookie-ს B პოდი უარყოფდა და WordPress თავიდან შესვლას ითხოვდა. „ერთხელ შევედი“ მხოლოდ იმას ნიშნავდა, რომ ზედიზედ ორი მოთხოვნა ერთსა და იმავე პოდზე მოხვდა.
შემოწმება, რომელიც ცრუობს
ამის დამტკიცების პირველმა მცდელობამ ცრუ-უარყოფითი შედეგი მისცა. პოდებს შორის wp-config.php-ის define() სტრიქონების ჰეშები შევადარე. მაგრამ ამ სტრიქონებში კონკრეტული პოდის შემთხვევითი fallback ინახება და არა ის მნიშვნელობა, რომელსაც WordPress რეალურად იყენებს. საიმედო შემოწმება ეფექტური მნიშვნელობაა: printenv WORDPRESS_AUTH_KEY ყოველ პოდში და ჰეშების შედარება. ისინი განსხვავდებოდნენ, სწორედ ესაა არსი.
გამოსწორება Git-ის გავლით
Argo CD self-heal-ით მუშაობდა, ასე რომ kubectl-ით გამოსწორება წუთებში დაბრუნდებოდა. ყველაფერი რეპოზიტორიის გავლით წავიდა, იმ სქემით, რომელიც კლასტერში საიდუმლოებებისთვის უკვე არსებობდა:
- თითოეული საიტისთვის რვა salt ერთხელ დავაგენერირეთ და Vault-ში შევინახეთ.
- ლენდინგების საერთო ჩარტს
VaultStaticSecret-ის შაბლონი დავუმატეთ, რომ Vault Secrets Operator-მა თითოეული საიტისთვის Kubernetes Secret შექმნას. - რვა ცვლადი
WORDPRESS_*_KEYდაWORDPRESS_*_SALTამ Secret-იდან მივაწოდეთ. იმიჯი მათgetenv_docker()-ით კითხულობს, ასე რომ ყველა პოდი ერთსა და იმავე მნიშვნელობებს იყენებს.
Argo CD-მ ეს ცხრავე საიტზე maxUnavailable: 0-ით გაავრცელა, დაუნთაიმის გარეშე. salt-ების შეცვლამ ყველა ადმინი ერთხელ გამოიყვანა სისტემიდან — მოსალოდნელი და წინასწარ გაფრთხილებული.
რა უნდა დავიმახსოვროთ
- „ზოგჯერ მუშაობს“ იმ მდგომარეობის ხელწერაა, რომელიც რეპლიკებს შორის განსხვავდება. კონფიგურაციის შეცდომა ყოველ ჯერზე ფუჭდება.
- ნებისმიერ stateless აპლიკაციას, რომელიც ერთზე მეტ რეპლიკაშია sticky-ის გარეშე ბალანსერის უკან, ხელმოწერისა და სესიების საერთო გასაღებები სჭირდება. Sticky სესიები პრობლემას მხოლოდ მალავს.
- ეფექტური მნიშვნელობა პროცესის შიგნით შეამოწმე და არა კონფიგის სტრიქონი, რომელიც შეიძლება fallback აღმოჩნდეს.
- როცა Argo CD-ში self-heal ჩართულია, გამოსწორების ადგილი Git-ია და არა
kubectl.