서론
해당 글은 일프로 님의 인프런 강의 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2의 내용을 정리한 글입니다.
해당 글에 사용된 내용, 사진 및 그림은 모두 강의와 강의 자료에 포함된 내용입니다.
Probe 기본 개념
![](https://velog.velcdn.com/images/appti/post/69029212-031b-4af9-947e-7029cd868c48/image.png)
예제 환경
- 세 개의 Probe가 존재
- startupProbe
- periodSeconds : 10
- 10초마다 /ready 엔드 포인트로 요청해 기동 상태 확인
- successThreshold : 1
- failureThreshold : 10
- readinessProbe
- periodSeconds : 10
- 10초마다 /ready 엔드 포인트로 요청해 트래픽을 전달할 수 있는 상태인지 확인
- 성공 시 서비스 활성화, 실패 시 연결 종료
- successThreshold : 1
- failureThreshold : 2
- livenessProbe
- periodSeconds : 10
- 10초마다 /ready 엔드 포인트로 요청해 애플리케이션이 정상 동작하는지 모니터링
- 실패 시 애플리케이션 재시작
- 컨테이너 애플리케이션에는 /url이라는 엔드 포인트가 존재
동작 과정
- 컨테이너 내 애플리케이션이 기동 중인 경우
1.1 기동이 될 때 까지 startupProbe는 계속 실패
1.2 failureThreadhold를 10으로 설정했으므로 10회 실패 전 응답이 있으면 성공으로 간주
그림에서는 3회만에 성공했다고 가정
1.3 쿠버네티스에서 성공한 startupProbe를 중단하고, readinessProbe와 livenessProbe 트리거
- 애플리케이션이 사라있는 동안 10초 간격으로 readinessProbe와 livenessProbe가 /ready 엔드 포인트로 요청, 200 OK 결과 반환
- 애플리케이션에 문제가 생겨 /ready 엔드 포인트로 요청했을 때 실패
3-1. readinessProbe 실패로 인해 서비스 비활성화 및 외부와의 연결 종료, livenessProbe 실패로 인해 애플리케이션 재시작
의문점
- 왜 3개의 probe가 모두 동일한 url을 호출하고 있는지?
- 동일한 엔드 포인트로 인한 요청이 실패할 경우 3개의 probe가 모두 실패
- probe를 하나를 사용하나 3개를 사용하나 동작에는 차이가 없는 상태
- 각 probe의 용도를 파악하고 정확하게 사용할 필요가 있음
Application 로그를 통한 Probe 동작 분석
사전 작업
// HPA minReplica 1로 바꾸기 - Master Node
kubectl patch -n anotherclass-123 hpa api-tester-1231-default -p '{"spec":{"minReplicas":1}}'
- 로그 식별의 편의성을 위해 minReplica를 2에서 1로 변경
![](https://velog.velcdn.com/images/appti/post/2104844d-d3de-4abc-b2d5-c8d5e70ef283/image.png)
실습
![](https://velog.velcdn.com/images/appti/post/0fc7a033-a84e-4871-ba15-1a70708f6405/image.png)
![](https://velog.velcdn.com/images/appti/post/ff6211bc-7172-49b2-b117-8adbfbd03b85/image.png)
![](https://velog.velcdn.com/images/appti/post/71805594-4e3d-4368-8f79-104313516f2c/image.png)
- 애플리케이션 기동 완료
- startupProbe 성공
- readinessProbe, livenessProbe 트리거
- 아직 ConfigMap등의 초기화 작업이 끝나지 않았으므로 readinessProbe 실패
- 애플리케이션이 기동 중이므로 livenessProbe 성공
![](https://velog.velcdn.com/images/appti/post/bf31445d-1683-4c92-b3c4-634181a5afcb/image.png)
- 애플리케이션 초기화 작업 완료
- readinessProbe, livenessProbe 모두 성공
- 앞으로 애플리케이션이 기동하는 동안 10초 간격으로 헬스 체크 수행
로그 분석
![](https://velog.velcdn.com/images/appti/post/0853c93f-9d9f-458a-b901-181186b0bd03/image.png)
- App 초기화 단계
- 스프링 부트의 DispatcherServlet 초기화
- 초기화가 완료되기 전에는 startupProbe는 실패하다가 완료된 이후 성공
- 로그의 경우 임의로 애플리케이션 내부에서 출력했기 때문에 실제로 애플리케이션이 동작을 하자마자 startupProbe가 호출되고 실패함
- User 초기화 단계
- 예시에서는 ConfigMap을 초기화하는 과정
- readinessProbe는 실패, livenessProbe는 성공
- 모든 초기화 완료 후
- readinessProbe, livenessProbe 모두 성공
- 10초마다 헬스 체크 수행
Application 동작 중심의 Probe 이해
- 쿠버네티스의 요구사항에 따라 Probe 동작 이해
- 쿠버네티스는 애플리케이션을 편리하게 관리하기 위한 도구
- 애플리케이션 동작을 기반으로 분석
![](https://velog.velcdn.com/images/appti/post/6521c573-39f1-461d-8799-65f572b32d8a/image.png)
-
애플리케이션 동작
- 애플리케이션 초기화
- User 초기화
- 애플리케이션 기동
- 애플리케이션 장애 발생
-
자동화 요구사항
- 애플리케이션 초기화 수행 -> 초기화가 끝나지 않았기 때문에 API를 받을 수 없음 -> 초기화가 끝났는지 애플리케이션 상태 체크 필요
1-1. 외부 API 접근 금지 -> 애플리케이션이 초기화되지 않았기 때문
- 애플리케이션 초기화 완료, User 초기화 수행 -> 초기화가 끝났기 때문에 API를 받을 수 있음 -> 애플리케이션이 살아있는지 상태 체크 필요
2-1. 외부 API 접근 금지 -> 애플리케이션만이 초기화되었고 정상적으로 서비스를 제공하기 위한 User 초기화 작업이 수행 중이기 때문
- 애플리케이션 기동 -> 애플리케이션 초기화 & User 초기화 작업 모두 수행 완료 -> 애플리케이션이 살아있는지 상태 체크 필요 (L4 스위치로 외부 트래픽 허용 처리)
3-1. 외부 API 접근 허용 -> 서비스를 정상적으로 제공하기 위한 모든 준비가 끝났기 때문
- 애플리케이션 장애 발생 -> 애플리케이션 재기동 필요
-
쿠버네티스 제공 기능
- 애플리케이션 초기화 -> startupProbe를 통해 판단
1-1. service와 파드는 selector로 연결을 했지만 쿠버네티스는 실제 연결을 하지 않음
- 애플리케이션 초기화 완료, User 초기화 수행 -> startupProbe 중단, livenessProbe, readinessProbe 트리거
2-1. livenessProbe는 설정된 API를 계속 호출하며 정상적인 상황이라면 항상 성공하고, 실패한다면 비정상적인 상황이므로 파드 재기동
2-2. readinessProbe는 User 초기화 완료 전까지 계속 실패 -> 성공 시 service와 파드를 연결해 외부 트래픽 접속 허용
2-3. readinessProbe가 API 호출을 실패하면 service와 파드를 분리해 외부 트래픽 접속 차단
2-4. readinessProbe가 API 호출을 다시 성공하면 service와 파드를 다시 연결해 외부 트래픽 접속 허용
-
readinessProbe의 용도
- 애플리케이션이 기동이 된 상태지만 의도적으로 외부 트래픽을 받지 않게 사용
- 이러한 의도에 따라 readinessProbe와 livenessProbe가 동일한 url을 받게 할지, 분리할지가 결정됨
-
정리
- startupProbe
- 애플리케이션의 기동 상태를 확인해 애플리케이션이 정상적으로 초기화되기 전 외부 트래픽을 차단하고자 할 때 사용
- 스프링 부트 애플리케이션의 ApplicationContext refresh 과정이 다 끝나지 않아 API 호출을 아예 수행하지 못할 때 사용
- readinessProbe
- 애플리케이션이 기동되었지만, 외부 트래픽을 차단하고자 할 때 사용
- 스프링 부트 애플리케이션의 초기화는 모두 끝났으나, 정상적인 서비스를 제공하기 위해 필요한 전처리 작업을 수행할 때 사용
- livenessProbe
- 애플리케이션의 기동 상태를 확인해 애플리케이션이 비정상적인 상태일 때 파드를 재기동하기 위해 사용
-
주의사항
- readinessProbe나 livenessProbe는 애플리케이션이 죽을 때 까지 주기적으로 헬스 체크를 수행하므로 이러한 API는 최대한 비용이 적게 처리해야 함
API 날려보며 Probe 동작 확인하기
![](https://velog.velcdn.com/images/appti/post/17eda1b7-b460-4e63-9e0b-c03b0f023268/image.png)
curl http://192.168.56.30:31231/hello
![](https://velog.velcdn.com/images/appti/post/d75a6e2b-dbea-45e1-a4b3-46b2c1f87763/image.png)
- 애플리케이션 초기화 단계
- 애플리케이션이 기동 중이기 때문에 외부 API 실패
![](https://velog.velcdn.com/images/appti/post/86fbc2c5-ef86-426c-8ef4-948d6f2ed01c/image.png)
curl http://192.168.56.30:31231/hello
kubectl exec -n anotherclass-123 -it api-tester-1231-75dd57f8cb-tpdpb -- curl localhost:8080/hello
![](https://velog.velcdn.com/images/appti/post/8cf163c7-3db4-44ea-aa24-277ebb0517a7/image.png)
- 애플리케이션 초기화 이후 User 초기화 단계
- 내부 API는 성공하지만, 외부 API를 수행하기에는 모든 초기화 작업이 수행되지 않았으므로 실패
![](https://velog.velcdn.com/images/appti/post/ac2fdd76-0960-4967-b5a7-89787d280870/image.png)
curl http://192.168.56.30:31231/hello
kubectl exec -n anotherclass-123 -it api-tester-1231-75dd57f8cb-tpdpb -- curl localhost:8080/hello
![](https://velog.velcdn.com/images/appti/post/0f34838b-95dd-476e-b8a8-c6131913a5c4/image.png)
- 애플리케이션 초기화, User 초기화 모두 성공
- 이후 startupProbe 비활성화, readinessProbe와 livenessProbe 트리거
curl http://192.168.56.30:31231/traffic-off
curl http://192.168.56.30:31231/hello
![](https://velog.velcdn.com/images/appti/post/f60a74ab-d41f-4ab5-9935-8a7eb856f432/image.png)
- readinessProbe 실패로 인해 외부 트래픽 접근 금지
![](https://velog.velcdn.com/images/appti/post/1bbc6b6c-14d9-4ea8-acc6-a62253cb2bfa/image.png)
kubectl exec -n anotherclass-123 -it api-tester-1231-75dd57f8cb-tpdpb -- curl localhost:8080/traffic-on
![](https://velog.velcdn.com/images/appti/post/cb2ebbb6-3aae-4bf7-bdb2-ba5704b46a70/image.png)
curl http://192.168.56.30:31231/server-error
![](https://velog.velcdn.com/images/appti/post/014f5927-54c6-4e9e-beab-7b45a8e531d3/image.png)
- readinessProbe 3번 실패로 인해 파드 재기동
일시적인 장애 상황에서의 Probe 활용
![](https://velog.velcdn.com/images/appti/post/66072b4c-ee4f-4c1c-8192-d00c1a796de4/image.png)
- 문제 상황
- 애플리케이션에서 시간이 지난다면 자연스럽게 해결되는 일시적인 장애 발생
- readinessProbe와 livenessProbe가 실패하면서 파드 재기동
- 살아있는 다른 파드의 부하가 커지고 문제가 생긴 애플리케이션이 처리 중인 작업이 모두 실패
- 개선 방안
- 애플리케이션에서 시간이 지난다면 자연스럽게 해결되는 일시적인 장애 발생
- readinessProbe의 경우 외부 트래픽을 차단하므로 그대로 유지
- livenessProbe의 경우 readinessProbe의 주기보다 길게 설정해 파드가 너무 빠르게 재시작하지 않도록 설정
3-1. 애플리케이션마다 파드 수명을 적절히 설정해야 함
응용 과제 - Pod(Probe)
응용 1
startupProbe가 실패 되도록 설정해서 Pod가 무한 재기동 상태가 되도록 설정해 보세요.
- startupProbe는 애플리케이션 초기화를 체크하는 Probe
- 쿠버네티스만을 활용해 항상 startupProbe가 실패하도록 설정하기 위해서 다음과 같은 실패 조건을 쉽게 충족시킬 수 있도록 설정을 변경하면 됨
- periodSeconds
- 애플리케이션이 초기화되기 위해 소모되는 시간보다 훨씬 짧은 주기로 startupProbe를 실행하도록 변경
- failureThreshold
- startupProbe가 실패했음을 판단하는 수치를 매우 낮게 측정
startupProbe:
httpGet:
path: "/startup"
port: 8080
periodSeconds: 1
failureThreshold: 1
응용 2
일시적 장애 상황(App 내부 부하 증가)가 시작 된 후, 30초 뒤에 트래픽이 중단되고, 3분 뒤에는 App이 재기동 되도록 설정해 보세요.
curl http://192.168.56.30:31231/server-load-on
curl http://192.168.56.30:31231/hello
curl http://192.168.56.30:31231/server-load-off
- 30초 뒤에 트래픽 중단
- readinessProbe의 주기 및 실패 한도를 변경해서 처리
- 3분 뒤 애플리케이션 재기동
- livenessProbe의 주기 및 실패 한도를 변경해서 처리
readinessProbe:
httpGet:
path: "/readiness"
port: 8080
periodSeconds: 15
failureThreshold: 2
livenessProbe:
httpGet:
path: "/liveness"
port: 8080
periodSeconds: 60
failureThreshold: 3
응용 3
Secret 파일(/usr/src/myapp/datasource/postgresql-info.yaml)이 존재하는지 체크하는 readinessProbe를 만들어 보세요.
![](https://velog.velcdn.com/images/appti/post/0a87eebd-5fa5-45d4-b85a-49779b7d2957/image.png)
readinessProbe:
exec:
command:
- cat
- /usr/src/myapp/datasource/postgresql-info.yaml
periodSeconds: 10
failureThreshold: 3