Spring/Spring Cloud

Spring Cloud 마이크로서비스들이 직접 Vault에서 값을 읽도록 만들어야 할까? - 보안과 유연성의 고민

묠니르묘묘 2023. 10. 7. 16:43

🚀 현재 상황

Vault를 적용한 Spring Cloud 아키텍처

  • Spring Cloud Config Server (구성서버)는 가장 중요한 정보를 Vault에서 가져옴 (id, pw ...)
  • 덜 중요한 정보는 Github를 통해 가져옴 (application.yml ...)
    • application.yml에는 `${vault.gitId}`로 vault값을 사용하고 있음
application.yml 또는 application.properties에 굳이 ${vault.gitId}를 사용하지 않고, Vault에서 "spring.cloud.config.server.git.username" 키에 값을 넣으면 자동으로 적용되게 된다. 따라서 소스코드에서 Vault를 통해 값을 주입받는다는 기록을 남기지 않을 수 있다. 나는 왜 Vault에서 값을 가져온다고 명시했냐면 추후 설정정보를 변경하게 될 때 빠르게 찾기 위해서이다. 이것 또한 trade-off이다. 소스코드에 남기느냐 남기지 않느냐이기 때문이다.

 

🚀 문제점

  • 각 마이크로서비스들은 Vault에서 값을 가져오지 못하는 문제점 발생
    • `${vault.gitId}`를 문자 그대로 인식하고 있는 문제점
    • 즉, Vault에서 값을 못가져왔음

따라서 나는 2가지 해결방법을 생각했다.

  1. Vault에서 값을 가져오도록 각 MS(마이크로서비스)에 Vault와 Bootstrap 라이브러리 추가하기 (유연성 하락)
  2. Github의 application.yml에 id,pw 명시하기 (보안 하락)

보안을 선택하면 각 마이크로서비스들은 Vault에 의존성이 생기며,

유연성을 선택하면 구성 서버만 잘 관리하면 된다. 

 

🚀 해결방법

보안을 선택한 Spring Cloud 아키텍처 구조

보안을 선택해서 각 MS들도 Vault와 Bootstrap 라이브러리를 추가했다.

Github에 중요 정보를 적어놓으면 불안하기 때문이다.

때문에 Vault와 Config Server(구성서버)의 고가용성이 보장되어야하는 아키텍처 구조가 만들어졌다.

 

✅ 그런데 순간 머리에서 생각이 팍! 하고 나왔다.

Config Server의 백엔드 저장소를 vault, github, native를 사용하고 있는데 그러면 여기 저장소들에서 설정값을 MS에 배포하니 MS에서는 Vault를 의존하지 않아도 되는것이 아닌가????

Config Server에서 배포하는 UserService의 설정파일

Config Server에서 Vault에 user-service/dev 값을 넣으니 위 그림처럼 제공되고 있었다.

즉, MS에서는 Vault를 의존하지 않고 Config Server에서 모든 값들을 제공받으므로 의존성을 추가하지 않아도 됐다.

Native에 있던 것은 테스트하려고 한 것이라 Github에 이동시킬 예정

Spring Cloud Config Server에서 제공하는 설정정보

  • Config Serveer가 Vault와 Github에서 설정정보를 가져와 취합하여 한번에 설정정보를 제공
  • MS들은 Config Server만 의존하면 됨
  • MS들은 Vault 라이브러리를 추가하지않아도 되었음

처음 봤었던 아키텍처 구조와 동일하게 보안적으로 향상된 구조가 되었다.

한 쪽을 선택해서 다른 한 쪽을 포기하게 되는 trade-off를 생각하다보니 큰 고민을 하게 되었다.

고민을 가지고 깊게 생각하다보니 내가 놓치고 있었던 부분을 발견하게 되어 최고의 선택지가 나오게 되었다.

 

처음에는 단순하게 MS에다가 Vault 라이브러리를 추가하여 값을 읽도록 하지만 의존성이 생기는 차선책을 선택했지만,

Spring Cloud Config Server의 백엔드 저장소를 제대로 생각하지 못했다는 점을 깨달았다.

Vault의 Secret Engine은 각 MS별로 만들어야하는 줄 알았기 때문이다. (나 약간 바보...?)

Config Server가 읽고있는 Secret Engine에다가 "user-service/dev" 를 만들어 값을 넣으니 제대로 작동되었다.

Vault 저장소

위 사진처럼 "config-service-secret" 이라는 Secret Engine이 있는데, 여기에 "user-service" 값을 넣었어야 했는데 또 다른 Secret Engine으로 만들었었다. 그래서 각 MS별로 Secret Engine을 읽어야하는 줄 알았는데 Config Server가 읽어서 거기서 나온 값을 MS로 전달하면 되었던 것이다. 계속 코드를 살펴보고 찾다보니 이렇게 놓치고 있었다는 점을 깨닫게 된다.

 

글로 설명하면 이해가 안갈 수 있으니 그림으로 내가 착각했던 것을 남겨본다.

착각했던 Vault 사용법과 올바른 Vault 사용법

파란색이 Secret Engine을 의미한다. 

 

Spring Cloud Config Server와 Vault에 대한 자료 및 강의가 많이 없기에 외국 행님들의 영상도 찾아보며 고생했던 기억이 무척 많이 남았다. 그래서 글을 써보게 되는데, 나중에는 무료강의도 한번 찍어볼 수 있지 않을까 싶다.