Mengatur Probe Liveness, Readiness dan Startup
Laman ini memperlihatkan bagaimana cara untuk mengatur probe liveness, readiness, dan startup untuk Container.
Probe liveness digunakan oleh kubelet untuk mengetahui kapan perlu mengulang kembali (restart) sebuah Container. Sebagai contoh, probe liveness dapat mendeteksi deadlock, ketika aplikasi sedang berjalan tapi tidak dapat berfungsi dengan baik. Mengulang Container dengan state tersebut dapat membantu ketersediaan aplikasi yang lebih baik walaupun ada kekutu (bug).
Probe readiness digunakan oleh kubelet untuk mengetahui kapan sebuah Container telah siap untuk menerima lalu lintas jaringan (traffic). Suatu Pod dianggap siap saat semua Container di dalamnya telah siap. Sinyal ini berguna untuk mengontrol Pod-Pod mana yang digunakan sebagai backend dari Service. Ketika Pod dalam kondisi tidak siap, Pod tersebut dihapus dari Service load balancer.
Probe startup digunakan oleh kubelet untuk mengetahui kapan sebuah aplikasi Container telah mulai berjalan. Jika probe tersebut dinyalakan, probe akan menonaktifkan pemeriksaan liveness dan readiness sampai berhasil, kamu harus memastikan probe tersebut tidak mengganggu startup dari aplikasi. Mekanisme ini dapat digunakan untuk mengadopsi pemeriksaan liveness pada saat memulai Container yang lambat, untuk menghindari Container dimatikan oleh kubelet sebelum Container mulai dan berjalan.
Sebelum kamu memulai
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekankubectl version
.
Mendefinisikan perintah liveness
Kebanyakan aplikasi yang telah berjalan dalam waktu lama pada akhirnya akan bertransisi ke state yang rusak (broken), dan tidak dapat pulih kecuali diulang kembali. Kubernetes menyediakan probe liveness untuk mendeteksi dan memperbaiki situasi tersebut.
Pada latihan ini, kamu akan membuat Pod yang menjalankan Container dari image
k8s.gcr.io/busybox
. Berikut ini adalah berkas konfigurasi untuk Pod tersebut:
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: k8s.gcr.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Pada berkas konfigurasi di atas, kamu dapat melihat bahwa Pod memiliki satu Container
.
Field periodSeconds
menentukan bahwa kubelet harus melakukan probe liveness setiap 5 detik.
Field initialDelaySeconds
memberitahu kubelet untuk menunggu 5 detik sebelum mengerjakan
probe yang pertama. Untuk mengerjakan probe, kubelet menjalankan perintah cat /tmp/healthy
pada Container tujuan. Jika perintah berhasil, kode 0 akan dikembalikan, dan kubelet menganggap
Container sedang dalam kondisi hidup (alive) dan sehat (healthy). Jika perintah mengembalikan
kode selain 0, maka kubelet akan mematikan Container dan mengulangnya kembali.
Saat dimulai, Container akan menjalankan perintah berikut:
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"
Container memiliki berkas /tmp/healthy
pada saat 30 detik pertama setelah dijalankan.
Kemudian, perintah cat /tmp/healthy
mengembalikan kode sukses. Namun setelah 30 detik,
cat /tmp/healthy
mengembalikan kode gagal.
Buatlah sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml
Dalam 30 detik pertama, lihatlah event dari Pod:
kubectl describe pod liveness-exec
Keluaran dari perintah tersebut memperlihatkan bahwa belum ada probe liveness yang gagal:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
Setelah 35 detik, lihatlah lagi event Pod tersebut:
kubectl describe pod liveness-exec
Baris terakhir dari keluaran tersebut memperlihatkan pesan bahwa probe liveness mengalami kegagalan, dan Container telah dimatikan dan dibuat ulang.
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox"
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined]
36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e
2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Tunggu 30 detik lagi, dan verifikasi bahwa Container telah diulang kembali:
kubectl get pod liveness-exec
Keluaran perintah tersebut memperlihatkan bahwa jumlah RESTARTS
telah meningkat:
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 1m
Mendefinisikan probe liveness dengan permintaan HTTP
Jenis kedua dari probe liveness menggunakan sebuah permintaan GET HTTP. Berikut ini
berkas konfigurasi untuk Pod yang menjalankan Container dari image k8s.gcr.io/liveness
.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: k8s.gcr.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
Pada berkas konfigurasi tersebut, kamu dapat melihat Pod memiliki sebuah Container.
Field periodSeconds
menentukan bahwa kubelet harus mengerjakan probe liveness setiap 3 detik.
Field initialDelaySeconds
memberitahu kubelet untuk menunggu 3 detik sebelum mengerjakan
probe yang pertama. Untuk mengerjakan probe tersebut, kubelet mengirimkan sebuah permintaan
GET HTTP ke server yang sedang berjalan di dalam Container dan mendengarkan (listen) pada porta 8080.
Jika handler path /healthz
yang dimiliki server mengembalikan kode sukses, kubelet menganggap
Container sedang dalam kondisi hidup dan sehat. Jika handler mengembalikan kode gagal,
kubelet mematikan Container dan mengulangnya kembali.
Kode yang lebih besar atau sama dengan 200 dan kurang dari 400 mengindikasikan kesuksesan. Kode selain ini mengindikasikan kegagalan.
Kamu dapat melihat kode program untuk server ini pada server.go.
Untuk 10 detik pertama setelah Container hidup (alive), handler /healthz
mengembalikan
status 200. Setelah itu, handler mengembalikan status 500.
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
duration := time.Now().Sub(started)
if duration.Seconds() > 10 {
w.WriteHeader(500)
w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
} else {
w.WriteHeader(200)
w.Write([]byte("ok"))
}
})
Pemeriksaan kesehatan (health check) dilakukan kubelet 3 detik setelah Container dimulai, sehingga beberapa pemeriksaaan pertama akan berhasil. Namun setelah 10 detik, pemeriksaan akan gagal, dan kubelet akan mematikan dan mengulang Container kembali.
Untuk mencoba pemeriksaan liveness HTTP, marilah membuat sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/http-liveness.yaml
Setelah 10 detik, lihatlah event Pod untuk memverifikasi bahwa probe liveness telah gagal dan Container telah diulang kembali:
kubectl describe pod liveness-http
Untuk rilis sebelum v1.13 (termasuk v1.13), jika variabel lingkungan
http_proxy
(atau HTTP_PROXY
) telah diatur pada Node dimana Pod
berjalan, probe liveness HTTP akan menggunakan proksi tersebut.
Untuk rilis setelah v1.13, pengaturan variabel lingkungan pada proksi HTTP lokal
tidak mempengaruhi probe liveness HTTP.
Mendefinisikan probe liveness TCP
Jenis ketiga dari probe liveness menggunakaan sebuah soket TCP. Dengan konfigurasi ini, kubelet akan mencoba untuk membuka soket pada Container kamu dengan porta tertentu. Jika koneksi dapat terbentuk dengan sukses, maka Container dianggap dalam kondisi sehat. Namun jika tidak berhasil terbentuk, maka Container dianggap gagal.
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
Seperti yang terlihat, konfigurasi untuk pemeriksaan TCP cukup mirip dengan
pemeriksaan HTTP. Contoh ini menggunakan probe readiness dan liveness.
Probe readiness yang pertama akan dikirimkan oleh kubelet, 5 detik setelah
Container mulai dijalankan. Container akan coba dihubungkan oleh kubelet dengan
goproxy
pada porta 8080. Jika probe berhasil, maka Pod akan ditandai menjadi
ready. Pemeriksaan ini akan dilanjutkan oleh kubelet setiap 10 detik.
Selain probe readiness, probe liveness juga termasuk di dalam konfigurasi.
Probe liveness yang pertama akan dijalankan oleh kubelet, 15 detik setelah Container
mulai dijalankan. Sama seperti probe readiness, kubelet akan mencoba untuk
terhubung dengan Container goproxy
pada porta 8080. Jika probe liveness gagal,
maka Container akan diulang kembali.
Untuk mencoba pemeriksaan liveness TCP, marilah membuat sebuah Pod:
kubectl apply -f https://k8s.io/examples/pods/probe/tcp-liveness-readiness.yaml
Setelah 15 detik, lihatlah event Pod untuk memverifikasi probe liveness tersebut:
kubectl describe pod goproxy
Menggunakan sebuah porta dengan nama
Kamu dapat menggunakan ContainerPort dengan nama untuk melakukan pemeriksaan liveness HTTP atau TCP:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
Melindungi Container yang lambat untuk dimulai dengan probe startup
Terkadang kamu harus berurusan dengan aplikasi peninggalan (legacy) yang
memerlukan waktu tambahan untuk mulai berjalan pada saat pertama kali diinisialisasi.
Pada kasus ini, cukup rumit untuk mengatur parameter probe liveness tanpa
mengkompromikan respons yang cepat terhadap deadlock yang memotivasi digunakannya
probe_ tersebut. Triknya adalah mengatur _probe startup_ dengan perintah yang sama,
baik pemeriksaan HTTP ataupun TCP, dengan failureThreshold * periodSeconds
yang
mencukupi untuk kemungkinan waktu memulai yang terburuk.
Sehingga, contoh sebelumnya menjadi:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
Berkat probe startup, aplikasi akan memiliki paling lambat 5 menit (30 * 10 = 300 detik)
untuk selesai memulai.
Ketika probe startup telah berhasil satu kali, maka probe liveness akan
mengambil alih untuk menyediakan respons cepat terhadap deadlock Container.
Jika probe startup tidak pernah berhasil, maka Container akan dimatikan setelah
300 detik dan perilakunya akan bergantung pada restartPolicy
yang dimiliki Pod.
Mendefinisikan probe readiness
Terkadang aplikasi tidak dapat melayani lalu lintas jaringan sementara. Contohnya, aplikasi mungkin perlu untuk memuat data besar atau berkas konfigurasi saat dimulai, atau aplikasi bergantung pada layanan eksternal setelah dimulai. Pada kasus-kasus ini, kamu tidak ingin mematikan aplikasi, tetapi kamu tidak ingin juga mengirimkan permintaan ke aplikasi tersebut. Kubernetes menyediakan probe readiness sebagai solusinya. Sebuah Pod dengan Container yang melaporkan dirinya tidak siap, tidak akan menerima lalu lintas jaringan dari Kubernetes Service.
Catatan: Probe readiness dijalankan di dalam Container selama siklus hidupnya.
Probe readiness memiliki pengaturan yang mirip dengan probe liveness. Perbedaan
satu-satunya adalah kamu menggunakan field readinessProbe
, bukan field livenessProbe
.
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
Pengaturan untuk probe readiness untuk HTTP dan TCP juga sama persis dengan pengaturan untuk probe liveness.
Probe readiness dan liveness dapat digunakan secara bersamaan untuk Container yang sama. Apabila keduanya digunakan sekaligus, lalu lintas jaringan tidak akan sampai ke Container yang belum siap, dan Container akan diulang kembali (restart) saat mengalami kegagalan.
Mengatur Probe
Probe memiliki beberapa field yang dapat digunakan untuk mengendalikan pemeriksaan liveness dan readiness secara presisi.
initialDelaySeconds
: Durasi dalam detik setelah Container dimulai, sebelum probe liveness atau readiness diinisiasi. Nilai bawaannya adalah 0 detik. Nilai minimalnya adalah 0.periodSeconds
: Seberapa sering (dalam detik) probe dijalankan. Nilai bawaannya adalah 10 detik. Nilai minimalnya adalah 0.timeoutSeconds
: Durasi dalam detik setelah probe mengalami timeout. Nilai bawaannya adalah 1 detik. Nilai minimalnya adalah 0.successThreshold
: Jumlah minimal sukses yang berurutan untuk probe dianggap berhasil setelah mengalami kegagalan. Nilai bawaannya adalah 1. Nilanya harus 1 untuk liveness. Nilai minimalnya adalah 1.failureThreshold
: Ketika sebuah Pod dimulai dan probe mengalami kegagalan, Kubernetes akan mencoba beberapa kali sesuai nilaifailureThreshold
sebelum menyerah. Menyerah dalam kasus probe liveness berarti Container akan diulang kembali. Untuk probe readiness, menyerah akan menandai Pod menjadi "tidak siap" (Unready). Nilai bawaannya adalah 3. Nilai minimalnya adalah 1.
Probe HTTP
memiliki field-field tambahan yang bisa diatur melalui httpGet
:
host
: Nama dari host yang akan terhubung, nilai bawaannya adalah IP dari Pod. Kamu mungkin juga ingin mengatur "Host" pada httpHeaders.scheme
: Skema yang digunakan untuk terhubung pada host (HTTP atau HTTPS). Nilai bawaannya adalah HTTP.path
: Path untuk mengakses server HTTP.httpHeaders
: Header khusus yang diatur dalam permintaan HTTP. HTTP memperbolehkan header yang berulang.port
: Nama atau angka dari porta untuk mengakses Container. Angkanya harus ada di antara 1 sampai 65535.
Untuk sebuah probe HTTP, kubelet mengirimkan permintaan HTTP untuk path yang ditentukan
dan porta untuk mengerjakan pemeriksaan. Probe dikirimkan oleh kubelet untuk alamat IP Pod,
kecuali saat alamat digantikan oleh field opsional pada httpGet
. Jika field scheme
diatur menjadi HTTPS
, maka kubelet mengirimkan permintaan HTTPS dan melewati langkah verifikasi
sertifikat. Pada skenario kebanyakan, kamu tidak menginginkan field host
.
Berikut satu skenario yang memerlukan host
. Misalkan Container mendengarkan permintaan
melalui 127.0.0.1 dan field hostNetwork
pada Pod bernilai true. Kemudian host
, melalui
httpGet
, harus diatur menjadi 127.0.0.1. Jika Pod kamu bergantung pada host virtual, dimana
untuk kasus-kasus umum, kamu tidak perlu menggunakan host
, tetapi perlu mengatur header
Host
pada httpHeaders
.
Untuk probe TCP, kubelet membuat koneksi probe pada Node, tidak pada Pod, yang berarti bahwa
kamu tidak menggunakan nama Service di dalam parameter host
karena kubelet tidak bisa
me-resolve-nya.
Selanjutnya
- Pelajari lebih lanjut tentang Probe Container.
Kamu juga dapat membaca rujukan API untuk: