본문 바로가기
MSA/Spring Microservice In Action

3. 스프링 클라우드 컨피그 서버로 구성 관리

by 화트마 2022. 1. 2.

- 배포되는 실제 코드에서 애플리케이션의 구성을 완전하게 분리

- 서버를 시작할 때 환경 변수나 애플리케이션의 마이크로서비스가 읽어 올 수 있는 중앙 저장소를 이용해 애플리케이션 구성 정보를 주입

 

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/

 

GitHub - hmg0616/msainaction-config-repo

Contribute to hmg0616/msainaction-config-repo development by creating an account on GitHub.

github.com

- 각 환경 별 프로퍼티 설정 (파일 명명 규칙 : 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

POSTMAN을 이용한 POST 호출

- 암호화한 프로퍼티 설정 : {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가 표시된다.

댓글