Kubernetes Readiness ve Liveness Nedir?
Kubernetes Readiness ve Liveness, uygulamaların sağlığını izlemede kullanılan Kubernetes özellikleridir. Uygulamaların sağlık durumlarını takip ederek hizmet kesintileri önleyebilir ve uygulamalarınıza otomatik onarım yeteneği kazandırabilirsiniz.
1. Readiness Probe Nedir?
Readiness, bir uygulamanın hizmet vermeye hazır olup olmadığını belirler. Yani uygulama, kullanıcılardan gelen taleplere cevap verebilecek hale gelmiş mi, yoksa henüz hazır değil mi sorusunun cevabı Readiness probe ile verilir. Örneğin, uygulamanın başlatılması birkaç saniye sürüyor olabilir veya veritabanı bağlantısının kurulması gecikebilir. Bu durumlarda, "readiness" durumunu kontrol eden bir mekanizma, uygulamanın kullanıcılara sunulmadan önce hazır olup olmadığını doğrulayabilir.
Readiness probe, periyodik olarak çağrılır ve bir Pod'un client isteklerini alıp almayacağını belirler. Bir container, readiness probe'a başarılı sonuç döndüğünde, ilgili Pod, istekleri kabul etmeye hazır olarak işaretlenir. Eğer başarılı sonuç dönmezse Pod Unhealthy
olarak işaretlenir ve Pod'u yöneten bir Servis varsa ilgili Pod'a trafiği yönlendirmez.
2. Liveness Probe Nedir?
Liveness, uygulamanın doğru şekilde çalışıp çalışmadığını düzenli olarak kontrol eder. Uygulama, beklenmeyen bir şekilde çöktüğünde veya donduğunda, liveness durumunu kontrol eden mekanizma bu durumu tespit eder ve uygun bir şekilde işlem yapar. Bu işlem, uygulamanın yeniden başlatılması, kapatılması veya yedek uygulamanın devreye sokulması olabilir.
Normalde bir Container hata verip kapandığında restartPolicy
ayarlıysa yeniden başlatılır. Fakat bazen container içindeki uygulamanızda bir sorun olduğunda, uygulama çalışmaya devam edip Container'ı canlı tutsa bile, uygulama doğru bir çalışma tutumu sergilemiyor olabilir. Örneğin bir Java uygulaması çalışırken sürekli OutOfMemoryError hatası atıyor olabilir veya daha farklı sebepler yüzünden beklenen gibi çalışmayabilir. Bu durumda restartPolicy
devreye girmez çünkü JVM uygulamayı halen ayakta tutuyordur. Bu tip senaryolar için Liveness probe hayat kurtarıcıdır.
Tıpkı Readiness probe gibi, Liveness probe da periyodik olarak çağrılır ve uygulamanın sağlıklı olup olmadığı belirlenir. Eğer sağlıklı değilse Pod içindeki container'lar yeniden başlatılır.
2. Readiness ve Liveness Probe Tipleri, Parametreleri ve Loglar
Hem Readiness hem de Liveness probe oluşturmak için üç farklı yöntem vardır. Uygulamanızın nasıl çalıştığına bağlı olarak herhangi bir yöntemi seçip kullanabilirsiniz.
Exec
probe: Container içinde shell komutu execute edilir. Probe'un durumu bu process'in exit koduna göre belirlenir.HTTP GET
probe: Container'ın belirttiğiniz bir endpointine HTTP GET isteği atılır. Response kodu 2xx ve 3xx ise sağlıklı, değilse sağlıksız olarak işaretlenir.TCP Socket
probe: Container'ın belirlenen bir portuna bir TCP bağlantısı açılmaya çalışılır. Eğer bağlantı kurulursa sağlıklı, kurulamazsa sağlıksız olarak işaretlenir.
Ayrıca tüm probe'larda ortak kullanabileceğiniz bazı parametreler vardır. Bu parametreler ve açıklamaları şu şekildedir:
initialDelaySeconds
: Container'ın başlatılmasından sonra ilk kontrollerin ne kadar süre sonra başlayacağını belirten değerdir.periodSeconds
: Kontroller arasındaki süreyi belirten değerdir.timeoutSeconds
: Kontrol işleminin kaç saniye içinde tamamlanması gerektiğini belirten değerdir. Bu süre geçtiği halde komut tamamlanmazsa başarısız sayılır.successThreshold
: Sağlıklı sayılabilmesi için kontrolün kaç kez ardışık başarılı olması gerektiğini belirten değerdir.failureThreshold
: Sağlıksız sayılabilmesi için kontrolün kaç kez ardışık başarısız olması gerektiğini belirten değerdir.
failureThreshold
değerini 1 ayarlamak mantıklı değildir. Bu gibi nedenlerle varsayılan olan 3 değerini kullanmak için bu parametreyi eklemeyebilirsiniz. Son olarak ise Pod içindeki container liveness probe'un onu sağlıksız olarak işaretlemesi sonucu kapandıysa ve yeni bir container başladıysa, yine de kubectl logs mypod --previous
komutu ile kapatılan container'ın loglarına erişebiliriz. Böylece sorunun ne olduğunu inceleme şansınız olur.
Şimdi her bir probe tipini örneklerle inceleyelim.
2.1. Exec Probe
Exec probe, belirli bir komutu pod içindeki bir container içinde çalıştırır ve sonucuna göre sağlık durumunu belirler.
apiVersion: v1
kind: Pod
metadata:
name: exec-probe-pod
spec:
containers:
- name: readiness
image: registry.k8s.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
Bu pod, 5sn bekledikten sonra (initialDelaySeconds
), her 10 saniyede bir (periodSeconds
) komutu çalıştırarak sonucunu değerlendirir. Komut 1 saniyeden uzun sürerse (timeoutSeconds
), probe başarısız sayılacaktır. Success threshold, yani kaç defa üst üste başarılı sonuç alınması gerektiği (successThreshold
), burada 1 olarak ayarlanmıştır. Aynı şekilde, kaç defa üst üste başarısız sonuç alınması durumunda (failureThreshold
) container'ın sağlıksız sayılacağı belirtilir.
Örnekte /tmp/healthy
dosyası ilk 30sn boyunca olacağı için Pod Healthy ve Ready olarak işaretlenecek fakat 30. sn den sonra yapılan kontrollerde dosya olmayacağı için Unhealty ve NotReady olarak işaretlenecektir.
Liveness probe ise 60.sn den sonra devreye girecek ve dosyayı bulamadığı için container'ı yeniden başlatacaktır.
$ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
exec-probe-pod 0/1 Running 0 12s
exec-probe-pod 1/1 Running 0 21s
exec-probe-pod 0/1 Running 0 61s
exec-probe-pod 0/1 Running 1 (7s ago) 2m8s
exec-probe-pod 1/1 Running 1 (20s ago) 2m21s
kubectl describe
komutuyla baktığımızda ise event ve detayları görebilirsiniz.
$ kubectl describe pod exec-probe-pod
•••
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
•••
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
•••
Normal Scheduled 3m24s default-scheduler Successfully assigned default/exec-probe-pod to minikube
Normal Pulled 3m17s kubelet Successfully pulled image "registry.k8s.io/busybox" in 6.473781714s (6.473799548s including waiting)
Warning Unhealthy 114s (x3 over 2m14s) kubelet Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Normal Killing 114s kubelet Container readiness failed liveness probe, will be restarted
Normal Pulling 84s (x2 over 3m24s) kubelet Pulling image "registry.k8s.io/busybox"
Normal Created 78s (x2 over 3m17s) kubelet Created container readiness
Normal Started 78s (x2 over 3m17s) kubelet Started container readiness
Normal Pulled 78s kubelet Successfully pulled image "registry.k8s.io/busybox" in 6.444312214s (6.444332022s including waiting)
Warning Unhealthy 34s (x13 over 2m44s) kubelet Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory
2.2. HTTP Get Probe
HTTP Get probe, uygulamanızın belirlediğiniz bir endpointine HTTP Get isteği gönderir ve sonucuna göre sağlık durumunu belirler. Probe'un başarılı sayılabilmesi için response kodunun 2xx veya 3xx olması gerekir.
apiVersion: v1
kind: Pod
metadata:
name: http-probe-pod
spec:
containers:
- name: my-app
image: my-image:latest
readinessProbe:
httpGet:
path: /health
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
Exec probe örneğinde detaylı açıklama ve örnek verdiğimiz için burada sadece probe syntax'ını gösterip sıradaki başlığa geçiyoruz. Dilerseniz livenessProbe
içinde readinessProbe
'da kullandığımız aynı syntax'ı kullanabilirsiniz.
2.3. TCP Socket Probe
TCP socket probe, uygulamanızın belirlediğiniz bir portuna socket bağlantısı yapmaya çalışır ve sağlık durumunu belirler.
apiVersion: v1
kind: Pod
metadata:
name: tcp-probe-pod
spec:
containers:
- name: my-app
image: my-image:latest
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
Exec probe örneğinde detaylı açıklama ve örnek verdiğimiz için burada sadece probe syntax'ını gösterip sıradaki başlığa geçiyoruz. Dilerseniz readinessProbe
içinde livenessProbe
'da kullandığımız aynı syntax'ı kullanabilirsiniz.
3. Container Exit Code
Bir container'a Liveness probe ayarlarsanız ve unhealthy bir durumda container yeniden başlatılırsa kubectl describe
komutunun çıktısında LastState
altında Exit Code
değerini görebilirsiniz.
$ kubectl describe pod mypod
•••
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Wed, 10 May 2023 14:44:24 +0300
Finished: Wed, 10 May 2023 14:46:18 +0300
•••
Container'ın neden terminate edilğine dair alınan kodu 137 olarak görüyoruz. B değerlerin özel bir anlamı vardır.
137 sayısı, iki sayının toplamıdır: 128+X
. Burada X
, sürecin sonlanmasına neden olan işleme gönderilen sinyal numarasıdır. Örnekte x, SIGKILL sinyalinin numarası olan 9'a eşittir, yani çalışan process force kill ile sonlandırılmıştır.
Eğer bu sayı 143 olsaydı, X
değeri 15 yani SIGTERM sinyali kullanılmış anlamına gelecekti.
Sıradaki yazı ile eğitim serisine devam edebilirsiniz.