분산 컨피규레이션?
애플리케이션의 컨피규레이션을 팻 JAR 파일 안에 제공하게되면, 마이크로서비스 인스턴스를 다시 컴파일하거나 다시 배포해야 하는 문제가 발생하는데, 분산 컨피규레이션을 사용하면 이러한 문제가 해소
- 클라우드 네이티브 환경에서 가장 인기 있는 표준
- 분산 시스템에서 외부 컨피규레이션을 위해 서버 측과 클라이언트 측을 지원
- 전체 환경에 걸쳐 애플리케이션을 위한 외부 속성을 관리하는 중앙의 단일 저장소를 두어서 사용
사용예)
VCS(버전관리 시스템)
파일 시스템
볼트(Vault)
- 서버는 단지 HTTP와 자원 기반(Restful API) 인터페이스를 노출하는 것이 전부이며, JSON 혹은 YAML, 속성 형태로 반환
(+ 암호화 복호화 수행 지원)
HTTP API 자원의 소개
컨피그 서버는 다양한 방법으로 호출할 수 있는 HTTP API를 제공한다. 아래와 같은 종단점이 제공된다.
/{application}/{profile}[/{label}] |
/{application}-{profile}.yml |
/{label}/{application}-{profile}.yml |
/{application}-{profile}.properties |
/{label}/{application}-{profile}.properties |
- {application} : 애플리케이션 이름
- {profile} : active.profile (2.6.x에서는 spring.profiles.active)
- {label} : 선택적인 값으로, git 저장소의 브랜치 정보다. (기본값은 default branch이다)
- 기본적으로 스프링 클라우드 컨피그 서버는 컨피규레이션 데이터를 가져오려고 하는데, spring.profiles.active를 native (네이티브 프로파일을 활성화)하여 서버를 시작해야 컨피그 파일을 찾는다. (자동으로 되어있는듯)
classpath:/
classpath:/config
file:./
file:./config
(속성 또는 YAML 파일이 JAR파일 안에 위치할 수 있다는 의미)
VCS (깃백엔드)를 사용한 config 파일 생성 및 HTTP API 호출
- VCS의 주요기능인 commit, revert, branching과 같은 것들을 사용하면 중요한 운영작업들을 매우 쉽게 처리할 수 있다.
- 컨피그 서버 코드와 컨피그 파일을 강제로 분리하여 저장한다. 그리고 spring.cloud.config.server.git.uri 속성에 컨피그 속성 소스들을 볼러오도록 경로를 설정한다.
(!) 예제를 위해 git 계정 인증을 사용하지 않도록 저장소를 설정했지만, 실제로는 username, password 등의 계정정보가 입력되어야 한다.
(!) file:/home/nodo3482/ys-spring-config 와 같이 로컬 저장소를 이용할 수도 있다.
- 당연하지만, 원격 VCS서버를 사용하면 모든 인스턴스와 쉽게 공유가 가능하다.
- Spring Config 서버 (PORT:8888)
https://gitlab.com/nodo3482/ys-spring-cloud/-/tree/main/eureka.config
- Spring Config 파일 VCS저장소
https://gitlab.com/nodo3482/ys-spring-config
아래의 예제는 컨피그 서버 API 엔드포인트 호출을 VCS저장소에 연동하여 호출해보는 부분을 테스트한 내용이다.
-> spring.config.name=configserver 속성을 사용하게 되면, 해당 속성에 정의된 이름의 .yml 파일을 사용하게 되는데, spring-cloud-config에서 기본적으로 제공하는 configserver.yml 파일을 사용할 수도 있다. (테스트용)
-> 위의 예제처럼 컨피그 서버의 기본 포트는 8888 이지만,
포트를 변경하는 경우에는 클라이언트 애플리케이션에서 bootstrap.yml 파일의 spring.cloud.config.url 속성에 주소를 설정 (http://localhost:8889)해야 한다.
(spring boot 2.4이후로는 spring cloud에서 bootstrap.yml 지원을 중단하였으며, 아래의 링크를 참고하여 작성을 하면 된다)
- 참고링크: https://hongdor.dev/112
-> 컨피그 서버에서는 spring-cloud-starter-eureka 의존성을 포함해야 한다. (디스커버리 클라이언트 활성)
-> 클라이언트 서버에서는 컨피그 서버의 주소값을 가질 필요가 없으며, 컨피그 서버가 다를 경우에는 Service ID만 설정하면 된다.
spring.cloud.config.discovery.service-id 에 Service ID를 추가한다.
spring.cloud.config.discovery.enabled 를 true로 활성화하여 컨피규레이션 원격 속성 소스를 가져오도록 한다.
파일시스템 백엔드
- 컨피그 파일이 로컬 파일 시스템 또는 클래스 경로에서 로딩하여 속성 소스를 읽어오는 방법. 보통 우리가 흔히 알고있는 프로젝트 resources폴더에 yml, properties 설정파일에 작성하여 사용하는 방법을 말한다.
- 교육용이나 테스트용으로 사용하며, 운영용으로는 잘 사용하지 않는 방법이다.
- spring.cloud.config.server.native.search-locations 속성에 경로를 지정하여 디스크상의 속성 소스를 읽어올 수 있다.
(file:/home/ys-cloud-config 등..)
- spring.cloud.config.server.native.add-label-locations 속성을 false(default: true)로 하면 위와같은 동작을 비활성화 한다.
URI에 플레이스홀더 사용하기
HTTP API 종단점(=엔드포인트)를 설명하면서 나온 application, profile, label 플레이스홀더를 활용하여 여러가지 방식으로 속성소스들을 가져올 수 있다. 특히, 깃 저장소를 사용할 때 커밋 ID나 브랜치, 태그명을 가지고 label에 매핑하여 사용할 수 있다.
- 컨피그 파일을 수정하고, 커밋ID를 추가하여 변경 이전의 정보를 가져오는 테스트 결과 화면이다.
- 클라이언트에서도 위와같이 label 플레이스홀더를 사용할 수 있다. spring.cloud.config.label 속성에 추가해준다.
- 단일 컨피그 서버에 여러 저장소를 구성할 수도 있다. 설계방식에 따라 사용할 수 있다. spring.cloud.config.server.git.repos 속성에 설정 값을 추가해준다.
=============예시=============
dev: https://giuthub.com/dev/ys-config
pre:
pattern: pre*/abc*,*pre*/abc*
url: https://giuthub.com/pre/ys-config
prod:
pattern: prod*
url: https://giuthub.com/prod/ys-config
=============================
볼트 (Vault)
: HashiCorp에서 개발된 크로스플랫폼 패스워드 및 인증 관리 시스템이다. 공개되면 안되는 비밀번호나 API Key, 토큰 등의 민감정보들을 저장하고 관리한다.
- 볼트는 docker 환경에서 구동이 가능하고, 필요에 따라 별도의 서버를 두어서 운영할 수도 있을 것이다.
docker run --cap-add=IPC_LOCK -d --name=vault -e 'VAULT_DEV_ROOT_TOKEN_ID=client' -p 8200:8200 vault
=> VAULT_DEV_ROOT_TOKEN_ID: 초기 루트 토큰
- 볼트는 서버에 값을 추가하거나 조회할 수 있는 CLI 인터페이스와 HTTP API를 제공해준다.
# 쓰기 CLI
$ vault write secret/hello value=world
# 읽기 CLI
$ vault read secret/hello
- API 레퍼런스 공식문서
- 컨피그 서버에서 Vault를 사용할 경우, spring.cloud.config.server에 vault 인자를 사용하여 연결해주면 된다.
- 클라이언트 서버에서는 Vault에 access할 수 있는 token정보를 spring.cloud.config.token 속성에 추가해주어야 한다.
그밖에 추가 기능..
1] 시작 시 실패와 재시도
- 컨피그 서버에 접속이 안될 경우 성공할 때까지 접속을 시도하게 할 수 있다. spring.cloud.config.failFast (default:false) 속성을 true로 변경해준다.
- spring.cloud.config.retry.* 속성으로 설정값을 변경할 수 있다.
- initial-interval: 재시도 요청의 초기 시간 간격 (ms)
- max-attempts: 최대 요청 횟수
- max-interval: 재시도 요청의 최대 시간 간격 (ms)
- multiplier: 시간의 간격 곱수를 나타냄. (재시도 요청시 네트워크 연속적인 충돌을 방지하기 위함) 1.2 -> 1.44 -> 1.72 ....
2] 클라이언트 안전하게 하기
- 컨피그 서버도 기본 인증을 사용해 안전하게 할 수 있다. 스프링 시큐리티를 사용할 수 있다.
- 이때, 클라이언트 서버들은 username과 password를 설정해두어야 한다.
재시작 없이 동적으로 컨피규레이션 다시 읽기
- 컨피그내용이 변경이 되는경우, 웹혹을 통해 변경을 알려서 스프링 클라우드 버스를 통해 레빗엠큐나 아파치 카프카를 구현하여 메시지 브로커에 전송하고, 클라이언트에서는 @RefreshScope 어노테이션을 통해 컨피규레이션을 다시 읽도록 하는 방법이 있다.
- POST - http://localhost:8081/refresh 를 호출하면 컨피그 갱신을 수행한다. (단, 서비스 디스커버리, 컨피그 서버가 활성화되어있어야함)
@Component
@RefreshScope
public class ClientConfiguration {
@Value("${sample.string.id}")
private String id;
@Value("${sample.string.name}")
private String name;
public String toString() {
return "id: "+this.id+", name: "+this.name;
}
}
위의 코드처럼 @RefreshScope 어노테이션이 선언된 클래스내 프로퍼티들이 갱신되어서 변경된 값들로 응답을 한다. (재시작이 필요없다)
- 중간에 메시지 브로커(RabbitMQ, Apache Kafka)를 통해 변경 프로퍼티를 적용시킨다고 하였는데, 큐시스템 관련한 부분은 학습이 되지않아서 설명이 어렵다 ㅠㅠ.. 이번장에서는 이런 아키텍처로 동작한다는 것만 알아두자.
참고자료
= 서적 - 마스터링 스프링 클라우드 제 5장
= https://madplay.github.io/post/introduction-to-spring-cloud-config
'SpringFramework > Spring Cloud (스터디)' 카테고리의 다른 글
Spring Cloud - (6장) 마이크로서비스 간의 커뮤니케이션 (0) | 2022.04.30 |
---|---|
Spring Cloud - (4장) 서비스 디스커버리 (0) | 2022.04.17 |
Spring Cloud - (3장) 스프링 클라우드 개요 + 주요 프로젝트 (0) | 2022.04.11 |
Spring Cloud - (1장) 마이크로서비스를 위한 스프링 & 소개 (0) | 2022.04.04 |