- 배포되는 실제 코드에서 애플리케이션의 구성을 완전하게 분리
- 서버를 시작할 때 환경 변수나 애플리케이션의 마이크로서비스가 읽어 올 수 있는 중앙 저장소를 이용해 애플리케이션 구성 정보를 주입
1. 스프링 클라우드 컨피그 서버 구축
confsvr 라는 새로운 프로젝트 생성
- pom.xml 작성
// confsvr의 pom.xml
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
<!--Docker build Config-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>com.hmg.confsvr.ConfsvrApplication</start-class>
<java.version>1.8</java.version>
<docker.image.name>hmg/msa-confsvr</docker.image.name>
<docker.image.tag>1.0</docker.image.tag>
</properties>
...
</project>
깃 저장소를 스프링 클라우드 컨피그 서버로 사용
// 컨피그 서비스(confsvr)의 application.yml 수정
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/hmg0616/msainaction-config-repo/
searchPaths: licensingservice,organizationservice # 스프링 클라우드 컨피그 서버가 가동될 때 검색할 깃 저장소의 상대 경로 전달
username: native-cloud-apps
password: 0ffended
환경별 애플리케이션 구성 데이터 설정
- github repository 신규 생성, master branch
- https://github.com/hmg0616/msainaction-config-repo/
- 각 환경 별 프로퍼티 설정 (파일 명명 규칙 : appname-env.yml)
licensingservice.yml
licensingservice-dev.yml
licensingservice-prod.yml
example.property: "I AM IN THE DEFAULT"
spring.jpa.database: "POSTGRESQL"
spring.datasource.platform: "postgres"
spring.jpa.show-sql: "true"
spring.database.driverClassName: "org.postgresql.Driver"
spring.datasource.url: "jdbc:postgresql://database:5432/msainaction_local"
spring.datasource.username: "postgres"
spring.datasource.password: "{cipher}4788dfe1ccbe6485934aec2ffeddb06163ea3d616df5fd75be96aadd4df1da91"
spring.datasource.testWhileIdle: "true"
spring.datasource.validationQuery: "SELECT 1"
spring.jpa.properties.hibernate.dialect: "org.hibernate.dialect.PostgreSQLDialect"
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation: "true"
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults: "false"
spring.jpa.hibernate.ddl-auto: "create-drop"
redis.server: "redis"
redis.port: "6379"
signing.key: "345345fsdfsf5345"
부트스트랩 클래스 설정
- @EnableConfigServer : 서비스를 스프링 클라우드 컨피그 서비스로 사용 가능하게 한다.
// confsvr/src/main/java/com/hmg/confsvr/ConfigServerApplication.java
package com.hmg.confsvr;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
컨피그 서버 실행
> mvn spring-boot:run
테스트
- 웹 브라우저에 다음 url 호출 시 각 환경의 구성정보 확인 가능
http://localhost:8888/licensingservice/default
http://localhost:8888/licensingservice/dev
http://localhost:8888/licensingservice/prod
2. 스프링 부트 클라이언트 작성 - 컨피그 연결
의존성 설정
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.4</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
애플리케이션 이름 및 컨피그 서버 위치 설정
// licensing-service/src/main/resources/bootstrap.yml
spring:
application:
name: licensingservice # 애플리케이션 이름이며 컨피그 서버의 디렉터리 이름과 일치해야함
profiles:
active:
default
cloud:
config:
uri: http://localhost:8888 # 라이선싱 서비스가 접속할 스프링 클라우드 컨피그서버의 엔드포인트
라이선싱 서비스 시작
> mvn spring-boot:run
라이선싱 서비스의 스프링 액추에이터로 실행 중인 환경 정보 확인
http://localhost:8080/actuator/env
@Value 애너테이션으로 프로퍼티 직접 읽기
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ServiceConfig{
@Value("${example.property}")
private String exampleProperty;
public String getExampleProperty(){
return exampleProperty;
}
}
3. 중요한 구성 정보 보호
- 스프링 클라우드 컨피그 서버는 모든 프로퍼티를 구성 파일에 평문으로 저장하는 것이 기본 설정. 하지만 데이터베이스 자격 증명처럼 중요한 정보도 구성 파일에 포함됨.
- 스프링 클라우드 컨피그는 중요한 프로퍼티를 쉽게 암호화할 수 있는 기능을 제공하며 대칭(공유 비밀 키 사용) 및 비대칭 암호화(공개/비공개 키 사용)를 모두 지원한다.
암호화에 필요한 오라클 JCE jar 파일 설치
- Dockefile로 자동화
RUN cd /tmp/ && \
wget "http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip" --header 'Cookie: oraclelicense=accept-securebackup-cookie' && \
unzip jce_policy-8.zip && \
rm jce_policy-8.zip && \
yes |cp -v /tmp/UnlimitedJCEPolicyJDK8/*.jar /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/
대칭 암호화 키 설정
- 운영체제 환경 변수 ENCRYPT_KEY 저장
(대칭 키의 길이는 12자 이상이어야 하며, 불규칙 문자열이 이상적)
프로퍼티 암호화 및 복호화
- ENCRYPT_KEY 환경 변수 설정 감지 시 스프링 클라우드 컨피그에 새로운 엔드포인트(/encrypt와 /decrypt) 자동 추가됨
- POST 호출로 암호화 및 복호화 가능
http://localhost:8888/encrypt
http://localhost:8888/decrypt
- 암호화한 프로퍼티 설정 : {cipher} 태그
spring.datasource.password: "{cipher}a9f2aa47100cb8f768ba31338ce04ef3321cdab757c95b3fc1976fdabccefb35"
문제점 : http://localhost:8888/licensingservice/default 엔드포인트 호출 시 암호화된 프로터티가 복호화되면서 평문으로 보임
- 스프링 클라우드 컨피그 서버가 복호화를 하지않고 구성 데이터를 조회하는 애플리케이션이 암호화된 프로퍼티를 복호화하는 책임을 지도록 설정
1. 스프링 클라우드 컨피그의 서버 측 복호화 프로퍼티 비활성화
- 스프링 클라우드 컨피그의 confsvr/src/main/resources/bootstrap.yml 파일에 있는 spring.cloud.config.server.encrypt.enabled 프로퍼티를 false로 설정
spring:
application:
name: configserver
cloud:
config:
server:
encrypt.enabled: false
2. 라이선싱 서비스에서 대칭 키 설정
- 스프링 클라우드 컨피그 서버에 사용될 ENCRYPT_KEY 환경 변수가 동일한 대칭키로 설정되어 있는지 확인하고 라이선싱 서비스에 대칭 키 설정
3. 그 다음 라이선싱 서비스에 spring-security-rsa JAR 의존성 추가
- 이 JAR 파일에는 스프링 클라우드 컨피그 서버에서 전달된 암호화된 프로퍼티를 복호화하는 데 필요한 스프링 코드가 들어있음.
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-rsa</artifactId>
</dependency>
- 이 변경을 모두 적용하면 스프링 클라우드 컨피그 서비스와 라이선싱 서비스를 시작해도 된다. 이제 다시 http://localhost:8888/licensingservice/default 엔드포인트를 호출하면 암호화된 형식으로 spring.datasource.password가 표시된다.
'MSA > Spring Microservice In Action' 카테고리의 다른 글
5. 나쁜 상황에 대비한 스프링 클라우드와 넷플릭스 히스트릭스의 클라이언트 회복성 패턴 (0) | 2022.02.19 |
---|---|
부록. Dockerfile과 Docker-compose를 이용한 프로젝트 빌드 및 실행 (0) | 2022.01.20 |
4. 서비스 디스커버리 (0) | 2022.01.09 |
2. 스프링 부트 마이크로 서비스 구축 (0) | 2021.12.28 |
1. Spring Microservice 개요 (0) | 2021.12.28 |
댓글