K8s liveness ve readiness kontrollerini nasıl yapsak?

Bu yazı, liveness ve readiness probelardaki potansiyel riskleri de göz önüne alarak nasıl kullanmalıyız üzerinde sesli bir düşünce amacı taşımaktadır.

Liveness/Readiness Probelar Nedir?

Diyelim ki container içindeki servisler tepki vermiyor, multi-threadde bir sıkıntı var. Podu otomatik yeniden başlatmak sorun çözülene kadar en azından uygulamanın hizmet verebilmesi için geçici bir çözüm olabilir. En azından bunun için birini aramaktan daha iyi bir çözüm olacaktır. Bunun için liveness probeları kullanılır.

Readiness probeları da pod içinde ayağa kalkan containerlar hizmet vermeye hazır mı sorusunu sormak için kullanılmaktadır. Örneğin pod içindeki container ayağa kalkarken db’de ufak bir işlem yapması lazım, sonra ayaklanan container başka bir x servisinden konfigurasyon verisi çekip hazır hale gelecek. Bunun da 10 sn sürdüğünü varsayarsak bu süre öncesinde trafik yönlendirilmesi sadece client-side hata alınmasına sebep olacaktır. Bir şekilde hazır hale gelmediyse trafik hiç yönlendirilmez böylece gereksiz hata alma riski de oluşmayacaktır.

2 probe için de aşağıdaki kontroller pod sağlığını incelemek için kullanılabilir.

  • Http request atma
  • Tcp socket kontrolü
  • Containerda komut çalıştırma

Aşağıdaki şekilde de üstteki kontrollerin konfigurasyonları yapılır.

...
containers:
- name: ...
readinessProbe/livenessProbe:
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 5
httpGet:
path: /service-name/isready
port: 8080
tcpSocket:
port: 5432
exec:
command:
- cat..

Hızlıca üzerlerinden geçmek gerekirse: initialDelaySeconds, container kontrole girmeden önce beklenecek süre, periodSeconds kontrolün tekrarlanacağı süre ve failureThreshold’da kaç kere hata alınırsa podu gömebiliriz veya restartlayabilirizi belirliyor.

Olası sorunlar

İlk önce şu bilgiyi en tepeye yazayım: Readiness ve Liveness probeları sürekli çalışır.

Readiness Probe riskleri

Biraz acemi de olsam görebildiğim örneklerde her container tanımında readiness probe mutlaka olmalı şeklinde bir yaklaşım var. Tamam, container hazır olmadan trafik yönlendirmeyelim de, container hayattayken her daim çalışacak ve ayarları düzgün yapmazsak kritik bir batch çalışırken, networkte anlık bir yavaşlıkta, ani bir yük bindiğinde üstteki tanımlara yetecek şekilde ve sayıda cevap alınamazsa containere erişim kesilir, kalan diğer containerlara yük biner ve bunlar da bir süre sonra down olabilir.

Bunun yerine hazır ne demek onu biraz düşünebiliriz. Örneğin hazır mı sorusuna cevap aradığımız http requestimizi bağımlılık olan diğer containerlardan da cevap aldıktan sonra hazır olduğunu sunan bir başka servise yönlendirebiliriz. Aynı durum init, vb senaryoları tamamladıktan sonra da geçerli olabilir. Multi-dependency durumlarda (init, başka container ayaklanması, vb) hepsi için checklist olarak dönüş alınca ok dönen bir servise bakabilir probe. Bu şekilde servise probe geldiğinde tüm kontrolleri tam olan bir pod olacak ve bir hata varsa ayıklaması daha kolay olacaktır.

Bu yapı mantıklı gibi görünse de, ready olmak için başka servislerden teyit alması demek, networkte geçici bir yavaşlık, bağlı serviste anlık GC işlemi veya anlık yoğun trafik olması halinde ve readiness probe’un deault timeout’u olan 1sn’den yavaş cevap gelmesi durumunda container trafik almayacaktır. Bu şekilde podların birbiriyle ilişkisine göre hepsi fail olabilir. Uptime’ı arttıralım derken sistemi single point of failure’a yaratarak patlatmış olduk. Bu senaryoda hiçbirşey yapmasak ve kullanıcı biraz yavaş da olsa cevap alsa daha mantıklı olurdu :D.

Özetle probelanan alan bağımsızsa acımamak mantıklı olabilir ama örneğin ortak servisinden cevap beklemeniz gerekiyorsa x servisiniz için, probe kontrollerinde daha esnek davranmak faydalı olabilir.

  • Eğer ortak bir dependancy’den cevap bekliyorsanız, karşı servisin max resp time’ından fazla probe timeout eklemek mantıklı olacaktır. Bu şekilde diğer dependency ölmüş diyebiliriz.
  • failureThreshold parametresi, probe kontrol sıklığına göre yüksek tutulması gerekebilir. Anlık sorunlar, periyodik bakım, vb işlemler olabilir. Düşük threshold yüzünden ilgili tüm podların ortak dependency servisine bakım yapılırken çökmesi büyük sıkıntı yaratacaktır.

Liveness Probe riskleri

Liveness probeları sistem gerçekten çalışıyor mu kontrolü için var. Buradaki olası sorunlardan biri şu olabilir; örneğin 2 servisi olan bir containerda 1 de liveness probe için kontrol servisi (/app/live)bulunsun. Biz diğer 2 servise bakmadan live endpointine gidersek anında cevap alacağız ama diğer 2 servis cevap bile veremiyor olabilir. Bu yüzden liveness kontrolleri de üstteki gibi ilişkili kritik servislere de dokunuyor olması gerekiyor.

Ancak bu şekilde readiness ile aynı soruna geri geliyoruz. Yine aynı şekilde kriterlere uymayacak bir cevap süresi olması halinde tam yoğun yük varken pod restart olacak ve diğer podları patlatabilecek bir süreç başlatmış olabiliriz.

Liveness kontrollerinde bir chaos bonusu da, servisinizin altyapısında bir değişiklik sebebiyle container verdiğimiz 10sn initialDelaySeconds yerine artık 13sn’de ayağa kalkıyor. Bu da tahmin ettiğiniz gibi asla ayağa kalkmayan ve sürekli restart olan bir pod demek. Mimaride bu gibi değişiklikleri sürekli takip etmek gerekiyor. Network topoloji değişikliklerinde, örneğin sanal hava boşluğu cihazlarından vlanlar arası geçiş oluyorsa, sunucu bakımlarında (vm’lerin hostlar arası otomatik taşınması konuları) uptime için dikkat etmek gerekecektir.

Bu konuyla ilgili de bir pod’un haftalardır ayakta olması iyi bir şey mi yoksa safe zaman dilimlerinde kontrollü olarak podların otomatik resetlenmesi mantıklı olabilir mi tartışılabilir.

  • Liveness probe timeoutları sistem genelinde meydana gelebilecek problemleri kaldıramayacak kadar ucu ucuna olmamalı. Belki client timeout süreleri kadar olması değerlendirilebilir.
  • initialDelaySeconds kod içeriğindeki değişiklerde anında patlayacak kadar az olmamalı.
  • Mümkün olan podlar safe zamanlarda yeniden başlatılsa geleneksel bilgisayar mühendisliği görevimizi de (kapat/aç denedin mi) yapmış oluruz.

Özet

liveness ve readinesslar beraber kullanılması gereken kritik araçlar ancak yanlış tanımlanırsa bir sisteme uygulamadaki hatalar veya yükten daha fazla zarar verebilir.

Bu sınırlar planlanırken aşağıdakiler unutulmamalı;

  • Sistemde uygulama ekibinin kontrolünde olmayabilecek veya hatalı bir şekilde bilgi verilmeden network, sistem, vb manuel çalışma yapılması gereken durumlar olabilir.
  • Sistem donanımlarında geçici fiziksel bir arıza oluşabilir. 3 Hosttan biri arızaya düştü, tüm vm’ler diğer 2 hostta hayatta kalmaya çalışıyor, bazı vm’ler kapandı vb.
  • Ops personeli yanlışlıkla kritik bir podu kapatıp patch çıkarken nasıl olsa kullanan yok diye mola, vs için geçici olarak ayrılabilir. Bu sırada probelar yüzünden diğer podlar da patlayıp varsa çalışan batch işler de hata alacak duruma girilmemeli.
  • Yeni eklenen bir containerda sistem genelinde yavaşlık oluşturabilecek yazılım hatası var. Çözüm 1–2 gün sürebilir. Sistemin probelar yüzünden ölmemesi gerekiyor.

Just a software everything fighting battles against mostly myself, and gaining small victories lately.

Just a software everything fighting battles against mostly myself, and gaining small victories lately.