Notepad

프로덕션 레디 서비스 개발

핵심 내용

  • 보안 서비스 개발
  • 외부화 구성 패턴 적용
  • 관측성 패턴 적용
  • 마이크로서비스 섀시 패턴을 응용한 서비스 개발 단순화

보안 서비스 개발

  • 애플리케이션 개발자가 주로 구현하는 네 가지 보안 요소
    • 인증(Authentication): 애플리케이션에 접근하는 애플리케이션이나 사람의 신원 확인
    • 인가(Authorization): 주체가 어떤 데이터에 어떤 작업을 요청하여 수행할 수 있는 권한이 있는지 확인
    • 감사(auditing): 보안 이슈 탐지, 컴플라이언스 시행, 고객 지원을 위해 주체가 수행하는 작업 추적
    • 보안 IPC

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

애플리케이션의 클라이언트가 인증을 요청하는 과정

  1. 사용자: ID/패스워드로 로그인
  2. 클라이언트: 사용자 자격증명을 애플리케이션에 POST로 요청
  3. 애플리케이션: 자격증명이 맞으면 클라이언트에 세션 토큰을 반환
  4. 클라이언트: 이후 요청은 모두 이 세션 토큰을 포함시켜 전송

보안 아키텍처에서의 핵심은 세션(session)

  • 주체의 ID와 역할은 세션에 보관
  • 자바 애플리케이션은 HttpSession 객체를 메모리에서 관리
  • 예: FTGO 애플리케이션의 세션 토큰은 JESSIONID라는 HTTP 쿠키

보안 컨텍스트(security context)

  • 현재 요청을 보낸 사용자 정보를 보안 컨텍스트에 저장
  • 자바 EE 표준에는 보안 컨텍스트를 정적 스레드 로컬 변수에 저장
  • 모든 요청 핸들러 코드가 얼마든지 보안 컨텍스트에 접근 가능

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

  • MSA는 모든 외부 요청을 API 게이트웨이와 하나 이상의 서비스가 처리하는 분산 시스템
  • MSA에서 보안을 구현하려면 먼저 사용자의 인증/인사 처리를 누가 담당할지부터 결정해야함
  • 모놀리식에서는 통했지만 MSA에서는 사용할 수 없는 방법들
    • 인-메모리 보안 컨텍스트
    • 중앙화 세션
  • MSA에서는 다른 방식이 필요

API 게이트웨이에서 인증 처리

  • 인증 처리 방법
    • 서비스마다 알아서 사용자를 인증하는 방식
      • 미인증 요청이 내부 네트워크에 들어올 수 있음
      • 모든 개발자가 제대로 보안을 구현하리라 보기 어렵기에 보안 취약점 노출 위험성이 큼
      • 인증하는 방식이 클라이언트마다 제각각일 수 있음
    • 요청을 서비스에 보내기 전에 API 게이트웨이가 요청을 인증하는 방식(추천)
      • 인증 로직을 API 게이트웨이에 중앙화하면 나중에 문제가 생겨도 한곳만 수정하면 되기에 보안 취약점 노출 가능성이 줄어듬
      • 복잡한 코드도 서비스에서 감출 수 있음
      • 처리 방식
        • API 클라이언트: 자격증명을 포함시켜 요청 전송 후 세션 토큰 발급 받음
        • API 게이트웨이: 요청을 인증 후, 하나 이상의 서비스를 호출

인가 처리

  • 해당 클라이언트가 요청한 작업을 할 수 있도록 허가되었는지 검사하는 인가 메커니즘 역시 중요함
  • 인증처럼 인가 로직도 API 게이트웨이 내부에 중앙화하면 보안을 강화할 수 있지만 추천 하지 않음
    • API 게이트웨이와 서비스가 단단히 결함하게 되어서 나중에 변경할 일이 생기면 서로 맞물리게 될 수 있음
    • 역할 기반의 URL 경로 접근만 구현할 수 있으며, 개별 도메인 객체의 접근 권한을 제어하는 ACL(접근 제어 목록) 까지 구현하기에는 무리
  • 인가 로직은 서비스에 구현하는 것이 좋음
    • 서비스가 직접 역할 기나으로 URL과 메서드를 인가하고, ACL로 애그리거트 접근을 따로 관리

JWT로 사용자 신원/역할 전달

  • API 게이트웨이가 어떤 종류의 토큰에 사용자 정보를 담아 서비스에 전달할지 결정해야함
  • 토큰 종류
    • 난독화 토큰
      • UUID가 많이 사용되며, 성능 및 가용성이 떨어지고 지연 시간이 길다는 것이 단점
    • 보안 서비스 호출이 필요 없는 투명 토큰
      • JWT(JSON Web Token)이 사실상 투명 토큰의 표준
      • 두 당사자 간의 사용자 신원/역할 등의 정보를 안전하게 표현하는 표준 수단
      • 각종 메타데이터가 포함된 JSON 객체를 페이로드에 담아 JWT 생성자와 JWT 수신자만 알 수 잇는 시크릿으로 서명함
      • JWT는 토큰 자체가 포함되어 있기 때문에 취소할 수 없는 문제가 있음
      • 유효 기간이 짧은 JWT를 발급해야함

OAuth 2.0 응용

  • OAuth 2.0: 퍼블릭 클라우드 서비스 사용자가 자기 정보에 접근하려는 서드파티 애플리케이션을 패스워드 노출 없이 허가할 수 있는 방안을 찾다가 정착된 인증 프로토콜
  • OAuth 2.0을 애플리케이션의 인증/인가 용도로도 사용할 수 있음
  • OAuth 2.0 핵심 개념
    • 인증 서버
    • 액세스 토큰
    • 리프레시 토큰
    • 리소스 서버
    • 클라이언트
  • API 클라이언트의 요청을 API 게이트웨이가 인증하는 과정
    • 클라이언트는 기본 인증을 이용하여 자격증명과 함께 요청
    • API 게이트웨이는 OAuth 2.0 인증 서버에 패스워드 승인을 요청
    • 인증 서버는 API 클라이언트의 자격증명을 검증하고 엑세스/리프레시 토큰을 반환
    • API 게이트웨이는 서비스에 요청을 할 때마다 발급받은 엑세스 토큰을 넣어 보내고, 서비스는 액세스 토큰을 이용하여 요청을 인증
  • 액세스 토큰을 세션 토큰처럼 이용해서 세션 지향 클라이언트를 인증할 수 있음
    • 로그인 기반의 클라이언트가 자격증명을 API 게이트웨이에 POST
    • API 게이트웨이의 로그인 핸들러는 OAuth 2.0 인증 서버에 패스워드 승인을 요청
    • 인증 서버는 클라이언트의 자격증명을 검증 후, 액세스/리프레시 토큰을 반환
    • API 게이트웨이 인증 서버에서 받은 두 토큰을 클라이언트에 반환
    • 클라이언트는 액세스/리프레시 토큰을 API 게이트웨이에 요청할 때마다 실어 보냄
    • API 게이트웨이의 세션 인증 인터셉터는 액세스 토큰을 검증 후 서비스에 토큰을 넣어 보냄

구성 가능한 서비스 설계

  • 여러 구성 프로퍼티를 소스 코드에 미리 하드 코딩해 놓거나, 스프링 프레임워크의 프로파일 장치로 런타임에 프로퍼티 세트를 선택하는 구조는 보안에 취약하고 배포에 한계가 있어서 적절치 않음
  • 런타임에 구성 프로퍼티 값을 서비스에 제공하는 외부화 구성 메커니즘
    • 푸시 모델: OS 환경 변수, 구성 파일 등을 통해 배포 인프라에서 서비스로 프로퍼티 값 전달
    • 풀 모델: 서비스 인스턴스가 구성 서버에 접속해서 프로퍼티 값을 읽어옴

푸시 기반의 외부화 구성

  • OS 환경 변수, 구성 파일 등을 통해 배포 인프라에서 서비스로 프로퍼티 값 전달
    • 도커 컨테이너를 통해 환경 변수를 지정하는 방법
    • 스프링 부트
      • CLI 인수
      • JVM 시스템 프로퍼티
      • OS 환경변수
      • 현재 디렉터리의 구성 파일

풀 기반의 외부화 구성

  • 서비스 인스턴스가 구성 서버에 접속해서 프로퍼티 값을 읽어옴
    • 버전 관리 시스템
    • SQL/NoSQL DB
    • 전용 구성 서버(스프링 클라우드 컨피스 서버), 해시코프 볼트, AWS 파라미터 스토어
  • 스프링 클라우드 컨피그
    • 서버/클라이언트로 구성된, 유명한 구성 서버 기반 프레임워크
    • 서버: 버전 관리 시스템, DB, 해시코프 볼트 등 구성 프로퍼티 를 저장하는 다양한 백엔드 기술 지원
    • 클라이언트: 서버에서 구성 프로퍼티를 가져와 스프링 ApplicationContext에 주입하는 역할
  • 구성 서버 장점
    • 중앙화 구성
    • 민감한 데이터의 투명한 복호화
    • 동적 재구성

관측 가능한 서비스 설계

  • 관측 가능한 서비스를 설계하는 패턴
    • 헬스 체크 API: 서비스 헬스를 반환하는 끝점을 표출
    • 로그 수집: 서비스 활동을 로깅하면서 검색/경고 기능이 구현된 중앙 로그 서버에 로그 출력
    • 분산 추척: 각 외부 요청에 ID를 하나씩 붙여 서비스 사이를 드나드는 과정을 추적
    • 예외 추적: 예외 중복 제거, 개발자 알림, 예외별 해결 상황 추적 등을 수행하는 예외 추적 서비스에 예외를 보고
    • 애플리케이션 지표: 서비스는 카운터, 게이지 등 지표를 유지하고, 수집한 데이터를 지표 서버에 표줄
    • 감사 로깅: 사용자 액션을 로깅

헬스 체크 API 패턴

  • 서비스는 서비스 상태를 반환하는 GET /health 등의 헬스 체크 API로 엔드포인트를 표출함

헬스 체크 엔드포인트 구현

  • 헬스 체크 엔드포인트를 구현한 코드는 서비스 인스턴스의 상태를 어떻게든 판단해야함
  • 스프링 부트 액추에이터는 /actuator/health 엔드포인트를 호출하면 헬스 체크 실행 결과를 반환함

헬스 체크 엔드포인트 호출

  • 호출하는 코드가 없으면 헬스 체크 엔드포인트는 쓸모가 없기에 서비스를 배포할 때 배포 인프라가 헬스 체크 엔드포인트를 호출하도록 구성해야함
  • 헬스 체크 엔드포인트 호출 방법
    • 서비스 레지스트리(예: 넷플릭스 유레카)가 헬스 체크 엔드포인트를 호출하도록 구성해서 서비스 인스턴스로 전송이 되었는지 확인
    • 도커, 쿠버네티스로 구성하는 방법은 12장에서 설명

로그 수집 패턴

  • 전체 서비스 로그를 중앙 DB에 수집하여 검색/알림 기능을 제공
  • 모든 서비스 인스턴스가 남긴 로그를 로그 수집 파이프라인을 통해 중앙 로깅 서버로 보내는 것

서비스 로그 생성

  • 적절한 로깅 라이브러리를 선택한 후, 로그 항목을 어디에 출력할지 결정 필요
  • 자바 로깅 라이브러리
    • 로그백, Log4J, JUL, Slf4J
  • Node.js 로깅 라이브러리
    • Log4js
  • 로그를 남길 장소 결정
    • 파일 시스템 경로에 로그 파일 생성(기존방식)
    • AWS 람다는 파일 시스템 자체가 없으므로 stdout에 로깅

로그 수집 인프라

  • 로깅 인프라는 로그를 수집, 저장함
  • 대표적인 로깅 인프라: ELK 스택
    • 엘라스틱 서치: 로깅 서버로 쓰이는 텍스트 검색 지향 NoSQL DB
    • 로그 스태시: 서비스 로그를 수집하여 엘라스틱 서치에 출력하는 로그 파이프라인
    • 키바나: 엘라스틱 서치 전용 시각화 툴
  • 오픈 소스 로그 파이프라인: Fluentd, 아파치 플룸
  • 로깅 서버: AWS 클라우드워치 로그 등

분산 추적 패턴

  • 외부 요청마다 유일한 ID를 하나씩 부여해서 한 서비스에서 다음 서비스로 흘러가는 과정을 기록하고, 시각화/분석 기능을 제공하는 중앙화 서버에 자료를 남김
  • 각 요청은 하나의 트레이스로 표시됨
    • 스팬: 작업을 나타내며, 작업명, 시작/종료 타임스탬프가 주요 속성이며 자식 스팬을 거느릴 수 있음
    • 트레이스: 하나 이상의 스팬으로 구성
  • 분산 추적은 각 서비스에 쓰이는 인스트루멘테이션 라이브러리와 분산 추적 서버 두 부분으로 구성

인스트루멘테이션 라이브러리

  • 스팬 트리를 만들어서 분산 추적 서버로 보냄

분산 추적 서버

  • 전달받은 스팬을 서로 짜깁기해서 와넞ㄴ한 트레이스 형태로 만든 후 DB에 저장
  • 잘 알려진 분산 추적 서버: 오픈 집킨

애플리케이션 지표 패턴

  • 서비스는 수집, 시각화, 알림 기능을 제공하는 중앙 서버로 지표를 보고

서비스 수준의 지표 수집

  • 스프링 부트 기반의 서비스는 마이크로미터 메트릭스라는 라이브러리를 디펜던시로 추가하고 구성 코드 몇 줄만 넣으면 기본 지표는 바로 수집 가능
  • 애플리케이션의 특정한 지표를 수집하고 싶다면 마이크로미터 메트릭스 API를 직접 호출하는 코드를 서비스에 작성하면 됨

지표 서비스에 지표 전달

  • 수집한 지표를 푸시 또는 풀 방식으로 메트릭스 서비스에 전달함
  • 푸시 모델
    • 서비스 인스턴스가 API를 호출하여 메트릭스 서비스에 지표를 밀어 넣는 방법(예: AWS 클라우드워치)
  • 풀 모델
    • 메트릭스 서비스(또는 로컬에서 실행되는 에이전트)가 서비스 API를 호출하여 서비스 인스턴스에서 지표를 당겨오는 방법(예: 프로메테우스)
  • 애플리케이션 지표는 애플리케이션의 동작을 파악하는 중요한 단서 제공

예외 추적 패턴

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

감사 로깅 패턴

  • 고객 지원, 컴플라이언스 준수, 수상한 동작 감지를 위해 사용자 액션을 DB에 저장

감사 로깅 코드를 비즈니스 로직에 추가

애스팩트 지향 프로그래밍 활용

이벤트 소싱 이용

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

마이크로서비스 섀시

  • 예외 추적, 로깅, 헬스 체크, 외부화 구성, 분산 추적 등의 횡단 관심사를 처리하는 프레임워크를 기반으로 서비스를 구축

참고

  • 마이크로서비스 패턴 자바(저 : 크리스 리처드슨)

'dev > 아키텍처' 카테고리의 다른 글

마이크로서비스 패턴(8)  (0) 2022.04.14
마이크로서비스 패턴(7)  (0) 2022.04.06
마이크로서비스 패턴(6)  (0) 2022.03.31
마이크로서비스 패턴(5)  (0) 2022.03.24
마이크로서비스 패턴(4)  (0) 2022.03.10
profile

Notepad

@Apio

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!