boot가 아직 준비되지 않았는데 기존 파드가 삭제될때

새로운 버전을 배포할 때,
Deployment는 최신 버전을 먼저 실행하고, 실행이 완료되면 이전 버전의 파드를 삭제한다.
그러나 최신 버전의 파드는 정상적으로 실행됐지만 boot가 아직 준비상태가 아닌데
이전 버전의 파드가 삭제되면 최신 버전의 파드가 준비상태가 될 때 까지 접속 장애가 나타난다.
boot가 준비 상태가 되어야만 파드가 실행 완료 되었다고 간주하도록 설정해보자.


Spring Boot 에서 actuator 적용하기

파드가 실행될 때 boot가 준비되었는지 확인하기 위한 endpoint를 만들어준다.

  1. actuator 의존성 추가하기
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>


  1. actuator 가 정상적으로 동작하는지 테스트
$ curl localhost:8080/actuator/health
{"status":"up"}


K8s Deployment startupProbe 추가하기

파드가 실행되면 actuator 로 추가한 준비상태 endpoint로 요청 후 응답을 받았을 때 파드가 정상 동작임으로 간주한다.

(HTTP 상태코드가 200 ~ 400 상태 코드 사이의 값을 반환하면 정상, 400 ~ 500인 경우 오류)

  startupProbe:
	httpGet: # http GET으로 요청
	  port: 80 # 요청할 웹포트
	  path: /actuator/health # 요청할 엔드포인트
	  httpHeaders:
	  - name: Host
	    value: probe-httpreq
	initialDelaySeconds: 60 # 초기 지연시간 (60초 기다린 후 최초 요청, default:0)
	periodSeconds: 10 # 재요청 대기 초 (최초 실패 후 10초마다 재요청) (timeoutSeconds 보다 커야함, default:10)
	timeoutSeconds: 2 # 2초동안 응답을 받지 못하면 실패로 간주 (periodSeconds 보다 작아야함, default:1)
	failureThreshold: 30 # 최대 30번 요청
	successThreshold: 1 # 1회 성공하면 컨테이너 상태를 성공으로 설정 (default : 1)

결과

적용 전

  1. deployment의 버전을 새로운 버전으로 적용(apply) 하면 새로운 버전의 파드가 빌드 -> 배포 된다.
  2. 배포가 시작되면서 Springboot가 실행되는 로그가 출력되면, 기존 버전의 파드가 삭제된다.
  3. Spring boot가 아직 실행중인 상태이기 때문에 사용자의 요청이 도달할 수 있는 endpoint가 없어 오류가 난다.
  4. Spring boot가 준비가 완료되기까지 (어플리케이션 실행 속도는 편차가 크다 대략 5분이라고 가정) 요청은 모두 오류
  5. 5분이 지난 후 준비가 완료되면 새로운 버전의 pod로 endpoint가 연결된다.


=> 최소 5분의 endpoint 유실이 존재

적용 후

  1. deployment의 버전을 새로운 버전으로 적용(apply) 하면 새로운 버전의 파드가 빌드 -> 배포 된다.
  2. 배포가 시작되면서 Springboot가 실행되는 로그가 출력되지만 /actuator/health 를 요청해도 응답할 수 없는 상태이기 때문에
    현재 파드가 준비상태가 아닌것으로 간주하므로 기존 버전의 파드가 유지된다.
  3. 새 버전의 어플리케이션이 /actuator/health 가 UP 상태를 응답할때까지(boot의 준비가 끝날때까지 5분으로 간주)
    새 버전의 pod는 준비상태가 아니다.
    이 시간동안 모든 사용자 요청은 기존 파드에 endpoint가 연결되어있다.
  4. 5분이 지난 후 새 버전의 파드가 준비가 완료되면 기존 파드를 삭제하기 시작한다.
  5. 사용자는 이 시간동안 endpoint가 유실되는 일이 없으므로 응답받지 못하는 경우가 없다.


=> 최소 5분동안은 새로운 버전의 응답을 받지 못하나 오류가 발생하진 않는다.