최근 IT환경은 Cloud로 대변되는 시스템 구축 환경의 변화에 따라 이를 잘 활용할 수 있는 다양한 Architecture들이 나타나고 있습니다.
Service Mesh Architecture는 MicroService Architecture와 더불어 최근 활발하게 언급되고 있는데 Service Mesh Architecture가 뭔지 한번 알아봅시다!
1. MicroService Architecture를 적용한 시스템의 내부 통신이 Mesh 네트워크의 형태를 띄는 것에 빗대어 Service Mesh로 명명되었습니다.
2. Service Mesh 는 서비스 간 통신을 추상화하여 안전하고, 빠르고, 신뢰할 수 있게 만드는 전용 InfraStructure Layer입니다.
추상화를 통해 복잡한 내부 네트워크를 제어하고, 추적하고, 내부 네트워크 관련 로직을 추가함으로써 안정성, 신뢰성, 탄력성, 표준화, 가시성, 보안성 등을 확보합니다.
3. Service Mesh 는 URL 경로, 호스트 헤더, API 버전 또는 기타 응용 프로그램 수준 규칙을 기반으로하는 계층 7 네트워크 Layer입니다.
Service Mesh의 구현체인 경량화 Proxy를 통해 다양한 Routing Rules, circuit breaker 등 공통기능을 설정할 수 있습니다. 이는 서비스 간 통신에 연관된 기능 뿐만 아니라, 서비스의 배포 전략에도 도움을 줍니다.
MicroService Architecture는 Monolitic Architecture의 단점 극복과 Cloud 환경에서 시스템을 운영할 때의 이점을 극대화하기 위해 많이 사용되고 있습니다.
이를 통해 많은 문제들이 해결되었지만, 또다른 문제점도 발생했습니다.
그것은 시스템의 런타임 복잡성 입니다.
복잡성이 증가하는 이유
1. 서비스 & Instance 의 증가
시스템의 규모에 따라 다르지만 활발히 운영되는 MSA 시스템에는 수십개의 MicroService가 분리되어 있고, 운영 환경에 수백 ~ 수천개의 서비스 Instance가 동작하고 있습니다.
PaaS, CaaS 등의 환경에서 각 서비스의 Instance는 스케일링되며 동적으로 뜨고 집니다. 이 수백 ~ 수천개의 Instance을 모니터링 하고 로깅을 처리하고 Instance를 관리해야 합니다.
2. 서비스 간 통신
Monolitic Architecture에서 프로세스나 쓰레드 간 메모리 공유 등 서비스 Instance 내부에서 처리하던 기능들이 서비스 간 통신을 통해 처리됩니다.
보통 사람들은 네트워크를 레이턴시가 없고 무한대 대역폭에 항상 안정적인 idle 상태로 생각하지만, 현실은 그렇지 않습니다. 안정적이지 않은 내부 네트워크는 시스템의 신뢰성, 안정성을 보장할 수 없습니다.
동적으로 수많은 Instance가 뜨고/지고, 서비스 간 통신이 유발하는 이런 복잡한 상황에서 내부 네트워크를 안정적으로 다루기 위해 새로운 기능(또는 요구사항, 관리 point)들이 필요합니다.
아래 내용은 MicroService Architecture가 적용된 시스템의 새로운 요구사항으로 이는Service Mesh의 기능이기도 합니다.
Service Mesh는 MicroService Architecture를 보완하고 있기 때문입니다.
Service Mesh Architecture의 구현은 보통 서비스의 앞단에 경량화 프록시를 사이드카 패턴으로 배치하여 서비스 간 통신을 제어하는 방법으로 구현합니다.
서비스 간 통신은 사이드카로 배치된 경량화 Proxy를 통해서 동작합니다. 이 경량화 Proxy에 Routing rules, retry, timeout 등을 설정하고 로직을 작성하여 공통 기능을 기본 어플리케이션에서 분리시킬 수 있습니다.
사이드카 패턴은 클라우드 디자인 패턴의 일종입니다.
기본 Application 외 필요한 추가 기능을 별도의 Application으로 구현하고 이를 동일한 프로세스 또는 컨테이너 내부에 배치하는 것입니다.
동일한 프로세스 또는 컨테이너에 배치된 사이드카 Application은 저장 공간, 네트워크 등의 리소스를 공유하며 모니터링, 로깅, 프록시 등의 동작을 합니다.
사이드카 Application은 기본 Application과 별도의 Application입니다.
기본 Application의 로직을 수정하지 않고도 추가 기능을 수행할 수 있습니다.
기본 Application을 polyglot 프로그래밍을 적용해 요구 사항에 최적화된 환경에서 개발을 진행할 수 있습니다.
사이드카 Application은 기본 Application과 리소스를 공유할 수 있습니다. 이를 통해 모니터링에 필요한 Metrics 수집, 프록시 동작 등을 수행할 수 있습니다.
Istio는 Envoy를 Data Plane으로 사용하고 이를 control해주는 오픈 소스 솔루션이다.
Envoy를 이용해서 Service Mash를 구현하기 위해서는 Envoy로 구성된 Data Plane을 control할 솔루션이 필요하다.
모든 컴포넌트가 istiod 라는 하나의 프로세스로 합쳐지고 Mixer 가 없어지고 Pilot 이 Mixer 의 기능까지도 함께 수행하는 것으로 되어 있다.
proxy 방식의 container를 추가하여 네트워크를 구성합니다.
micro servcie간 통신이 proxy를 거치기에 모든 통신 log를 기록하여 모니터링에 필요한 Metrics 수집, 프록시 동작을 수행할 수 있습니다.
Istio는 Data Plane과 Control Plane으로 구성되어 있다.
실제로 트래픽을 받아 처리해주는 파트다.
Service의 Sidecar 형태로 구성된 Proxy들을 가리킨다.
Data Plane은 Control Plane에 의해 통제된다.
Istio에서는 envoy를 sidecar proxy로 사용한다.
1) Envoy
경량화된 L7 전용 Proxy다.
HTTP, TCP 등의 프로토콜을 지원한다.
Circuit Breaker, Retry, Timeout 등의 기능을 지원한다.
Data Plane을 컨트롤하는 구성 요소를 가리킨다.
Pilot, Mixer, Citadel, Galley 등으로 구성되어 있다.
1) Pilot
envoy에 대한 설정 관리를 하는 역할을 한다.
Traffic Management 기능을 제공한다.
1) 트래픽 분할
서로 다른 버전의 서비스를 배포해놓고, 버전별로 트래픽의 양을 조절할 수 있는 기능이다.
ex) 새 버전의 서비스를 배포할때, 기존 버전으로 95%의 트래픽을 보내고, 새 버전으로 5%의 트래픽만 보내서 테스트하는 것이 가능하다.
2) 컨텐츠 기반의 트래픽 분할
단순하게 커넥션 기반으로 트래픽을 분할하는 것이 아니라, 조금 더 발전된 기능으로 네트워크 패킷의 내용을 기반으로 라우팅이 가능하다.
ex) 아래 우측 그림과 같이 HTTP 헤더의 User-agent 필드에 따라서, 클라이언트가 안드로이드일 경우에는 안드로이드 서비스로 라우팅을 하고, IPhone일 경우에는 IOS 서비스로 라우팅을 할 수 있다.
Pilot은 트래픽 통제를 통해서 서비스 호출에 대한 안정성을 제공한다.
1) 헬스체크 및 서비스 디스커버리
파일럿은 대상 서비스가 여러개의 인스턴스로 구성이 되어 있으면 이를 로드 밸런싱하고, 이 서비스들에 대해서 주기적으로 상태 체크를 한다.
만약에 장애가 난 서비스가 있으면 자동으로 서비스에서 제거한다.
2) Retry, Timeout, Circuit breaker
서비스간의 호출 안정성을 위해서, 재시도 횟수를 통제할 수 있다.
호출을 했을때 일정 시간 (Timeout)이상 응답이 오지 않으면 에러 처리를 할 수 있고, Mircro Service Architecture 패턴중 하나인 Circuit breaker 패턴을 지원한다.
서비스에 대한 보안 기능을 추가해준다.
1) 통신 보안
기본적으로 envoy를 통해서 통신하는 모든 트래픽을 자동으로 TLS를 이용해서 암호화한다. 즉 서비스간의 통신이 디폴트로 암호화 된다.
암호화를 위해서 인증서를 사용하는데, 이 인증서는 Citadel에 저장되어 있는 인증서를 다운 받아서, 이 인증서를 이용하여 암호화된 TLS 통신을 한다.
2) 서비스 인증과 인가
Istio는 서비스에 대한 인증 (Authentication)을 제공하는데, 크게 서비스와 서비스간 호출에서, 서비스를 인증하는 기능과, 서비스를 호출하는 클라이언트를 직접 인증 할 수 있다.
3) 서비스간 인증
서비스간 인증은 인증서를 이용하여 양방향 TLS (Mutual TLS) 인증을 이용하여, 서비스가 서로를 식별하고 인증한다.
4) 서비스와 사용자간 인증
서비스간 인증뿐 아니라, 엔드 유저 즉 사용자 클라이언트를 인증할 수 있는 기능인데, JWT 토큰을 이용해서 서비스에 접근할 수 있는 클라이언트를 인증할 수 있다.
5) 인가를 통한 권한 통제(Authorization)
인증뿐만 아니라, 서비스에 대한 접근 권한을 통제 (Authorization)이 가능하다.
기본적으로 역할 기반의 권한 인증 (RBAC : Role based authorization control)을 지원한다.
앞에서 인증된 사용자(End User)나 서비스는 각각 사용자 계정이나 쿠버네티스의 서비스 어카운트로 계정이 정의 되고, 이 계정에 역할(Role)을 부여해서 역할을 기반으로 서비스 접근 권한을 정의할 수 있다.
마이크로 서비스에서 문제점중의 하나는 서비스가 많아 지면서 어떤 서비스가 어떤 서비스를 부르는지 의존성을 알기가 어렵고, 각 서비스를 개별적으로 모니터링 하기가 어렵다는 문제가 있다.
Istio는 네트워크 트래픽을 모니터링함으로써, 서비스간에 호출 관계가 어떻게 되고, 서비스의 응답 시간, 처리량등의 다양한 지표를 수집하여 모니터링할 수 있다.
-> Mixer에서 서비스 관련 지표를 수집하는 구조
서비스 A가 서비스 B를 호출할때 호출 트래픽은 각각의 envoy 프록시를 통하게 되고, 호출을 할때, 응답 시간과 서비스의 처리량이 Mixer로 전달된다.
전달된 각종 지표는 Mixer에 연결된 Logging Backend에 저장된다.
Mixer는 위의 그림과 같이 플러그인이 가능한 아답터 구조로, 운영하는 인프라에 맞춰서 로깅 및 모니터링 시스템을 손쉽게 변환이 가능하다.