Enjoy My Posts

bintegration의 구성 관리

Posted on By Geunwon Lim

스프링 마이크로서비스 코딩공작소에 나온 내용

msa에서 사람이 수동으로 구성하거나 배포하면 구성편차와 예상하지 못한 장애, 애플리케이션 확장 요구에 대한 지체 시간이 발생할 수 있다고 한다.

구성 정보를 실제 코드 외부로 분리하면 관리하고 버전 제어를 해야 할 외부 의존성이 생긴다. 애플리케이션 구성을 제대로 관리하지 못하면 탐지하기 어려운 버그와 예상치 못한 장애를 만드므로 애플리케이션 구성 데이터를 추적하고 버전 제어하는 것은 아무리 강조해도 지나치지 않다.

존 카넬이 실제로 겪은 일화를 소개해주는데, 한 프롷젝트에서 발견한 중요한 문제 중 하나가 애플리케이션 팀이 데이터비에스와 서비스의 엔드포인트에 대한 모든 구성을 프로퍼티 파일로 관리한다는 것이었다고 한다. 이 프로퍼티 파일들은 수동으로 관리되며 버전 관리도 되지 않았다. 구성 파일이 엉망이어서 수백 개의 서버와 서버에서 실행 중인 애플리케이션에서 분산된 1만 2천개의 구성 파일을 마이그레이션 해야 했다고 한다. 이 파일들은 애플리케이션 서버 구서용 파일도 아니고 애플리케이션 구성용 파일이었다고 한다. 문제의 팀은 처음엔 소수의 애플리케이션으로 구성 전략을 수립했지만 5년간 구축하고 배포하는 웹 앱이 폭발적으로 증가했다고 한다. 구성 관리 방식의 재작업은 우선순위에서 밀리기 일쑤였다.

이 사례에서 구성 관리를 중앙화하는게 중요하다는 걸 느낄 수 있었다.

bintegration에 적용

bintegraion은 config server를 두고 config server에 구성 관리를 집중화한다. 그리고 비밀 정보를 보호하기 위해 대칭키 암호화를 사용하고, 대칭키는 AWS Secrets Manger로 관리한다.

configserver_package

위와 같이 config 서버는 src/main/resources 밑에 각 서비스 구성 정보를 폴더별로 갖고, 각 폴더는 환경에 따른 구성 파일이 있다.

예를 들어,

http://[config-server host]:[config-server port]/access/dev에 Get 요청을 하면, 다음과 같은 응답을 받는다.

{
    "name": "access",
    "profiles": [
        "dev"
    ],
    "label": null,
    "version": "6aa3017e9625c6ecb621eb755b6f53425d9b61e2",
    "state": null,
    "propertySources": [
        {
            "name": "https://github.com/beyond-eyesight/bintegration/config/src/main/resources/config/access/access-dev.yml",
            "source": {
                "spring.datasource.url": "jdbc:mysql://test-access-1.cuwocpon5oew.ap-northeast-2.rds.amazonaws.com:3306/access",
                "spring.datasource.username": "beyondeyesight",
                "spring.datasource.password": "{cipher}4517326d65dc7a7424d981f3f0c42b90da31317ef28dec52246af9a5a98ea480",
                "spring.jpa.show-sql": true,
                "spring.jpa.hibernate.ddl-auto": "update",
                "spring.jpa.properties.hibernate.show-sql": true,
                "spring.jpa.properties.hibernate.format_sql": true,
                "spring.jpa.properties.hibernate.dialect": "org.hibernate.dialect.MySQL8Dialect"
            }
        }
    ]
}

다음과 같이 중요한 정보는 암호화되어 전달받는다.

“spring.datasource.password”: “{cipher}4517326d65dc7a7424d981f3f0c42b90da31317ef28dec52246af9a5a98ea480”

그리고 task-definition에

"secrets": [{
  "name": "ENCRYPT_KEY",
  "valueFrom": "arn:aws:secretsmanager:ap-northeast-2:174579883227:secret:ENCRYPT_KEY-I43Lmf"
}]

이렇게 SecretsManager arn을 설정해주면 서비스를 배포할 때 인스턴스 환경 변수에 대칭키를 할당하고, 그 대칭키로 중요 정보를 복호화한다.

비대칭키를 활용하면 좀 더 보안적으로 좋다고 하는데, 현재 단계에서는 대칭키도 충분한 것 같다.

ecs-cli compose로 수동 배포할 때는

version: "3"
services:
  access:
    image: beyondeyesight/access:latest
    ports:
      - "8081:8081"
    environment:
      ENCRYPT_KEY: ${ENCRYPT_KEY}

이렇게 로컬 환경의 환경 변수를 활용할 수 있다.