구성이 더 이상 애플리케이션 코드에 패키징되어 배포되지 않는다. 따라서 애플리케이션을 다시 빌드하거나 배포하지 않고 구성을 변경하거나 원래 값으로 환원할 수 있다.
공통적인 구성을 공유하는 마이크로서비스가 자신의 속성 설정으로 유지/관리하지않고도 동일한 속성들을 공유할 수 있다. 그리고 속성 변경이 필요하면 한 곳에서 한번만 변경해도 모든 마이크로서비스에 적용할 수 있다.
보안에 민감한 구성 속성은 애플리케이션 코드와는 별도로 암호화하고 유지/관리할 수 있다. 그리고 복호화된 속성 값을 언제든지 애플리케이션에서 사용할 수 있으므로 복호화를 하는 코드가 애플리케이션에 없어도 된다.
스프링 클라우드 구성 서버는 애플리케이션의 모든 마이크로서비스가 구성에 의존할 수 있는 서버를 사용해서
중앙 집중식 구성을 제공한다.
Git과 같은 소스 코드 제어 시스템에 구성 속성을 저장함으로써 애플리케이션 소스 코드처럼 구성 속성의 버전, 분기 등을 관리할 수 있다. 그러나 구성 속성을 사용하는 애플리케이션과 별도로 구성 속성을 유지/관리하므로 애플리케이션과 독립적으로 버전을 관리할 수 있다. (독립적! 실무에서도 Git 으로 config 서버 구현됨.)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
스프링 클라우드 구성 서버 스타터 의존성을 추가한다.
<properties>
...
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
</properties>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
스프링 클라우드 버전 의존성과 버전 속성을 지정한다.
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/habuma/tacocloud-config
order: 2
vault:
host: localhost
port: 8300
scheme: http
order: 1
위의 port와 uri 속성은 '구성 서버' 자체의 구성에 필요한 속성이다.
구성 서버가 클라이언트에 제공하는 구성 속성은 Git이나 Vault의 repository에서 가져온다.
구성 서버의 클라이언트인 것처럼 구성 서버를 테스트해볼 수 있다.
호출을 하면 구성 서버의 응답을 받을 수 있다.
Git 백엔드 repo에 저장되는 암호화된 데이터를 사용하는 핵심은 암호화 키(encryption key)이다.
암호화된 속성을 사용하기 위해서는 암호화 키를 사용해 구성 서버를 구성해야 하며, 암호화 키는 속성 값을 클라이언트 애플리케이션에 제공하기 전에 복호화하는데 사용된다.
대칭 키와 비대칭 키 모두 지원한다.
대칭 키(암호화와 복호화에 사용하는 암호 키가 같음)
encrpyt:
key: s3cr3t
bootstrap.yml or bootstrap.propertes에 설정되어야 한다.
자동-구성이 구성 서버를 활성화시키기 전에 로드되어 사용할 수 있기 때문이다.
비대칭 키(암호화와 복호화에 사용하는 암호 키가 다르고 암호화 : public 키 / 복호화 : private 키)
비대칭 키 생성
keytool -genkeypair -alias tacokey -keyalg RSA \
-dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
-keypass s3cr3t -keystore keystore.jks -storepass l3tm31n
결과로 생성되는 keystore.jks는 파일 시스템의 키스토어 파일로 유지하거나 애플리케이션 자체에 둘 수 있다.
둘 중 어느 경우든 해당 키스토어의 위치와 인증 정보를 구성 서버의 bootstrap.yml 파일에 구성해야 한다.
키스토어를 애플리케이션 자체(classpath의 root)에 둔다고 하면 bootstrap.yml에 다음과 같이 작성해야 한다.
encrypt:
key-store:
alias: tacokey
location: classpath:/keystore.jks
password: l3tm31n
secret: s3cr3t
키나 키스토어가 준비된 후에는 데이터를 암호화해야 한다.
구성 서버는 /encrypt 엔드포인트를 제공하기 때문에, 암호화될 데이터를 갖는 POST 요청을 /encrpt 앤드포인트에 하면 된다.
몽고DB 비밀번호 암호화
POST 요청으로 암호화된 값 응답 받기
$ curl localhost:8888/encrypt -d "s3cr3tP455w0rd"
93912a660a7f3c04e811b5df9a3cf6e1f63850cdcd4aa092cf5a3f7e1662fab7
Git repo에 저장된 application.yml 파일에 spring.data.mongodb.password 속성 추가
spring:
data:
mongodb:
password: '{cipher}93912a660a7f3c04e811b5df9a3cf6e1f63850...'
기본적으로 구성 서버가 제공하는 암호화된 값은 백엔드 Git repo에 저장되어 있을 때만 암호화되어 있으며, 구성 서버에 의해 복호화된 후 제공된다.따라서, 복호화하는 코드를 애플리케이션 코드에 포함시킬 필요 없다.
암호화된 값 받기
구성 서버의 bootstrap.yml에 spring.cloud.config.server.encrypt.enabled 속성을 false로 설정하면 된다.
수동식과 자동식이 존재하며 수동식은 매우 번거롭기 때문에 자동으로 적용하는 방법을 사용한다.
14.6.1 구성 속성 수동으로 리프레시
curl localhost:8080/actuator/refresh -X POST
위 요청을 실행 해야 한다.
14.6.2 구성 속성 자동으로 리프레시
속성 리프레시 절차
웹훅이 Git repo에 생성되어 Git repo에 대한 변경이 생겼을을 구성 서버에 알려준다.
웹훅은 GitHub, GitLab, Bitbucket, Gogs를 비롯한 많은 리퍼지터리에서 지원된다.
구성 서버는 RabbitMQ나 Kafka와 같은 메시지 브로커를 통하여 변경 관련 메시지를 전파함으로써 웹훅의 POST 요청에 반응한다.
알림을 구독하는 구성 서버 클라이언트 애플리케이션은 구성 서버로부터 받은 새로운 속성 값으로 자신의 속성을 리프레시한다.
구성 서버를 통한 속성의 자동 리프레시 사용 시 고려할 사항
구성 서버와 이것의 클라이언트 간의 메시지 처리에 사용할 수 있는 메시지 브로커가 있어야 하며, RabbitMQ나 Kafka 중 하나를 선택할 수 있다.
구성 서버에 변경을 알려주기 위해 웹훅이 백엔드 Git repo에 생성되어야 한다.
구성 서버는 구성 서버 모니터 의존성 및 RabbitMQ 나 카프카 스프링 클라우드 스트림 의존성과 함께 활성화되어야 한다.
메시지 브로커가 기본 설정으로 로컬에서 실행되는 것이 아니라면, 브로커에 연결하기 위한 세부 정보를 구성 서버와 이것의 모든 클라이언트에 구성해야 한다.
각 구성 서버 클라이언트 애플리케이션에 스프링 클라우드 버스 의존성이 추가되어야 한다.
스프링 클라우드 구성 서버는 중앙 집중화된 구성 데이터 소스를 마이크로서비스 기반의 더 큰 애플리케이션을 구성하는 모든 마이크로서비스에 제공한다.
구성 서버가 제공하는 속성들은 백엔드 Git이나 Vault 리퍼지터리에서 유지 / 관리된다.
모든 구성 서버 클라이언트에 제공되는 전역적인 속성들에 추가하여 구성 서버는 프로파일에 특정된 속성과 애플리케이션에 특정된 속성도 제공할 수 있다.
보안에 민감한 속성들은 백엔드 Git 리퍼지터리에 암호화하여 저장하거나 Vault 백엔드의 보안 속성으로 저장하여 보안을 유지할 수 있다.
구성 서버 클라이언트는 새로운 속성으로 리프레시할 수 있다. 이때 액추에이터 엔드포인트를 통해 수동으로 리프레시하거나, 스프링 클라우드 버스와 Git 웹훅을 사용해서 자동으로 리프레시할 수 있다.