Chapter 14 - 클라우드 구성 관리

ChapJun·2022년 3월 12일
0

14.1 구성 공유하기 (Spring Cloud Config Server)

  • 여러 마이크로 서비스 간에 설정을 공유하려면 중앙집중식 Config Server가 필요하다.

중앙 집중식 구성의 장점 (= 스프링 클라우드 구성 서버의 장점 )

  1. 구성이 더 이상 애플리케이션 코드에 패키징되어 배포되지 않는다. 따라서 애플리케이션을 다시 빌드하거나 배포하지 않고 구성을 변경하거나 원래 값으로 환원할 수 있다.

  2. 공통적인 구성을 공유하는 마이크로서비스가 자신의 속성 설정으로 유지/관리하지않고도 동일한 속성들을 공유할 수 있다. 그리고 속성 변경이 필요하면 한 곳에서 한번만 변경해도 모든 마이크로서비스에 적용할 수 있다.

  3. 보안에 민감한 구성 속성은 애플리케이션 코드와는 별도로 암호화하고 유지/관리할 수 있다. 그리고 복호화된 속성 값을 언제든지 애플리케이션에서 사용할 수 있으므로 복호화를 하는 코드가 애플리케이션에 없어도 된다.

스프링 클라우드 구성서버는 애플리케이션의 모든 마이크로서비스가 구성에 의존할 수 있는 서버를 사용해서 중앙 집중식 구성을 제공한다. 따라서 모든 서비스에 공통된 구성은 물론이고, 특정 서비스에 국한된 구성도 한 곳에 관리할 수 있다.

14.2 구성 서버 실행하기

  • GitHub, GitLab, MS의 Team Foundation Server, Gogs 등의 Git 구현 서버가 구성 서버의 백엔드로 사용될 수 있다.

  • 보안처리된 속성은 주로 Vault를 사용한다.

14.2.1 구성 서버 활성화하기

  • 스프링 클라우드 구성서버 의존성을 추가한다.
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<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>
  • @EnableConfigServer 어노테이션을 추가하여 구성서버로 작동시킨다.
@SpringBootApplication
@EnableConfigServer
public class ConfigServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServiceApplication.class, args);
    }

}
  • 구성 서버의 application.yml (git 계정 방식)
server:
  port: 8888 
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/habuma/tacocloud-config
          username:			#git userId
          password:			#git password
          search-paths:     #sub directory
          default-label:    #branch
  • 공개키를 이용한 SSH로 가져오는 방식

https://oingdaddy.tistory.com/188


  • 구성 서버가 클라이언트에 제공하는 구성 속성은 Git의 repository에서 가져온다. (HTTP GET 요청)

구성 서버의 클라이언트인 것처럼 구성 서버를 테스트해볼 수 있다.

  • localhost:8888 : 구성 서버의 호스트 이름과 포트
  • application : 애플리케이션 이름(spring.application.name)
  • default : 활성화된 스프링 프로파일 (기본값. default -> dev, test 파일 존재시 가져올 수 있음)
  • master : Git 라벨/분기(생략 가능, master가 기본값 -> branch)

Git에 ecommerce.yml 올린 후 호출 시 응답 값 test 결과

// 20220312115430
// http://localhost:8888/ecommerce/default # http://IP:PORT/yml파일이름/프로파일/브랜치

{
  "name": "ecommerce",
  "profiles": [
    "default"
  ],
  "label": null,
  "version": "a933c7262f624b53eec35921e08d67ba997c013c",
  "state": null,
  "propertySources": [
    {
      "name": "git@github.com:ChapJun/springcloud.git/file:C:\\Users\\82105\\AppData\\Local\\Temp\\config-repo-8849544333285225778\\ecommerce.yml",
      "source": {
        "token.expiration_time": 86400000,
        "token.secret": "my_token",
        "gateway.ip": "xxx.xxx.x.xxx",
        "my.greeting": "hello world from config server",
        "order_service.url": "http://ORDER-SERVICE/order-service/%s/orders"
      }
    }
  ]
}

14.3 공유되는 구성 데이터 사용하기

  • 구성 서버의 설정 값들을 사용하는 서비스에서 dependency 추가
 		<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>
  • /resources/bootstrap.yml (application.yml 보다 우선순위가 높음 - 먼저 로딩을 해야함)
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name:  # yml 파일 이름
  profiles:
    active: dev      

14.4 애플리케이션이나 프로파일에 특정된 속성 제공하기

14.4.1 애플리케이션에 특정된 속성 제공하기

  • Git 백엔드에 application.yml, ingredient-serivce.yml, order-service.yml ... 이라는 이름의 YAML 구성 파일들을 생성하고 요청하면 된다.

14.4.2 프로파일로부터 속성 제공하기

  • Git 백엔드에 application.yml, application-production.yml 이라는 이름의 YAML 구성 파일들을 생성하고 요청하면 된다.

14.5 구성 속성들의 보안 유지하기

  • 구성서버에서 민감한 정보(비밀번호나 보안 토큰 등)를 포함하는 속성들을 제공해야 할 경우가 있다.

  • 보안 구성 속성을 사용할 때 구성서버는 두 가지 옵션을 제공한다.

  1. Git 백엔드 Repo에 저장된 구성파일에 암호화된 값 쓰기
  2. Git 백엔드 Repo에 추가하여 구성서버의 백엔드 저장소로 해시코프 Vault 사용하기

14.5.1 Git 백엔드 repo에 저장된 구성 파일에 암호화된 값 쓰기

  • Git 백엔드 repo에 저장되는 암호화된 데이터를 사용하는 핵심은 암호화 키(encryption key)이다.

  • 암호화된 속성을 사용하기 위해서는 암호화 키를 사용해 구성 서버를 구성해야 하며, 암호화 키는 속성 값을 클라이언트 애플리케이션에 제공하기 전에 복호화하는데 사용된다.

  • 대칭 키와 비대칭 키 모두 지원한다.

대칭 키(암호화와 복호화에 사용하는 암호 키가 같음)

# bootstrap.yml
encrpyt:
  key: s3cr3t

비대칭 키(암호화와 복호화에 사용하는 암호 키가 다르고 암호화 : 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 앤드포인트에 하면 된다.

POST 요청으로 암호화된 값 응답 받기 (몽고DB 비밀번호)

$ curl localhost:8888/encrypt -d "s3cr3tP455w0rd"

-> 93912a660a7f3c04e811b5df9a3cf6e1f63850cdcd4aa092cf5a3f7e1662fab7

Git repo에 저장된 application.yml 파일에 spring.data.mongodb.password 속성 추가

spring:
  data:
    mongodb:
      password: '{cipher}93912a660a7f3c04e811b5df9a3cf6e1f63850...'
      
# cipher -> 암호화된 값      
  • 기본적으로 구성 서버가 제공하는 암호화된 값은 백엔드 Git repo에 저장되어 있을 때만 암호화되어 있으며, 구성 서버에 의해 복호화된 후 제공된다. 따라서, 복호화하는 코드를 애플리케이션 코드에 포함시킬 필요 없다.

암호화된 값 받기

구성 서버의 bootstrap.yml에 spring.cloud.config.server.encrypt.enabled 속성을 false로 설정하면 된다.

server:
  port: 8888 
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/habuma/tacocloud-config
          username:			#git userId
          password:			#git password
          search-paths:     #sub directory
          default-label:    #branch
        encrypt:
        	enabled: false

14.6 실시간으로 구성 속성 리프레시

수동식과 자동식이 존재하며 수동식은 매우 번거롭기 때문에 자동으로 적용하는 방법을 사용한다.

14.6.1 구성 속성 수동으로 리프레시

14.6.2 구성 속성 자동으로 리프레시

  • 자동식 : Repo의 commit hook가 모든 서비스의 리프레시를 촉발

속성 리프레시 절차

  • 웹훅이 Git repo에 생성되어 Git repo에 대한 변경이 생겼을을 구성 서버에 알려준다.
    웹훅은 GitHub, GitLab, Bitbucket, Gogs를 비롯한 많은 리퍼지터리에서 지원된다.

  • 구성 서버는 RabbitMQ나 Kafka와 같은 메시지 브로커를 통하여 변경 관련 메시지를 전파함으로써 웹훅의 POST 요청에 반응한다.

  • 알림을 구독하는 구성 서버 클라이언트 애플리케이션은 구성 서버로부터 받은 새로운 속성 값으로 자신의 속성을 리프레시한다.

  • 구성 서버와 이것의 클라이언트 간의 메시지 처리에 사용할 수 있는 메시지 브로커가 있어야 하며, RabbitMQ나 Kafka 중 하나를 선택할 수 있다.

  • 구성 서버에 변경을 알려주기 위해 웹훅이 백엔드 Git repo에 생성되어야 한다.

  • 구성 서버는 구성 서버 모니터 의존성 및 RabbitMQ 나 카프카 스프링 클라우드 스트림 의존성과 함께 활성화되어야 한다.

  • 메시지 브로커가 기본 설정으로 로컬에서 실행되는 것이 아니라면, 브로커에 연결하기 위한 세부 정보를 구성 서버와 이것의 모든 클라이언트에 구성해야 한다.

  • 각 구성 서버 클라이언트 애플리케이션에 스프링 클라우드 버스 의존성이 추가되어야 한다.

요약

  • 스프링 클라우드 구성 서버는 중앙 집중화된 구성 데이터 소스를 마이크로서비스 기반의 더 큰 애플리케이션을 구성하는 모든 마이크로서비스에 제공한다.

  • 구성 서버가 제공하는 속성들은 백엔드 Git이나 Vault 리퍼지터리에서 유지 / 관리된다.

  • 모든 구성 서버 클라이언트에 제공되는 전역적인 속성들에 추가하여 구성 서버는 프로파일에 특정된 속성과 애플리케이션에 특정된 속성도 제공할 수 있다.

  • 보안에 민감한 속성들은 백엔드 Git 리퍼지터리에 암호화하여 저장하거나 Vault 백엔드의 보안 속성으로 저장하여 보안을 유지할 수 있다.

  • 구성 서버 클라이언트는 새로운 속성으로 리프레시할 수 있다. 이때 액추에이터 엔드포인트를 통해 수동으로 리프레시하거나, 스프링 클라우드 버스와 Git 웹훅을 사용해서 자동으로 리프레시할 수 있다.

profile
Chap Chap

0개의 댓글