Spring Cloud Config는 서버, 클라이언트 구성에 필요한 설정 정보 (application.yml)를 외부 시스템에서 관리합니다. 외부 시스템 즉, 하나의 중앙화된 저장소에서 설정 정보를 관리 가능하며 배포 파이프라인을 통해 dev, uat, prod 환경에 맞는 구성 정보를 사용합니다.
예를 들어 auth-service를 구동하고 있는 중에 token의 값을 변경하는 상황을 가정해보겠습니다. token의 secret plain text를 변경한다면 application.yml 파일에서 user_token -> changed_user_token로 변경을 하겠죠.
이러한 변경된 설정 정보를 서버에 반영을 해야한다면 서버를 죽이고 다시 재구동해야하는 번거로운 상황이 올 수 있습니다. 대규모의 서비스를 운영하는 서버의 경우엔 상황이 좀 더 복잡하고, 심각해질 수도 있을 것 같습니다.
하지만 이러한 토큰에 대한 정보를 외부 시스템인 Spring Cloud Config에서 관리한다면 어떻게 될까요? 굳이 auth-service에서 작업을 하지 않고, auth-service가 spring cloud config server의 정보만 받아와 갱신할 수 있다면 서버를 다시 빌드하고 배포할 필요성이 사라지게 됩니다.
즉, 운영 환경에 있어서 리스크를 감수하지 않고 편리하게 운영이 가능하다고 볼 수 있겠습니다.
다음과 같은 구조로 Spring Cloud Config Server의 구조를 살펴 볼 수 있겠죠.
Local, Remote Repository에서 .yml파일로 설정을 관리할 수 있습니다. 이 yml파일은 우선 순위를 가지는데 다음과 같습니다.
1) application.yml
2) application-name.yml
3) application-name-(profile).yml
예를 들어서 현재 auth-service와 관련된 설정 파일을 만들어 보겠다고 가정하겠습니다. 이 파일들의 우선 순위를 보면 application.yml -> auth-service.yml -> auth-service-dev.yml or auth-service-test.yml or auth-service-prod.yml 이런 식의 우선 순위를 가지게 되는 것이죠.
Local Git Repository는 본인 PC에 저장되는 저장소입니다. 사용법은 로컬 PC에 디렉토리를 만들고 이곳에서 설정파일을 만들어 사용합니다. 코드를 통해 살펴보겠습니다.
이런 식으로 로컬 디렉토리에 rental.yml파일을 만들어 설정을 관리하도록 하겠습니다. rental.yml파일에 토큰 관련 설정을 했으므로 auth-service의 토큰 관련 설정을 지우도록 하겠습니다.
그리고 Spring Cloud Config 프로젝트를 만들어 보도록 하겠습니다.
Spring Cloud Config 설정을 진행하겠습니다.
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
server:
port: ${port:8888}
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: file:///home/biuea/Desktop/MyRentalPlatform/git-local-repo
다음처럼 cloud.config.server.git.uri에 file://(git-local-repo-path) 이런 식으로 디렉토리의 경로를 적으면 Cloud Config Server에서 해당 경로를 읽어 들여와 갱신을 합니다.
결과 화면처럼 rental.yml파일에 설정해둔 값들이 잘 나오는 모습을 확인할 수 있습니다.
결과 확인을 통해 Config Server가 잘 구동되는 모습을 볼 수 있었습니다. 그러면 auth-service와 Config Server를 연동해서 설정 값들을 받아오도록 하겠습니다.
연동을 위해서 auth-service의 pom.xml파일에 다음과 같은 디펜던시를 추가하도록 하겠습니다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
bootstrap이라는 디펜던시를 추가했습니다. bootstrap은 bootstrap.yml파일을 위해 필요한 디펜던시인데 이 파일에다가 Cloud Server에 연결에 관한 설정을 하도록 하겠습니다.
spring:
cloud:
config:
uri: http://127.0.0.1:8888
name: rental
다음과 같은 설정으로 구동중인 Cloud Server에 연결하여 설정을 받아올 수 있습니다.
그리고 Controller에서 status메서드를 변경하여 Cloud Server와 연결이 잘 되어 설정 값들을 잘 받아오는지 확인하도록 하겠습니다.
@GetMapping("/health_check")
public String status() {
return String.format(
"It's working in Auth Service"
+ ", port(local.server.port) =" + env.getProperty("local.server.port")
+ ", port(server.port) =" + env.getProperty("server.port")
+ ", token secret = " + env.getProperty("token.secret")
+ ", token expiration time = " + env.getProperty("token.exp_time")
);
}
그리고 Environment 객체를 생성자에 추가하여 application.yml파일에서 값을 읽어 올 수 있도록 하겠습니다.
auth-service이 정상 구동되고 터미널에 다음과 같은 메시지를 확인할 수 있습니다.
2021-08-21 16:21:10.695 INFO 37437 --- [ restartedMain] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://127.0.0.1:8888
2021-08-21 16:21:10.802 INFO 37437 --- [ restartedMain] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=rental, profiles=[default], label=null, version=6a6dc4a508b3b1aedc99949ee1ecad00699f251f, state=null
2021-08-21 16:21:10.802 INFO 37437 --- [ restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-file:///home/biuea/Desktop/MyRentalPlatform/git-local-repo/rental.yml'}]
2021-08-21 16:21:10.807 INFO 37437 --- [ restartedMain] c.m.authservice.AuthServiceApplication : No active profile set, falling back to default profiles: default
저는 ifconfig를 통해 wlp60s0이 지칭하는 ip를 사용하도록 하겠습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/**").access("hasIpAddress('10.0.15.41') or hasIpAddress('192.168.219.102') or hasIpAddress('172.30.1.35')")
.and().addFilter(getAuthenticationFilter());
}
이렇게 access메서드에 hasIpAddress 인자를 넣어준 결과 정상적으로 동작을 하였습니다.
결과를 마저 확인하도록 하겠습니다.
확인한 결과, token에 대한 설정 값을 Config Server에서 잘 받아오는 모습을 확인할 수 있습니다.
#1 Spring Cloud Config
https://madplay.github.io/post/introduction-to-spring-cloud-config
인프런: Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) - 이도원