728x90
반응형

Service Discovery

ServiceDiscovery는 말 그대로 외부에서 다른 어떤 서비스들이 마이크로서비스를 검색하기 위해서 사용되는 개념이다.

우리가 가지고 있는 일종의 전화번호부(Service Registry)에서 다른 사람들의 전화번호(Microservice)를 찾는 것이라고 생각할 수 있다.

전화번호부 안에 들어간 정보는 key, value 형태로 저장이 되어 있다.

 

즉, 어떠한 서버가 어느 위치에 있는지, 어떤 서비스가 어떤 위치에 있는지 이런 것들을 등록하고 있는 정보가 Service Discovery라고 생각할 수 있다.

[ Service Registry 개념 ]

분산 환경 위에서 서로간의 서비스를 원격 호출하기 위해서는 각 서비스의 IP 주소와 PORT 번호를 알아야 한다.

MSA 어플리케이션의 경우 네트워크 주소가 동적으로 할당된다.
따라서 클라이언트가 서비스를 호출하기 위해서 찾는 매커니즘이 필요하다.

  • Service Registry는 Service Discovery를 하기 위하여 필요하다(Service Registry에 모두 등록되어 있기 때문에)
  • Service Registry는 사용가능한 서비스 인스턴스의 목록을 관리하고 서비스 등록, 해제, 조회 등을 할 수 있는 API 를 제공한다

MSA에서 Service Discovery

클라우드 환경이 되면서 IP 주소가 동적으로 생성되고 삭제되는 일이 잦아져서 서비스 클라이언트가 서비스를 호출할 때 서비스의 위치를 알아낼 수 있는 기능이 필요해졌다.

 

Service Discovery를 구현하는 디자인 패턴은 서비스 인스턴스의 네트워크 위치를 찾고 로드밸런싱하는 역할을 클라이언트가 담당하는 Client Side Discovery가 있고, 서버 쪽에서 디스커버리 로직을 구현한 방식인 Server Side Discovery 디자인 패턴이 있다.

Client Side Discovery

Service Client가 Service Registry에서 서비스의 위치를 찾아서 호출하는 방식이다.

장점

  • Server Side Discovery와 비교했을때 간단하다
  • 클라이언트가 사용 가능한 서비스 인스턴스에 대해서 알고 있기 때문에 각 서비스별 로드 밸런싱 방법을 선택할 수 있다

단점

  • 클라이언트와 서비스 레지스트리가 연결되어 있어서 종속적이다
  • 서비스 클라이언트에서 사용하는 각 프로그래밍 언어 및 프레임 워크에 대해서 클라이언트 측 서비스 검색 로직을 구현해야 한다

Server Side Discovery

호출이 되는 서비스 앞에 proxy 서버(로드 밸런서)를 넣는 방식이다.

서비스 클라이언트가 로드 밸런서를 호출하면 로드밸런서가 Service Registry로부터 등록된 서비스의 위치를 리턴하고, 이를 기반으로 라우팅하는 방식.

클라우드의 로드밸런서, AWS의 ELB나 구글 클라우드의 로드 밸런서들이 Server Side Discovery 방식으로 구현되어 있다.

쿠버네티스 환경에서 Server Side Discovery를 구현하기 편리하다.

Kubernetes 배포 환경에서 Server Side Service Discovery 구현방법

만약 public Cloud를 사용한다면 AWS에서는 AWS ELB를 제공해주고, GCP도 구글 로드밸런서를 제공해준다. 해당 서비스를 Service Discovery로 사용할 수 있다.

(private Cloud의 경우라면 MetalLB를 사용하면 된다.)

 

[kube-proxy와 ELB를 사용하는 예시]

1. 클라이언트는 해당 로드밸런서(kube-proxy)를 통해서 DNS 이름을 사용하여 ELB 에 요청을 보낸다.

2. ELB 에서는 Kube-DNS 서비스에게 DNS 이름으로 문의(query)를 요청

3. Kube-DNS 는 쿠버네티스의 저장소인 etcd 를 조회하여 호출하려는 서비스의 ip와 port 정보를 넘겨준다.

 

즉 Service registry 역할을 Kube-DNS(API 제공) 와 etcd(목록 관리) 가 나누어서 한다. 넘겨받은 정보를 ELB 에서 호출을 할때 Kube-proxy가 loadbalancer 역할을 하여 준다.

장점

  • discovery의 세부 사항이 클라이언트로부터 분리되어있어서 의존성이 낮다.
  • 분리 되어 있어 클라이언트는 단순히 로드 밸런서에 요청만 하기 때문에 각 프로그래밍 언어 및 프레임 워크에 대한 검색 로직을 구현할 필요가 없다
  • 일부 배포환경(AWS, GCP 등)에서는 이 기능을 무료로 제공한다

단점

  • 로드밸런서가 배포환경에서 제공되어야 한다
  • 로드밸런서가 제공되어있지 않다면 설정 및 관리해야하는 또 다른 고가용성 시스템 구성 요소가 된다(private cloud라면 metalLB)

Server-Side Discovery의 예로는 AWS Elastic Load Balancer(ELB), Kubernetes가 있다

Service Registry

서비스를 등록하는 Service Registry는 Service Discovery에서 사용할 서비스들을 모두 등록해 놓은 것이다.

Service Registry를 구현하는 가장 쉬운 방법은 DNS 레코드에 하나의 호스트명에 여러 개의 IP를 등록하는 방식이지만, DNS는 레코드 삭제 시 업데이트 되는 시간 등이 소요되기 때문에 적절하지 않다.

그래서 Service Registry에서는 제공되는 솔루션을 사용하는 방법이 있는데 쿠버네티스에서는 ZooKeeper나 etcd와 같은 서비스를 이용 가능하다.

 

쿠버네티스 배포 환경에서는 주로 Service Registry를 Kube DNS와 etcd를 사용하여서 구현한다.

또한, Service Discovery에 전문화된 솔루션인 Netflix의 Eureka나 Hashcorp의 Consul을 사용할 수도 있다.

[Spring Cloud Gateway + Spring Eureka Server를 선택한 이유]

프로젝트에서 프론트에서는 최대한 작업이 필요없게 구현하기 위해서 Client Side 작업이 필요없는 Server-Side Discovery를 선택하였다.

그리고 private Cloud에서 Server Side Discoery 디자인 패턴을 구현하려면 MetalLB와 같은 또다른 구성 요소를 포함해야 하는데 아직 MetalLB에 대한 이해도가 부족하고, Spring Cloud에서 제공해주는 서버 사이드 디스커버리 패턴으로 구현가능한 Spring Cloud Gateway를 Spring Eureka Server와 함께 사용하였다.

[ Service Cloud Gateway의 사용법 ]

사용법

  1. 일단 사용하려면 각각의 마이크로 서비스가 전부 다 자신의 위치 정보를 Netflix Eureka Server에다가 등록이라는 작업을 먼저 한다
  2. 마이크로서비스를 사용하고 싶은 클라이언트는 제일 먼저 자신이 필요한 어떤 요청 정보를 로드밸런서 아니면 API Gateway에다가 자신이 필요한 요청 정보를 전달하게 되면 요청 정보가 Service Discovery에 전달이 돼서 내가 필요한 정보가 어디에 있는지 묻게 된다.
  3. 그럼 서비스 디스커버리가 반환을 시켜주게 되면 사용자 요청 정보가 호출되고 결과값을 가져가게 된다.

서비스 디스커버리가 해주는 역할은 각각의 마이크로 서비스가 어디에 누가 저장되어 있으며 요청 정보가 들어왔을 때, 그 요청 정보에 따라서 필요한 서비스의 위치를 알려주는 것이다.

[ Eureka Server에 API-Gateway (spring cloud gateway) 가 등록된 화면 ]

 

728x90
반응형

+ Recent posts