오랜 시간 동안 실행되는 많은 응용 프로그램은 문제가 발생하면 중단된 상태로 전환되며 다시 시작해야만 복구할 수 있다.
Kubernetes는 이러한 상황을 감지하고 해결하기 위한 liveness probe를 제공한다.
이 연습에서는 registry.k8s.io/busybox
이미지를 기반으로 컨테이너를 실행하는 Pod를 만든다.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: registry.k8s.io/busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
periodSeconds: kubelet이 5초마다 liveness probe를 수행하도록 지정
initialDelaySeconds: 첫 번재 probe를 수행하기 전에 5초 기다리는 것을 지정
/bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600": 처음 30초동안은 성공 코드를 반환, 30초 후에는 실패 코드를 반환하는 것을 지정
명령이 성공하면 0을 반환하고 kubelet은 컨테이너가 살아 있고 건강한 것으로 간주한다.
명령이 0이 아닌 값을 반환하면 kubelet은 컨테이너를 종료하고 다시 시작한다.
kubectl apply -f exec-liveness.yaml
kubectl describe pod liveness-exec
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12s default-scheduler Successfully assigned default/liveness-exec to minikube
Normal Pulling 9s kubelet Pulling image "registry.k8s.io/busybox"
Normal Pulled 6s kubelet Successfully pulled image "registry.k8s.io/busybox" in 3.120555208s (3.120582984s including waiting)
Normal Created 6s kubelet Created container liveness
Normal Started 6s kubelet Started container liveness
아직 Unhealthy 없이 정상이다.
kubectl describe pod liveness-exec
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 95s default-scheduler Successfully assigned default/liveness-exec to minikube
Normal Pulled 89s kubelet Successfully pulled image "registry.k8s.io/busybox" in 3.120555208s (3.120582984s including waiting)
Warning Unhealthy 44s (x3 over 54s) kubelet Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Normal Killing 44s kubelet Container liveness failed liveness probe, will be restarted
Normal Pulling 14s (x2 over 92s) kubelet Pulling image "registry.k8s.io/busybox"
Normal Created 12s (x2 over 89s) kubelet Created container liveness
Normal Started 12s (x2 over 89s) kubelet Started container liveness
Unhealthy가 생겼고 해당 컨테이너가 종료되고 다시 생성됐음을 알 수 있다.
kubectl get pod liveness-exec
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 1 (72s ago) 2m33s
RESTARTS가 1회 증가되었음을 알 수 있다.
RESTARTS는 실패한 컨테이너가 다시 생성됐을 때, 즉시 숫자가 증가한다.
다른 종류의 liveness probe는 HTTP GET 요청을 사용한다.
다음은 registry.k8s.io/liveness
이미지를 기반으로 컨테이너를 실행하는 Pod를 만든다.
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness
image: registry.k8s.io/liveness
args:
- /server
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
periodSeconds: kubelet이 3초마다 liveness probe를 수행하도록 지정
initialDelaySeconds: 첫 번재 probe를 수행하기 전에 3초 기다리는 것을 지정
probe를 수행하기 위해 kubelet은 컨티이너에서 실행 중이고 포트 8080에서 수신 대기 중인 서버에 HTTP GET 요청을 보낸다.
서버의 경로에 대한 핸들러가 성공 /healthz
코드를 반환하면 kubelet은 컨테이너가 살아 있고 건강한 것으로 간주한다.
핸들러가 실패 코드를 반환하면 kubelet은 컨테이너를 종료하고 다시 시작한다.
200번대, 300번대 코드는 성공을 나타낸다.
다른 코드는 실패를 나타낸다.
server.go에서 서버의 소스 코드를 볼 수 있다.
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"))
}
})
컨테이너가 활성 상태인 처음 10초 동안 /healthz 핸들러는 상태 코드 200을 반환한다.
그 후 핸들러는 상태 코드 500을 반환한다.
위의 yaml 파일에서 컨테이너가 시작된 후 3초 기다린 후에 상태 확인을 시작하고 3초마다 상태 확인을 하니, 첫 번째 두 개의 상태 확인은 성공한다.
그러나 10초 후에는 상태 확인에 실패하고 kubelet이 컨테이너를 종료하고 다시 시작한다.
kubectl apply -f liveness-http.yaml
kubectl describe pod liveness-http
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 27s default-scheduler Successfully assigned default/liveness-http to minikube
Normal Pulled 23s kubelet Successfully pulled image "registry.k8s.io/liveness" in 2.507501709s (2.507541747s including waiting)
Normal Pulling 5s (x2 over 26s) kubelet Pulling image "registry.k8s.io/liveness"
Warning Unhealthy 5s (x3 over 11s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 500
Normal Killing 5s kubelet Container liveness failed liveness probe, will be restarted
Normal Created 4s (x2 over 23s) kubelet Created container liveness
Normal Pulled 4s kubelet Successfully pulled image "registry.k8s.io/liveness" in 1.552769347s (1.55277954s including waiting)
Normal Started 3s (x2 over 23s) kubelet Started container liveness
10초 이후 Unhealthy가 생겼고 해당 컨테이너가 종료되고 다시 생성됐음을 알 수 있다.