[마이크로 서비스 패턴] 프로덕션 레디 서비스 개발

피누·2021년 4월 17일
1
post-thumbnail

본 포스팅은 마이크로서비스 패턴의 일부 내용을 정리한 내용입니다.

서비스를 프로덕션에 배포할 수 있게 준비하려면 세 가지 핵심 품질 속성, 즉 보안, 구성성, 관측성이 보장되어야한다.

보안 서비스 개발

애플리케이션 개발자는 주로 인증, 인가, 감사, 보안 IPC 보안 요소를 구현한다.

기존 모놀리식 애플리케이션의 보안

  • 기존 애플리케이션의 인증 과정
  • 보안 아키텍처의 핵심은 세션과 보안 컨텍스트
  • 보안 컨텍스트는 현재 요청을 보낸 사용자 정보를 담고 있다. 스프링 시큐리티 프레임워크에서는 자바 EE 표준에 따라 스레드 로컬 변수에 저장하기 때문에 모든 요청 핸들러 코드는 얼마든지 보안 컨텍스트에 접근 가능하다.

마이크로서비스 아키텍처에서의 보안 구현

  • 분산된 여러 서비스는 스스로 인증/인가를 조합해 구현해야한다. 예를 들면 주문 서비스는 소비자 본인의 주문 정보만 조회 가능해야 하는데 사용자의 인증/인가 처리를 누가 담당할지부터 결정해야한다.

  • 모놀리식에서 통했던 다음 두 가지 보안 요소는 MSA에서는 전혀 해당되지 않는다.

    • 인-메모리 보안 컨텍스트: 서비스는 메모리를 공유할 수 없으므로 메모리를 통해 신원을 전달 할 수 없다.
    • 중앙화 세션: 이론상 여러 서비스가 DB 기반의 세션에 접근하는 것이 가능하나 느슨한 결합 원칙에 위배된다.
  • API 게이트웨이에서 인증 처리
    서비스마다 사용자를 인증한다면 미인증 요청이 내부 네트워크로 들어올 수 있고 모든 개발자가 제대로 보안을 구현하리라 보기 어렵기 때문에 보안 취약점이 노출될 가능성이 크다. 또한 클라이언트마다 다양한 인증 메커니즘을 모두 처리해야 한다.
    때문에 요청을 서비스에 보내기전에 API 게이트웨이가 인증하는 것이 좋다. 인증 로직을 중앙화할 수 있어 보안 취약점 노출 가능성이 줄어들고 복잡한 인증 메커니즘 코드를 서비스에서 감출 수 있다.


  • 인가 처리
    가장 간단한 인가 구현 후보지는 API 게이트웨이로 보이나, 이는 API 게이트웨이와 서비스가 단단히 결합하게 된다는 문제점이 있다. 또한 API 게이트웨이는 역할 기반의 URL 경로 접근만 구현할 수 있어 개별 도메인 객체의 접근 권한을 제어하는 ACL까지 구현은 무리다. 따라서 인가 로직은 서비스에 구현하는 것이 좋다.

구성 가능한 서비스 설계

서비스 실행에 필요한 구성 프로퍼티(DB 도메인, 자격증명 등)는 실행 환경마다 다르기에 배포 서비스에 하드 코딩하는 것은 효율적이지 않다. 스프링 프레임워크의 프로파일 장치로 런타임에 프로퍼티 세트를 선택하는 구조는 보안에 취약하고 배포에 한계가 있다. 게다가 자격증명처럼 민감한 데이터는 볼트와 같은 보안 저장 장치로 안전하게 저장되어야 한다. 따라서 외부화 구성 패턴에 따라 런타임에 적잡한 구성 프로퍼티를 서비스에 제공하는 방법을 권장한다.

푸시 기반의 외부화 구성
서비스 인스턴스가 생성될 때 프로퍼티 값을 제공한다.도커 컨테이너를 통해 환경 변수를 지정하는 방법도 이 중 하나이다. 푸시 모델은 지금도 널리 사용되는 서비스 구성 메커니즘이지만 이미 실행 중인 서비스를 재구성하기는 어려운 한계가 있다. 구성 프로퍼티 값이 여러 서비스에 흝어지는 것도 문제이다.

풀 기반의 외부화 구성
풀 모델은 서비스 인스턴스가 시동 시 자신이 필요한 값을 구성 전용 서버에 접속하여 읽는 방식이다.

구성 서버를 구현하는 방법에는 여러가지가 있지만 스프링 클라우드 컨피그가 유명한 구성 서버 기반 프레임워크이다. 구성서버가 있으면 모든 구성 프로퍼티를 한곳에서 관리할 수 있고 중복 구성 프로퍼티를 제거할 수 있다. 또 자격증명 등 민감한 데이터의 암복호화를 제공한다. 또한 수정된 프로퍼티 값을 폴링 등으로 감지해서 동적 재구성이 가능하다.

관측 가능한 서비스 설계

서비스 운영자 입장에서는 초당 요청 수, 리소스 이용률 등 현재 애플리케이션에 상태를 알 수 있어야 하며 트러블 슈팅이 가능해야 한다.

헬스 체크 API 패턴

  • 서비스는 서비스 상태를 반환하는 GET /health 등의 헬스 체크 API 끝점을 표출한다.
  • 헬스 체크 끝점을 구현한 코드는 인스턴스의 상태를 어떻게든 판단해야 한다. 이 끝점은 배포 인프라가 호출한다.

로그 수집 패턴

  • 전체 서비스 로그를 중앙 DB에 수집하여 검색/알림 기능을 제공한다.
  • 로그 파이프라인과 로깅 서버는 보통 운영 팀이 담당하지만 유용한 로그를 남기는 코딩 작업은 서비스 개발자의 몫이다.

분산 추척 패턴

  • 외부 요청마다 유일한 ID를 하나씩 부여해서 서비스가 흘러가는 과정을 기록하고 시각화/분석 기능을 제공하는 중앙화 서버에 자료를 남긴다.
  • 인스트루멘테이션 라이브러리는 스팬 트리를 만들어 분산 추적 서버로 보낸다. 관련 코드는 AOP를 이용해 관심사를 분리하여 구현하는 것이 바람직하다.
  • AOP 프레임웍으로 알려진 스프링 클라우드 슬루스는 분산 추적 기능을 서비스에 자동 연계합니다. 이 라이브러리를 디펜던시로 추가하면 서비스가 분산 추척 API를 직접 호출 할 필요가 없다.

애플리케이션 지표 패턴

  • 서비스는 수집, 시각화, 알림 기능을 제공하는 중앙 서버로 지표를 보고한다.
  • 모니터링 역시 대부분 운영 팀이 관장하지만 서비스 개발자는 자신의 동작에 관한 지표를 수집하도록 구현하고, 이런 지표를 JVM 및 애플리케이션 프레임워크 수준에서 수집한 지표화 함께 지표 서버에 표출해야한다.
  • 서비스는 수집한 지표를 푸시 또는 풀 방식으로 매트릭스 서비스에 전달한다.

예외 추적 패턴

  • 서비스는 중복된 예외를 제거하고, 알림을 생성하고 예외 해결 과정을 관리하는 중앙 서비스에 예외를 보고한다.

감사 로깅 패턴

  • 고객 지원, 컴플라이언스 준수, 수상한 동작 감지를 위해 사용자 액션을 DB에 저장한다.
  • 감사 로깅을 구현하는 방법은 비즈니스 로직에 추가하거나, AOP를 활용하하거나 이벤트 소싱을 이용할 수 있다.

서비스 개발 마이크로 서비스 새시 패턴

앞에서 본 여러 요소들 외에도 디스커버리, 회로 차단기 기능을 서비스에 추가 구현이 필요한데 이런 작업을 서비스를 개발 할 때마다 반복되는 것은 말이 안된다. 마이크로 서비스 새시 기반으로 서비스를 구축하면 횡단 관심사를 처리하는 코드를 서비스에 작성할 일이 거의 없고 개발 속도는 그만큼 빨라진다.

예제 어플리케이션은 스프링 부트, 스프링 클라우드를 마이크로 서비스 새시로 활용한다. 서비스를 개발하는 모든 언어/플랫폼 조합마다 마이크로 서비스 새시가 하나씩 필요한 단점이 있다. 다행히도 마이크로 서비스 새시에 구현된 기능은 대부분 인프라에 대신 구현할 수 있다.

이제는 서비스 메시로
마이크로서비스 새시는 언어마다 하나씩 필요하다는 단점이 있다. 이런 문제점 때문에 공통 기능 일부를 서비스 외부에 위치한 서비스 메시에 구현하게 된다. 서비스 메시는 한 서비스와 다른 서비스, 그리고 외부간의 소통을 조정하는 인프라로 서비스를 드나드는 트래픽은 모두 회로 차단기, 분산 추적, 서비스 디스커버리, 부하 분산, 룰 기반 트래픽 라우팅등 다양한 관심사가 구현된 서비스 메시를 통과한다.

서비스 메시 덕분에서 마이크로 서비스 새시는 외부화 구성, 헬스 체크등 애플리케이션 코드와 단단히 결합된 관심사만 구현하면 되기때문에 단순해진다.

profile
어려운 문제를 함께 풀어가는 것을 좋아합니다.

0개의 댓글