1. 개요

이 튜토리얼에서는 Spring Boot 2.3Kubernetes 프로브 와 통합되어 더욱 쾌적한 클라우드 네이티브 환경을 만드는 방법을 살펴 보겠습니다 .

먼저 Kubernetes 프로브에 대한 배경 지식부터 시작하겠습니다. 그런 다음 기어를 바꾸고 Spring Boot 2.3이 이러한 프로브를 지원하는 방법을 살펴 보겠습니다.

2. Kubernetes 프로브

Kubernetes를 오케스트레이션 플랫폼으로 사용할 때 각 노드 kubelet 은 해당 노드의 포드를 정상 상태로 유지해야합니다.

예를 들어, 때때로 우리의 앱은 요청을 수락하기 전에 약간의 시간이 필요할 수 있습니다. kubelet은 애플리케이션이 준비가 된 경우에만 요청을 수신하도록 할 수 있습니다. 또한 어떤 이유로 든 포드의 기본 프로세스가 충돌하면 kubelet이 컨테이너를 다시 시작합니다.

이러한 책임을 수행하기 위해 Kubernetes에는 활성 프로브와 준비 프로브라는 두 가지 프로브가 있습니다.

kubelet은 준비 상태 프로브를 사용하여 애플리케이션이 요청을 수락 할 준비가되었는지 확인합니다. 보다 구체적으로, 모든 컨테이너가 준비되면 포드가 준비됩니다.

마찬가지로 kubelet은 활성 프로브를 통해 포드가 아직 살아 있는지 확인할 수 있습니다 . 기본적으로 활성 프로브는 kubelet이 컨테이너를 다시 시작해야하는시기를 알 수 있도록 도와줍니다.

이제 개념에 익숙해 졌으므로 Spring Boot 통합이 어떻게 작동하는지 살펴 보겠습니다.

3. 액추에이터의 활력과 준비성

Spring Boot 2.3부터 LivenessStateHealthIndicator  및  ReadinessStateHealthIndicator  클래스는 애플리케이션의 활성 상태 및 준비 상태를 노출합니다. 애플리케이션을 Kubernetes에 배포하면 Spring Boot가 이러한 상태 표시기를 자동으로 등록합니다.

결과적으로  / actuator / health / liveness 및  / actuator / health / readiness 엔드 포인트를 각각 활성 및 준비 상태 프로브로 사용할 수 있습니다.

예를 들어,이를 포드 정의에 추가하여 HTTP GET 요청으로 활성 프로브를 구성 할 수 있습니다.

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
    initialDelaySeconds: 3
    periodSeconds: 3

우리는 보통 Spring Boot가 우리를 위해 이러한 프로브를 사용할시기를 결정하도록 할 것입니다. 그러나 원하는 경우 application.properties 에서 수동으로 활성화 할 수 있습니다 .

Spring Boot 2.3.0 또는 2.3.1로 작업하는 경우 구성 속성을 통해 언급 된 프로브를 활성화 할 수 있습니다.

management.health.probes.enabled=true

그러나 Spring Boot 2.3.2부터이 속성은 구성 혼란 으로 인해 더 이상 사용되지 않습니다 .

Spring Boot 2.3.2로 작업하는 경우 새 속성을 사용하여 활성 및 준비 상태 프로브를 활성화 할 수 있습니다.

management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true

3.1. 준비 및 활성 상태 전환

Spring Boot는 서로 다른 준비 상태와 활성 상태를 캡슐화하기 위해 두 개의 열거 형을 사용합니다. 준비 상태의 경우 다음 값을 가진 ReadinessState  라는 열거 형이  있습니다.

  • ACCEPTING_TRAFFIC의  상태는 응용 프로그램 트래픽을 수용 할 준비가되어 있음을 나타냅니다
  • REFUSING_TRAFFIC의  응용 프로그램이 아직 요청을 받아 들일 아니라고 상태 수단

마찬가지로  LivenessState  열거 형은 두 가지 값으로 앱의 활성 상태를 나타냅니다.

  • CORRECT  값은 애플리케이션이 실행하는 수단과, 내부 상태를 정확
  • 반면  BROKEN  값은 응용 프로그램이 일부 치명적인 오류와 함께 실행 중임을 의미합니다.

Spring의 애플리케이션 수명주기 이벤트 측면에서 준비 상태 및 활성 상태가 어떻게 변경되는지는 다음과 같습니다.

  1. 리스너 및 이니셜 라이저 등록
  2. 환경 준비 
  3. ApplicationContext 준비 
  4. 빈 정의로드
  5. 활성 상태를 CORRECT로 변경 
  6. 응용 프로그램 및 명령 줄 실행기 호출
  7. 준비 상태를 ACCEPTING_TRAFFIC으로 변경 

애플리케이션이 가동되고 실행되면 적절한 AvailabilityChangeEvents 를 게시하여 이러한 상태를 변경할 수 있습니다  .

4. 애플리케이션 가용성 관리

응용 프로그램 구성 요소는 ApplicationAvailability  인터페이스 를 삽입하여 현재 준비 상태 및 활성 상태를 검색 할 수 있습니다  .

@Autowired private ApplicationAvailability applicationAvailability;

그런 다음 다음과 같이 사용할 수 있습니다.

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.CORRECT);
assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
assertThat(applicationAvailability.getState(ReadinessState.class))
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);

4.1. 가용성 상태 업데이트

AvailabilityChangeEvent  이벤트 를 게시하여 애플리케이션 상태를 업데이트 할 수도 있습니다 .

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.CORRECT);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.BROKEN);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("DOWN"));

위에 표시된대로 이벤트를 게시하기 전에  / actuator / health / liveness  엔드 포인트는 다음 JSON과 함께 200 OK 응답을 반환합니다.

{
    "status": "OK"
}

그런 다음 활성 상태를 중단 한 후 동일한 엔드 포인트가 다음 JSON과 함께 503 서비스를 사용할 수 없음 응답을 반환합니다.

{
    "status": "DOWN"
}

REFUSING_TRAFFIC  의 준비 상태로 변경 하면  상태  값은  OUT_OF_SERVICE가됩니다.

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.REFUSING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("OUT_OF_SERVICE"));

4.2. 변화에 귀 기울이기

애플리케이션 가용성 상태가 변경 될 때 알림을받을 이벤트 리스너를 등록 할 수 있습니다.

@Component
public class LivenessEventListener {
    
    @EventListener
    public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
        switch (event.getState()) {
        case BROKEN:
            // notify others
            break;
        case CORRECT:
            // we're back
        }
    }
}

여기서 우리는 애플리케이션 활성 상태의 변화를 듣고 있습니다.

5. 자동 구성

마무리하기 전에 Spring Boot가 Kubernetes 배포에서 이러한 프로브를 자동으로 구성하는 방법을 살펴 보겠습니다. AvailabilityProbesAutoConfiguration의  클래스는 조건부로 생동감과 준비 프로브를 등록 할 책임이있다.

사실 다음 중 하나가 참일 때 프로브를 등록 하는 특별한 조건있습니다.

애플리케이션이 이러한 조건 중 하나를 충족하면 자동 구성이 LivenessStateHealthIndicator  및  ReadinessStateHealthIndicator의 Bean을 등록   합니다.

6. 결론

이 기사에서는 Spring Boot를 사용하여 Kubernetes 통합을위한 두 가지 상태 프로브를 제공하는 방법을 살펴 보았습니다.

평소와 같이 모든 예제는 GitHub에서 사용할 수 있습니다 .