OAuth 2.0과 MSA 디자인패턴

뿌이·2022년 2월 9일
2

스프링 클라우드

목록 보기
8/32

OAuth 2.0 동작 방식의 이해

참고 블로그에 정리가 잘되어 있습니다. 저는 이 블로그를 요약하겠습니다.

OAuth 2.0(Open Authorization 2.0, OAuth2)

인증을 위한 개방형 표준 프로토콜 인데,
프로토콜에서는 리소스 소유자를 대신하여
리소스 서버에서 제공하는 자원에 대한 접근권한을 위임하는 방식을 제공

OAuth 2.0 방식 자체는 우리가 원하는 것처럼 이용하려는 애플리케이션에
비밀번호를 제공하지 않으면서 실제 서비스를 이용할 수 있도록 도움을 준다.
하지만 API 호출 요청에 대해 전달 받은 Access Token이 유효한 지를 확인하는 작업을 계속적으로 진행한다.

지금 같이 MSA 아키텍쳐를 구성하는 많은 서비스에서는 각각의 서버가 Access Token의 유효성 및 권한 확인을
인가 서버에 계속적으로 요청하여 병목 현상 등이 발생해 서버의 부하로 이어질 수 있는 문제가 존재한다.

이를 해결하기 위해 JWT 기반 인증 방식이 사용된다.

OAuth 2.0의 4가지 역할


리소스서버는 쉽게말하면, 우리가 네이버로그인 api를 사용할 때에
네이버 회원 정보를 우리의 웹페이지로 네이버 로그인 api를 사용해서 받아옵니다.
그럼 리소스서버는 네이버 회원정보를 갖고있는 자료 서버 = 네이버가 되는 셈

클라이언트는 우리 웹페이지 입니다.

  • 우리 웹페이지(클라이언트)가 사용자 정보를 받아오기 위해 네이버(리소스서버)에 요청했기 때문에

OAuth 2.0 주요 용어

OAuth 프로토콜의 종류

4개가 있으나, 본 글에서는 두개만 다루겠음 더 알고싶다면 참고 블로그 방문을 추천함

Authorization Code Grant│ 권한 부여 승인 코드 방식

권한 부여 승인을 위해 자체 생성한 Authorization Code를 전달하는 방식으로 많이 쓰이고
기본이 되는 방식입니다.
간편 로그인 기능(SNS 로그인 API)에서 사용되는 방식으로
클라이언트가 사용자를 대신하여 특정 자원에 접근을 요청할 때 사용되는 방식입니다.
보통 타사의 클라이언트에게 보호된 자원을 제공하기 위한 인증에 사용됩니다.
Refresh Token의 사용이 가능한 방식


이 그림을 쉽게 설명하자면 정말 딱 sns 로그인 api 그 자체이다.
어떤 웹 페이지를 들어간다.
그러면
이런 sns 로그인 창이 있다.
나는 naver 로그인을 하려고 한다.
그러면
이 추가 제공 항목들을 모두 파고다 홈페이지에 주는것에 동의해야지만
네이버 로그인을 할 수 있다
이게 user의 역할이다.

그래서 user가 동의 후 네이버 아이디와 비밀번호로 로그인을 하면,
네이버 서버에서는 권한 부여 승인코드를 어떤 웹페이지에 전달한다.
그러면 이제 클라이언트라고 불리우는 어떤 웹페이지는 다시 네이버 서버에 access token을 요청할 수 있다

엑세스 토큰이 네이버 서버에서 어떤 웹 페이지로 전달되면
이제부터는 네이버가 갖고있는 user정보를 요청하여 요청자원을 받아올 수 있는 것이다

이해가 쏙쏙되지 않는가???ㅋㅋㅋ

Resource Owner Password Credentials Grant │ 자원 소유자 자격증명 승인 방식

간단하게 username, password로 Access Token을 받는 방식입니다.
클라이언트가 타사의 외부 프로그램일 경우에는 이 방식을 적용하면 안됩니다.
자신의 서비스에서 제공하는 어플리케이션일 경우에만 사용되는 인증 방식입니다.
Refresh Token의 사용도 가능합니다


흐름은 간단합니다.
제공하는 API를 통해 username, password을 전달하여 Access Token을 받는 것입니다.

✨중요한 점은 이 방식은 권한 서버, 리소스 서버, 클라이언트가 모두 같은 시스템에 속해 있을 때 
사용되어야 하는 방식이라는 점

디자인 패턴

리액티브 마이크로서비스

동기방식 : 요청과 결과가 동시에 일어남 (블로킹 I/O)

- 장점 : 설계가 매우 간단하고 직관적임 

- 단점 : 결과가 주어질 때까지 아무것도 못하고 대기해야함

​

비동기방식 : 요청과 결과가 동시에 일어나지 않음 (논블로킹 I/O)

- 장점 : 결과가 주어지는데 시간이 걸리더라도 그 시간동안 다른 작업을 할 수 있음 ->자원을 효율적으로 사용

- 단점 : 동기보다 복잡함

관례적으로 자바개발자는 블로킹 I/O모델을 사용해 동기식 통신을 구현해왔다.

(단순하게 동기 방식으로 호출 -> 강한 의존성을 가짐)

이는 동시 요청수가 증가하거나 요청과 관련된 컴포넌트가 증가하면

운영체제의 가용 스레드가 부족해 응답시간이 늦어지거나 서버가 중단되는 문제가 발생한다.

이는 또 클라이언트한테도 문제를 유발한다. (연쇄장애)

이는 마이크로서비스의 강점을 사용하지 않고 모놀리식 서비스와 다를게 없다

그래서 도입되는 개념이 리액티브 마이크로 서비스이다.
reactive : 반응이 빠른
▶(논블로킹 I/O 사용 -> 데이터베이스나 다른 마이크로서비스가 처리하길 기다리는동안
스레드가 할당되지 않게 함)


위 그림에서 각 서비스에서 발생한 출력값이 다른서비스 입력값으로 들어가는데

특정 마이크로서비스의 값을 대기하는게 아니라 단지 자신의 입력 큐에 이벤트가 들어오기를 기다리고 있다.

그래서 마이크로서비스들은 서로의 존재를 알지 못한다.(이벤트발생을 리스닝 할 뿐)
messegeq 로 이어지는 것을 설명한 것이다.

서비스 검색 (Service Discovery)란?

마이크로서비스 아키텍처로 구성되어 있는 서비스들은 각자 다른 IP와 Port를 가지고 있다.

이러한 서로 다른 서비스들의 IP와 Port정보에 대해서 저장하고 관리할 필요가 있는데

이를 Service Discovery라고 한다

여러 서비스들을 운용할 때에 클라우드 환경에서 인스턴스는 생성, 삭제, 확장 등을 거치면서 IP나 Port들이 동적으로 변경될 가능성이 많다
이걸 일일히 알아내기엔 무리여서 서비스 검색이 필요하다

구현 방법

1. 클라이언트 사이드 디스커버리 패턴
서비스 클라이언트가 Service register에서 서비스의 위치를 찾아서 호출하는 방식

  • 장점
  1. 비교적 간단

  2. 클라이언트가 사용 가느한 서비스 인스턴스에 대해서 알고 있기 때문에 각 서비스별 로드밸런싱 방법을 선택할 수 있다.

  • 단점
  1. 클라이언트와 서비스 레지스토리가 연결되어 있어서 종속적임

  2. 서비스 클라이언트에서 사용하는 각 프로그래밍 언어 및 프레임워크에 대해 클라이언트 측 서비스 검색 로직을 구현해야 함.

-예) Neflix OSS의 Eureka

Eureka는 동적인 서비스들을 한대 모아 관리하고 각 서비스들의 호스트 이름과 포트를 하드 코딩하지 않고도 서비스 서로를 찾아 통신할 수 있게 해준다
2. 서버 사이드 디스커버리 패턴
: 호출되는 서비스 앞에 로드밸런서를 넣는 방식, 클라이언트는 로드밸런서를 호출하면 로드밸런서가 Service Register 로부터 등록된 서비스의 위치를 전달하는 방식.

장점

  1. 의존성이 낮다 (discovery의 세부사항이 클라이언트로부터 분리)

  2. 분리되어있어 클라이언트는 단순히 로드밸런서에 요청만 함 -> 각 프로그래밍 언어 및 프레임 워크에 대한 검색 로직을 구현할 필요 없음

  3. 일부 배포 환경에서는 이 기능을 무료로 제공

  • 단점
  1. 로드밸런서가 배포환경에서 제공되어야 함

  2. 제공되지 않는다면 설정 및 관리해야하는 또다른 고 가용성 시스템 구성요소가 된다.

예) 쿠버네티스

로그분석 중앙화와 분산 추적

블로그 보면 잘 나와있음
보충해서 설명을 하자면

로그분석 중앙화


로그분석 중앙화에서 마이크로 서비스 A' 마이크로서비스 B' 이런식으로 다 있다고 보는거임
그래서 A'에서 로그를 저장하고 관리해주는 것

분산 추적


원래는 문제가 일어나서 추적을 할 때에 a부터 f까지 다 모든 서비스를 돌아야했다
근데 이건 굉장히 비효율 적이다.
그래서 분산해서 추적하는 분산 추적 방식
로그가 찍힌 애들만 추적해주는것이다.

사용을 해야지만 로그가 찍히고, 사용을 해야지만 문제가 일어나니까 필요한 부분만 찾아서 추적할 수 있다는 것

서킷 브레이커, 제어루프, 모니터링 및 경고 중앙화

서킷 브레이커

서킷브레이커(Resilence4j): 넷플릭스의 히스트릭스에 영감을 받아 개발된 경량화 장애 감내 라이브러리(회로차단기)
   1. 기본개념 : 3가지 일반상태와 3가지의 특수상태를 가진다.
      1) 일반상태 : CLOSE / OPEN / HALF_OPEN
      2) 특수상태(강제상태변이): DISABLED / FORCED_OPEN / METRICS_ONLY
      3) metric 기준에 따라 일반 상태가 바뀌어 API 접근을 통제한다.
   2. metrix 수집 방식 : N개의 원형배열로 구현되며 카운트/시간 기반 측정값을 유지 및 새로운 값으로 갱신된다.
      ※ metrix : 평가지표, 서킷브레이커에서는 요청의 성공, 실패여부를 수집한다.
   3. 사용방법
      1) 직접 객체를 사용하는 방법 (데코레이팅 기능 순서 지정이 쉬움 / 기능 테스트에 스프링 컨텍스트가 필요없음)
      2) @Anotation을 이용 AOP 방식으로 사용하는 방법 
   4. 모니터링 
      1) Micrometer(http://micrometer.io) 툴 활용 표준형식으로 metric 제공(ex:프로메테우스)
      2) 적절한 모니터링 제품으로 metric 수집 및 대시보드 활용(ex:Grafana)
   5. 프로젝트 활용방안
      1) 문제가 있는 마이크로서비스로의 트래픽을 차단하여 전체서비스가 느려지거나 중단되는것을 미리 방지

1.1)의 HALF_OPEN 은 닫아놓고, 한쪽에서는 계속 문제가 일어날지도 모른다고 생각해서 모니터링 하고 있는 것을 말한다.
사용방법은 객체를 사용하는 방법과 어노테이션을 사용하는 방법이 있는데,
객체가 처음엔 어렵지만 관리하기가 쉽고,
어노테이션은 처음엔 쉽지만 관리하기 어렵다고 한다.(일일히 @달아줘야하는 문제+개발자가 헷갈려서 실수 잦음)

제어루프

어루프(쿠버네티스 컨트롤러 매니저): 클러스터의 원하는 상태를 실제 상태와 반복적으로 비교하여 문제를 해결하기 위한 방법.
   1. 기본개념 : 클러스터의 상태를 관찰 한 다음, 필요한 경우에 생성 또는 변경을 요청하는 컨트롤 루프,
   각 컨트롤러는 현재 클러스터 상태를 의도한 상태에 가깝도록 변경한다(온도 조절기)
   ※ 클러스터 : 컨테이너화된 애플리케이션을 실행하는 노드라고 하는 워커 머신의 집합, 
   모든 클러스터는 최소 1개의 워커 노드를 가진다.
   2. 제어방식 
      1)API 서버를 통한 제어 : 내장컨트롤러를 이용 한다. 
         ① 컨트롤러가 새로운 요청 확인
         ② API서버에 클러스터 내부에서 작업할 파드를 실행하도록 지시
            ※ POD : 쿠버네티스에서 가장 기본적인 배포단위, 컨테이너를 포함.
         ③ 신규정보를 업데이트하여 작업을 완료
      2)직접 제어 : 클러스터 외부의 것을 변경해야 할 필요가 있을 떄 사용방법
         ① 컨트롤러가 새로운 요청 확인
         ② 외부시스템과 직접 통신하여 업데이트
         ③ 반영된 내용을 클러스터의 API 서버에 재보고
   3. 디자인 : 간단할 컨트롤러를 여러개 사용하여 MSA구조에 최적화를 시킬 수 있다.
   4. 프로젝트 활용방안
      1) 컨테이너 배포
      2) 서비스를 관리하고 유지보수

모니터링 및 경고 중앙화

모니터링 및 경고 중앙화(프로메테우스, Grafana) : 메트릭 기반의 오픈소스 모니터링 시스템
   1. 프로메테우스 
      1) 이벤트 모니터링 및 경고에 사용되는 무료 소프트웨어 응용 프로그램
      2) 유연한 쿼리(PromQL) 및 실시간 경고가 가능
      3) 구조가 간단해서 운영이 쉽고, 강력한 쿼리 기능을 가지고 있으며, 그라파나(Grafana)를 통한 시각화를 지원
      4) ELK와 같은 로깅이 아니라, 대상 시스템으로부터 각종 모니터링 지표를 수집하여 저장하고 검색할 수 있는 시스템
      ※ ELK : 로그수집기술 -> 로그 수집/저장/검색/관리/시각화를 제공하는 오픈소스 
   2. 그라파나 : 프로메테우스에서 제공받은 Metric을 활용 시각화한다.
   3. 기본동작
      1) metric 수집 : 수집하려는 대상시스템 선정 및 수집
      2) pulling 방식 : Exporter로부터 metric 읽어봐서 수집, 
                  모니터링 대상이 가견적으로 변할경우 IP주소를 알수 없음.
      3) Service Discovery : 모니터링해야할 타겟 서비스의 목록을 가지고 올 수 있음.
      4) Exporter : 시스템에서 메트릭을 프로메테우스로 전송하기 위해 사용, 단순히 GET방식으로 테스트형태로 리턴
      5) Retrieval : 주기적으로 메트릭을 수집하는 모듈
      6) 저장 : 프로메테우스 내의 메모리 및 로컬 디스크에 저장
      7) 서빙 : PromQL 쿼리언어를 이용 조회가능, 그라파나와 통합하여 대쉬보드 구성 가능
   4. 장/단점
      (장점)
      1) pull 방식의 구조를 채택함으로써, 모든 메트릭의 정보를 중앙 서버로 보내지 않아도 된다.
      2) Kubernetes 환경에서 설치가 쉽고, grafana와의 연동을 통한 운영이 쉽다.
      3) Linux, Window등의 OS metric 뿐 아니라 각종 Third-party의 다양한 exporter를 제공한다.
      4) 데이터 저장소가 시계열 데이터 저장소로 구성되어있어, 많은 양의 정보를 빠르게 검색 가능하다.
      5) 구조가 복잡하지 않고 간단하기 때문에 특정 솔루션에 대한 export가 어렵지 않다.
      6) 모든 데이터를 수집하지 않고 일정 주기(기본 값: 15초)로 메트릭을 수집하기 때문에 애플리케이션에 무리가 없다.
 

      (단점)
      1) 클러스터링이 불가능하다. 프로메테우스를 여러대 구성하려면  
      Hierarchy 구조를 구성하여 사용해야한다.
      2) 모든 메트릭을 수집하지 않기 때문에 사실상 "추리"를 보는데에는 좋지만 
      APM(Application Performance Monitoring)과 같이 모든 로그를 추적하기에는 적합하지 않다. 
      Pullling 하는 순간의 스냅샷 정보만 알 수 있다.
      3) 싱글 호스트 아키텍처이기 때문에 저장용량이 부족하면 디스크 용량을 늘리는 방법밖에 없다.
      4) Prometheus server가 다운되거나, 설정 변경 등을 위해 재시작할 경우 메트릭이 일정시간동안 유실된다.

출처

OAuth2.0 동작 방식의 이해
OAuth2.0 인증과정 및 프로세스
[마이크로서비스 디자인패턴] 리액티브 마이크로서비스 (+동기/비동기방식)
[마이크로서비스 디자인패턴] 서비스 검색
[마이크로서비스 디자인 패턴] 로그 분석 중앙화, 분산 추적
[출처] [마이크로서비스 디자인 패턴] 로그 분석 중앙화, 분산 추적|작성자 하루

스터디를 통한 지식공유

profile
기록이 쌓이면 지식이 된다.

0개의 댓글