-
Spring Cloud Kubernetes: ConfigMap 변경 시 전체 서비스 갱신Spring/Spring 2024. 1. 10. 00:01
Kubernetes 환경에서 Spring Cloud를 사용하면 ConfigMap 변경 시 전체 서비스가 갱신되는 기능을 제공한다. 이는 spring-cloud-starter-kubernetes-client-config 라이브러리를 통해 가능하다.
ConfigMap 감지
Spring Cloud Kubernetes는 Kubernetes API 서버와 통신하여 ConfigMap의 변경을 감지한다. 이를 위해 Kubernetes Watch API를 사용하여 ConfigMap 리소스를 모니터링한다. Watch API는 Kubernetes 리소스의 생성, 업데이트, 삭제 등의 이벤트를 실시간으로 스트리밍한다.
이벤트 수신 및 트리거
ConfigMap이 변경되면, Watch API는 해당 변경 이벤트를 Spring Cloud Kubernetes로 전달한다. Spring Cloud Kubernetes는 이 이벤트를 수신하고, 설정된 리스너(listener)를 통해 애플리케이션에 알린다.
Spring Cloud Kubernetes는 내부적으로 다양한 리스너를 사용하여 ConfigMap 변경 이벤트를 처리한다. 이를 통해 설정 값이 동적으로 반영될 수 있다. 여기서 리스너는 일종의 콜백 함수나 메서드로, 특정 이벤트가 발생했을 때 자동으로 호출된다.
Spring Cloud Kubernetes Configuration Watch
Spring Cloud Kubernetes에서는 기본적으로 ConfigurationChangeDetector라는 컴포넌트가 ConfigMap의 변경 사항을 감지하는 역할을 한다. 이 컴포넌트는 Kubernetes 클러스터와 연결되어 ConfigMap 변경 이벤트를 수신하고, 이를 Spring Cloud Context로 전달한다.
동작 과정 요약
- Kubernetes Watch 설정: Spring Cloud Kubernetes는 Kubernetes Watch API를 사용하여 ConfigMap의 변경을 실시간으로 감지한다.
- 이벤트 수신: ConfigMap이 변경되면, Watch API는 변경 이벤트를 Spring Cloud Kubernetes로 전달한다.
- 리스너 호출: Spring Cloud Kubernetes는 수신된 이벤트를 기반으로 설정된 리스너를 호출한다.
- 설정 업데이트: 리스너는 변경된 설정 값을 처리하고, 필요 시 @ConfigurationProperties 또는 @RefreshScope 빈을 다시 로드하거나 갱신한다.
설정 업데이트?
Spring Cloud Kubernetes는 수신된 이벤트를 바탕으로 애플리케이션의 환경 설정을 동적으로 업데이트한다. Spring의 Environment 객체가 업데이트되며, 이 과정에서 변경된 설정 값들이 반영된다.
빈(Bean) 리프레시
Spring Cloud Kubernetes는 @ConfigurationProperties 또는 @RefreshScope로 선언된 빈(Bean)들을 다시 로드하거나 갱신한다. @RefreshScope는 Spring Cloud Context 모듈의 기능으로, 빈의 상태를 유지하면서 설정값을 갱신할 수 있다. 이로 인해 변경된 설정 값이 즉시 애플리케이션에 반영되고, 관련 빈이 재생성되거나 갱신된다.
@ConfigurationProperties 빈이 갱신되는 메커니즘은 Spring Cloud Kubernetes와 Spring Cloud Context의 기능을 결합하여 이루어진다. 이 과정은 Kubernetes에서 ConfigMap 변경을 감지하고, 변경된 설정을 Spring 애플리케이션에 동적으로 반영하며, 필요한 경우 관련 빈을 갱신하는 것을 포함한다.
1. ConfigMap 변경 감지
Spring Cloud Kubernetes는 Kubernetes Watch API를 사용하여 ConfigMap의 변경을 실시간으로 감지한다. 변경이 감지되면, Spring Cloud Kubernetes는 변경 이벤트를 수신하고 이를 처리하기 시작한다.
2. 환경(Environment) 재설정
변경 이벤트가 수신되면, Spring Cloud Kubernetes는 변경된 ConfigMap 값을 Spring의 Environment 객체에 반영한다. 이는 Spring의 환경 설정이 갱신된다는 것을 의미한다.
3. @RefreshScope 빈 갱신
@RefreshScope로 주석이 달린 빈은 Spring Cloud Context의 RefreshScope에 의해 관리된다. 이 어노테이션은 해당 빈의 상태를 유지하면서 설정 값이 변경될 때 빈을 다시 로드하거나 갱신할 수 있게 한다.
4. /actuator/refresh 엔드포인트 호출
Spring Boot Actuator를 사용하여 /actuator/refresh 엔드포인트를 활성화할 수 있다. 이 엔드포인트를 호출하면 Spring Cloud Context는 Environment 객체가 갱신된 것을 감지하고, @RefreshScope로 주석이 달린 모든 빈을 다시 로드하거나 갱신한다.
@ConfigurationProperties와 @RefreshScope
1. @ConfigurationProperties
@ConfigurationProperties는 설정 파일의 값을 클래스에 바인딩하는 데 사용된다. 이를 통해 애플리케이션 설정을 쉽게 관리할 수 있다.
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "my") public class MyConfigProperties { private String message; private int value; // Getters and Setters public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } }
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RestController; @RefreshScope @RestController public class MyConfigController { @Autowired private MyConfigProperties myConfigProperties; @GetMapping("/config") public String getConfig() { return "Message: " + myConfigProperties.getMessage() + ", Value: " + myConfigProperties.getValue(); } }
ConfigMap 생성
apiVersion: v1 kind: ConfigMap metadata: name: my-config data: application.yml: | my: message: Hello from ConfigMap value: 42
어플리케이션 설정
spring: cloud: kubernetes: config: enabled: true name: my-config namespace: default management: endpoints: web: exposure: include: refresh, health, info
참고 자료
'Spring > Spring' 카테고리의 다른 글
Spring Batch에서 Job Completed 이후 종료되지 않을때 (0) 2023.09.09 Spring Batch 3.0 이상에서 JPA 사용시 PlatformTransactionManager 설정 (0) 2023.06.01 SubscribeOn , PublishOn (31) 2021.12.23 Reactor List가 비어있을 때의 switchIfEmpty와 defaultIfEmpty (0) 2021.10.14 스프링 @Transactional과 잠금 (0) 2021.08.11