개요

서비스 메쉬란, 각 서비스 간에 데이터를 공유하는 방식을 제어하는 방법이다. 앱 내부 하나의 인프라 레이어로 직접 구축된다.(built-in)

제어가 왜 필요할까?

  • 분산 환경이므로 서비스 경로 제공(routing, registry, discovery)
  • 한 서비스에 몰리는 것 방지(lb)
  • 서비스 간 최적화된 커뮤니케이션 방식 고려(gRPC 등 파드 간 통신 프로토콜 제어) 

 

배경

MSA에서는 하나의 비즈니스 로직을 수행하기 위해서 여러 서비스의 작동이 필요하다.

따라서 다른 서비스와 비교할 때 특정 서비스에 부하가 많이 걸리는 경우가 발생할 수 있는데, 이러한 부하를 적절하게 분배하고, 작동 방식을 최적화하는 것이 서비스 메쉬이다.

물론, 서비스 메시가 없더라도 서비스에서 직접 다른 서비스를 호출할 수도 있을 것이나, 아키텍처가 복잡해질 수록 부하 예측과 상태 체크가 어려워질 것이다.

대량의 개별 서비스를 정상 애플리케이션으로 구성하기 위해서 서비스메시는 필수적이다.

 

방법

서비스 메시는 네트워크 프록시의 배열로서 구축되어 런타임 환경에 새로운 기능을 도입해야하는 방식보다는, 인프라 계층에 추상화되는 것이 특징이다. (Redhat 기준)

서비스 메시에서는 요청이 자체 인프라 계층의 프록시를 통하므로, 개별 프록시는 서비스 내부가 아니라, 서비스와 함께 실행되는 것이 특징이다. 이를 Sidecar 프록시라 한다. Sidecar 프록시들이 모여서 메쉬 네트워크를 형성한다.

(사이드카가 없다면, 각 서비스 간 커뮤니케이션 통제 로직을 직접 코딩해야 하므로 시간이 걸리고, 장애 진단이 더 어려워진다)

 

장점

  • 서비스 연결 자동화
  • 비즈니스 로직의 문제 진단 용이
  • 애플리케이션 복구 능력 향상(다운 시 재라우팅 가능)
  • 시스템 모니터링 가능

 

사이드카 패턴

의문점

SideCar에 대한 설명을 보니 (네트워크 레이어, 같이 실행이 아닌 함께 실행, 비즈니스 로직과 분리 등) 이건 Eureka만으로는 충족할 수 없는 조건들 아닌가? 하는 의문이 들었다.

왜냐하면 Eureka는 (1) 코드 내 Annotation으로 추가되고 (2) eureka 관련 로직은 빌드 과정에서 코드 빌드 결과물과 동일한 jar 파일에 포함되며 (3) 그 결과 특정 서비스가 죽으면 sidecar도 동작하지 않기때문이다.

검색해본 결과, netflix-sidecar라는 모듈이 존재했다. polyglot 환경에서도, 즉 파이썬, javascript 등의 서로 다른 언어로 구성된 이종(Hetero) 서비스 간에도 헬스 체크를 가능하게 한다.

또는 js같은경우 eureka client로써 jar 기반 eureka server에서 discovery할 수 있도록 기능하는 모듈을 import&packaging 할 수도 있다. (검색 결과 Spring Cloud는 엄밀한 의미의 사이드카 프록시를 제공하는 것은 아니었음. Service mesh 관련 기술도 Mesh(Network)와 tightly coupled인지 independent인지에 따라서 분류가 됨)

 

솔루션 분류

service mesh 솔루션은 서비스 코드의 연관도에 따라서 분류된다.

Mesh-Native, Mesh-Aware, Mesh-Agnostic 세 가지로 분류되는데, 각각 서비스 코드 개발 과정에서 Mesh에 대하여 얼만큼 고려해야 하는지를 기준으로 분류된다고 볼 수 있다.

  • Mesh-Native Code는 서비스 코드에 "Mesh 자체"를 구현하는 코드를 추가하는 형태를 말한다. 
  • Mesh-Aware Code는 서비스 코드 작성 시 Mesh를 이해하고서 부분적으로 수정을 가해야하는 수준을 말한다. ( ex. Spring Cloud Eureka, )
  • Mesh-Agnostic Code는 비즈니스 로직에는 Mesh에 관한 코드가 일절 불필요한 형태를 말한다. 서비스와 완전히 별개로 동작하므로 Sidecar Proxy가 실현된 사례라고 볼 수 있다.

 

Service Discovery

서비스 클라이언트가 동적으로 변경되는 서비스 위치를 Follow-up하는 기능

발생 배경은 클라우드, 컨테이너 기반 환경으로 넘어오면서 오토 스케일링, 컨테이너 자동 배포 등의 동적인 기능이 많이 구현되어 활용됨. 이로 인해서 런타임 중에 변경되는 서비스 정보도 catch-up할 수 있는 구성 요소가 필요해졌음.

- Service Registry

각 서비스들이 자신의 위치 정보를 등록해놓는 대상 서비스이다. 레지스트리에 등록된 후에는 다른 서비스들은 모든 서비스에 접근할 필요 없이, 레지스트리에 등록된 접근정보를 이용하여 타 서비스로 접근하게 된다.

- Client-side  vs Server-side discovery

클라이언트가 직접 서비스 등록 정보를 알아내면 Client-side이고 로드밸런서 또는 프록시 서버가 대신 정보를 알아내면 Server-side이다. 아마 Client-side가 더 빠르고, Server-side는 관리(부하 조절 등)가 용이할 것으로 보인다.