블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 


Istio #2 - Envoy Proxy


조대협 (http://bcho.tistory.com)

그럼 앞에서 설명한 서비스 매쉬의 구조를 구현한 Istio를 살펴보기전에, Istio에 사용되는 envoy 프록시에 대해서 먼저 알아보자.
(이 글은 예전에 포스팅한 내용이지만, Istio 글의 흐름상 다시 포스팅 한다.)

Envoy Proxy

먼저 istio에 사용되는 envory proxy를 살펴보자. Envoy 프록시는 Lyft사에서 개발되었으면 오픈소스로 공개되었다.

기존 프록시 L4기능 뿐 아니라 L7 기능도 지원하면서 HTTP 뿐아니라 HTTP 2.0,TCP,gRPC까지 다양한 프로토콜을 지원한다.


성능 지표를 보면 아래 Twillo에서 2017년에 테스트 한 자료를 참고할만 한데, (원본 https://www.twilio.com/blog/2017/10/http2-issues.html) HAProxy 보다 약간 느린것을 확인할 수 있다. 아무래도 L4가 아닌 L7단의 로드밸런서이다 보니 다소 성능 감소는 부담해야 한다.




(참고. 위의 문서를 보면 Envoy HTTP2 의 성능이 낮게 나오는데, 이는 Envory 자체 문제라가 보다는 HTTP/2가 Connection을 reuse하는 특성에서 온다고 볼 수 있는데, 성능에 대한 이슈가 있는 만큼 HTTP/2를 사용할 경우에는 별도의 검증 등이 필요하리라 본다.)


주요 기능적인 특성을 보면 다음과 같다.


  • HTTP, TCP, gRPC 프로토콜을 지원

  • TLS client certification 지원

  • HTTP L7 라우팅 지원을 통한 URL 기반 라우팅, 버퍼링, 서버간 부하 분산량 조절등

  • HTTP2 지원

  • Auto retry, circuit breaker, 부하량 제한등 다양한 로드밸런싱 기능 제공

  • 다양한 통계 추적 기능 제공 및 Zipkin 통합을 통한 MSA 서비스간의 분산 트렌젝션 성능 측정 제공함으로써 서비스에 대한 다양한 가시성 (visibility)을 제공

  • Dynamic configuration 지원을 통해서, 중앙 레파지토리에 설정 정보를 동적으로 읽어와서 서버 재시작없이 라우팅 설정 변경이 가능함

  • MongoDB 및 AWS Dynamo 에 대한 L7 라우팅 기능 제공


등 매우 다양한 기능을 제공한다.

Envoy 배포 아키텍처

Envoy 프록시는 배포 위치에 따라서 다양한 기능을 수행할 수 있는데, 크게 다음과 같이 4가지 구조에 배포가 가능하다.


<그림. Envoy 배포 방식>

Front envoy proxy

특정 서비스가 아니라, 전체 시스템 앞의 위치하는 프록시로, 클라이언트에서 들어오는 호출을 받아서 각각의 서비스로 라우팅을 한다. URL 기반으로 라우팅을 하는 기능 이외에도, TLS(SSL) 처리를 하는 역할들을 할 수 있다. 통상적으로 nginx나 apache httpd가 리버스프록시로 이 용도로 많이 사용되었다.

Service to service ingress listener

특정 서비스 앞에 위치하는 배포 방식으로 서비스로 들어오는 트래픽에 대한 처리를 하는데, 트래픽에 대한 버퍼링이나 Circuit breaker 와 같은 역할을 수행한다.

Service to service egress listener

특정 서비스 뒤에서 서비스로부터 나가는 트래픽을 통제 하는데, 서비스로 부터 호출 대상이 되는 서비스에 대한 로드 밸런싱, 호출 횟수 통제 (Rate limiting)와 같은 기능을 수행한다.

External service egress listener

내부서비스에서 외부 서비스로 나가는 트래픽을 관리하는 역할인데, 외부 서비스에 대한 일종의 대행자(Delegator)와 같은 역할을 한다.


시스템 앞 부분이나 또는 시스템을 구성하는 서비스의 앞뒤에 배치할 수 있는 구조지만, 서비스 앞뒤로 붙는다고 실제로 배포를 할때 하나의 서비스 앞뒤로 두개의 envoy proxy를 배치하지는 않는다.

다음과 같이 하나의 서비스에 하나의 Envoy를 배치 한후, ingress/egress 두 가지 용도로 겸용해서 사용한다.



Envoy 설정 구조

다음은 Envoy 설정 파일을 살펴 보자

Envoy의 설정은 크게 아래 그림과 같이 크게 Listener, Filter, Cluster 세가지 파트로 구성된다.



  • Listener
    Listener는 클라이언트로 부터 프로토콜을 받는 부분으로, TCP Listener, HTTP Listener 등이 있다.

  • Filter
    Filter는 Listener 로 부터 많은 메시지를 중간 처리하는 부분으로, 압축이나 들어오는 Traffic 에 대한 제한 작업등을 한후, Router를 통해서 적절한 클러스터로 메시지를 라우팅 하는 역할을 한다.

  • Cluster
    Cluster는 실제로 라우팅이 될 대상 서버(서비스)를 지정한다.


이렇게 Listener를 통해서 메시지를 받고, Filter를 이용하여 받은 메시지를 처리한 후에, 라우팅 규칙에 따라서 적절한 Cluster로 라우팅을 해서 적절한 서비스로 메시지를 보내는 형식이다.


Envoy 설치

Envoyproxy를 빌드하고 설치하는 방법은 여러가지가 있다. 소스코드로 부터 빌드를 하는 방법이나 이미 빌드된 바이너리를 사용해서 설치하는 방법 그리고 이미 빌딩된 도커 이미지를 사용하는 방법이 있다.

소스코드로 빌드하는 방법의 경우에는 bazel (make와 같은 빌드 도구) 빌드를 이용해서 빌드해야 하고, 빌드된 바이너리는 특정 플랫폼에 대해서만 미리 빌드가 되어 있기 때문에, 모든 플랫폼에 사용하기가 어렵다.

마지막으로는 도커 이미지 방식이 있는데, 이 방식이 배포면에서 여러모로 편리하기 때문에 도커 이미지를 이용한 배포 방식을 설명하도록 하겠다.


다음 명령어 처럼

docker pull을 이용하여 envoyproxy 도커 이미지 최신 버전을 가지고 오고, 다음 docker run 명령을 이용하여, 해당 이미지  (envoyproxy/envoy:latest)를 기동한다. 이때 -p 10000:10000 포트를 도커의 10000번 포트를 VM의 10000포트로 포워딩하도록 설정한다.


$ docker pull envoyproxy/envoy:latest
$ docker run --rm -d -p 10000:10000 envoyproxy/envoy:latest
$ curl -v localhost:10000


배포가 끝났으면, curl을 이용하여 localhost:10000번에 호출 하는 테스트를 하도록 한다.

설정에는 디폴트로, 10000 번 포트로 들어오는 모든 트래픽을 *.google.com으로 라우팅 하도록 설정되어 있다.


원본 설정 파일은 https://github.com/envoyproxy/envoy/blob/master/configs/google_com_proxy.v2.yaml 에 있고,  상세 내용을 보면 아래와 같다.


  • admin:
    이 부분은 envoyproxy의 admin 서버를 기동하는 부분으로, envoy 서버의 각종 설정이나 상태 정보를 127.0.0.1:9901로 들어오는 요청은 admin 기능으로 라우팅하도록 한다.

  • static_resources:
    Listener와 Filter 설정에 해당하는 부분으로, 아래 부면, listeners로 정의가 되어 있고 socket_address 부분에 0.0.0.0에 포트 10000 으로 들어오는 요청을 처리하도록 하였다.

    다음 filter_chain 부분에 filter들을 연속해서 정의하는데, http_connection_manager를 이용하여 모든 트래픽을 service_google이라는 클러스터로 라우팅 하도록 설정하였다.

  • clusters:
    마지막으로 clusters 부분에는 “service_google”이라는 클러스터를 정의했으며, 이 호스트의 URL은 google.com 443 포트로 정의하였다.


admin:

access_log_path: /tmp/admin_access.log

address:

  socket_address: { address: 127.0.0.1, port_value: 9901 }


static_resources:

listeners:

- name: listener_0

  address:

    socket_address: { address: 0.0.0.0, port_value: 10000 }

  filter_chains:

  - filters:

    - name: envoy.http_connection_manager

      config:

        stat_prefix: ingress_http

        route_config:

          name: local_route

          virtual_hosts:

          - name: local_service

            domains: ["*"]

            routes:

            - match: { prefix: "/" }

              route: { host_rewrite: www.google.com, cluster: service_google }

        http_filters:

        - name: envoy.router

clusters:

- name: service_google

  connect_timeout: 0.25s

  type: LOGICAL_DNS

  # Comment out the following line to test on v6 networks

  dns_lookup_family: V4_ONLY

  lb_policy: ROUND_ROBIN

  hosts: [{ socket_address: { address: google.com, port_value: 443 }}]

  tls_context: { sni: www.google.com }


다음글에서는 Istio에 대해서 알아보도록 하겠다.


Istio #1

마이크로 서비스 아키텍처와 서비스 매쉬

조대협 (http://bcho.tistory.com)


마이크로 서비스 아키텍쳐는 여러가지 장점을 가지고 있는 아키텍쳐 스타일이기는 하지만, 많은 단점도 가지고 있다. 마이크로 서비스는 기능을 서비스라는 단위로 잘게 나누다 보니, 전체 시스템이 커질 수 록 서비스가 많아지고, 그로 인해서 서비스간의 연결이 복잡해지고 여러가지 문제를 낳게 된다



<그림. 넷플릭스의 마이크로 서비스 구조 >

출처 : https://www.slideshare.net/BruceWong3/the-case-for-chaos?from_action=save


서비스간의 전체 연결 구조를 파악하기 어려우며 이로 인해서 장애가 났을때, 어느 서비스에서 장애가 났는지 추적이 어려워진다.

또한 특정 서비스의 장애가 다른 서비스에 영향을 주는 문제들을 겪을 수 있다.



예를 들어 클라이언트→ 서비스 A → 서비스 B의 호출 구조가 있다고 하자. 만약 서비스 B가 느려지거나 응답이 없는 상태가 되어 버리면, 서비스 B를 호출 하는 서비스 A 안의 쓰레드는 서비스 B로 부터 응답을 기다리기 위해 대기 상태가 되고, 이 상태에서 클라이언트에서 호출이 계속 되면, 같은 원리로 서비스 A의 다른 쓰레드들도 응답을 받기 위해서 대기 상태가 된다. 이런 상태가 반복되면, 서비스 A에 남은 쓰레드는 없어지고 결과적으로 서비스 A도 응답을 할 수 없는 상태가 되서 장애 상태가 된다. 이런 현상을 장애 전파 현상이라고 한다.  

마이크로 서비스 아키텍쳐 패턴

이런 문제들이 패턴화 되고 이를 풀어내기 위한 방법이 디자인 패턴으로 묶이기 시작하였다.

예를 들어 앞의 문제와 같은 장애 전파의 예는 써킷 브레이커 (Circuit breaker)라는 디자인 패턴으로 해결할 수 있다.



<그림, 써킷 브레이커(Circuit breaker) 패턴 >


서비스 A와 서비스 B에 써킷 브레이커라는 개념을 정의해서, 네트워크 트래픽을 통과 시키도록 하고, 서비스 B가 장애가 나거나 응답이 없을 경우에는 그 네트워크 연결을 끊어서 서비스 A가 바로 에러를 받도록 하는 것이다. 이렇게 하면 서비스 B가 응답이 느리거나 또는 응답을 할 수 없는 상태일 경우에는 써킷 브레이커가 바로 연결을 끊어서, 서비스 A내에서 서비스 B를 호출한 쓰레드가 바로 에러를 받아서 더 이상 서비스 B로 부터 응답을 기다리지 않고, 쓰레드를 풀어주서 서비스 A가 쓰레드 부족으로 장애가 되는 것을 막는다.

이 외에도 분산 시스템에 대한 로그 수집등 다양한 패턴들이 있는데, https://microservices.io/ 를 보면 잘 정리가 되어 있다.

이런 패턴은 디자인 패턴일 뿐이고, 이를 사용하기 위해서는 시스템에서 구현을 해야 하는데, 당연히 구현에 대한 노력이 많이 들어서 구체화 하기가 어려웠는데, 넷플릭스에서 이러한 마이크로 서비스 아키텍쳐 패턴을 오픈소스화 하여 구현하여 공개하였다. 예를 들어 위에서 언급한 써킷 브레이커 패턴의 경우에는 Hystrix (https://github.com/Netflix/hystrix/wiki)라는 오픈 소스로 공개가 되어 있다.

Hystrix 이외에도, 서비스 디스커버리 패턴은 Eureka, 모니터링 서비스인 Turbine 등 다양한 오픈 소스를 공개했다.



<그림. 넷플릭스의 마이크로 서비스 프레임웍 오픈소스 >

출처 : https://jsoftgroup.wordpress.com/2017/05/09/micro-service-using-spring-cloud-and-netflix-oss/


문제는 이렇게 오픈소스로 공개를 했지만, 여전히 그 사용법이 복잡하다는 것이다. Hystrix 하나만을 적용하는데도 많은 노력이 필요한데, 여러개의 프레임웍을 적용하는 것은 여간 어려운 일이 아니다.

그런데 여기서 스프링 프레임웍이 이런 문제를 풀어내는 기여를 한다. 스프링 프레임웍에 넷플릭스의 마이크로 서비스 오픈 소스 프레임웍을 통합 시켜 버린것이다. (http://spring.io/projects/spring-cloud-netflix)

복잡한 부분을 추상화해서 스프링 프레임웍을 적용하면 손쉽게 넷플릭스의 마이크로 서비스 프레임웍을 사용할 수 있게 해줬는데, 마지막 문제가 남게 된다. 스프링은 자바 개발 프레임웍이다. 즉 자바에만 적용이 가능하다.

서비스 매쉬

프록시

이러한 마이크로 서비스의 문제를 풀기 위해서 소프트웨어 계층이 아니라 인프라 측면에서 이를 풀기 위한 노력이 서비스 매쉬라는 아키텍쳐 컨셉이다.

아래와 같이 서비스와 서비스간의 호출이 있을때


이를 직접 서비스들이 호출을 하는 것이 아니라 서비스 마다 프록시를 넣는다.


이렇게 하면 서비스로 들어오거나 나가는 트래픽을 네트워크 단에서 모두 통제가 가능하게 되고, 트래픽에 대한 통제를 통해서 마이크로 서비스의 여러가지 문제를 해결할 수 있다.

예를 들어 앞에서 설명한 써킷 브레이커와 같은 경우에는 호출되는 서비스가 응답이 없을때 프록시에서 이 연결을 끊어서 장애가 전파되지 않도록 하면된다.


또는 서비스가 클라이언트 OS에 따라서 다른 서비스를 호출해야 한다면, 서비스가 다른 서비스를 호출할때, 프록시에서 메세지의 헤더를 보고 “Client”라는 필드가 Android면, 안드로이드 서비스로 라우팅을 하고, “IOS”면 IOS 서비스로 라우팅 하는 지능형 라우팅 서비스를 할 수 있다.


이런 다양한 기능을 수행하기 위해서는 기존의 HA Proxy,nginx, Apache 처럼 TCP 기반의 프록시로는 한계가 있다. 예를 들어서 위에서 언급한 HTTP 헤더 기반의 라우팅이나 조금더 나가면 메세지 본문을 기반으로 하는 라우팅들이 필요하기 때문에, L7 계층의 지능형 라우팅이 필요하다.

서비스 매쉬

그러면 이러한 마이크로 서비스에 대한 문제를 소프트웨어 계층이 아니라, 프록시를 이용해서 인프라 측면에서 풀어낼 수 있다는 것을 알았다. 그렇지만 마이크로 서비스는 한두개의 서비스가 아니라 수백, 수천의 서비스로 구성된다. 프록시를 사용해서 여러 기능을 구성할 수 있지만 문제는 서비스 수에 따라 프록시 수도 증가하기 때문에, 이 프록시에 대한 설정을 하기가 어려워진다는 것이다.



그래서 이런 문제를 해결하기 위해서, 각 프록시에 대한 설정 정보를 중앙 집중화된 컨트롤러가 통제하는 구조를 취할 수 있다. 아래 구조와 같이 되는데,

각 프록시들로 이루어져서 트래픽을 설정값에 따라 트래픽을 컨트롤 하는 부분을 데이타 플레인(Data Plane)이라고 하고, 데이타 플레인의 프록시 설정값들을 저장하고, 프록시들에 설정값을 전달하는 컨트롤러 역할을 하는 부분을 컨트롤 플레인(Control Plane) 이라고 한다.


다음 글에서는 이러한 서비스 매쉬 구조를 구현한 오픈 소스 솔루션인 Istio에 대해서 알아보도록 하겠다.



EAI, ESB, API 게이트 웨이,서비스 매쉬

조대협 (http://bcho.tistory.com)


서비스간의 연동은 작게 보면 마이크로 서비스 아키텍쳐로 인한 문제 같지만, 서비스간의 연동은 마이크로 서비스 아키텍쳐 이전에도 자주 있어왔던 전통적인 문제이다. 이러한 문제를 소프트웨어 개발 프레임웍이 아니라, 솔루션 차원에서 풀기 위한 여러가지 노력들이 있었다.


시스템 통합 문제

메인 프레임 시대에서 유닉스 시스템으로 내려오면서 부터 시스템들은 업무 단위로 분리가 되기 시작했다. ERP,CRM 등과 같은 시스템으로, 은행은 대내,대외,정보계와 같이 시스템으로 잘게 잘게 나눠지기 시작했는데, 당연히 이렇게 나눠진 시스템 사이에는 통신이 필요하게 되었고, 시스템이 거대화 되가면서, 시스템간에 직접 P2P로 통신하는 구조는 한계에 다다르기 시작하였다.  



시스템이 서로 얽히고 어느 시스템이 어떤 시스템과 통신하는지 통제가 어렵게 되는 상황이 되었다.

EAI (Enterprise Application Integration)

이러한 시스템간의 문제를 해결하기 위해서 등장한 솔루션이 EAI인데, 통합을 원하는 시스템을 기존에는 직접 1:1로 붙였다면, EAI는 EAI가 중앙에 허브 역할을 하면서, 모든 통신을 EAI를 거치도록 하였다.



EAI의 가장 큰 특징은 표준화 되지 않은 이기종 시스템간의 연동을 가능하게 해준다는 것이다. 메인프레임 → Unix ERP 시스템으로 데이타를 전송하게 한다던지 Oracle → CRM 시스템으로 데이타를 전송해주는 것과 같은 시스템 통합을 지원했는데, 이는 이기종간에 통신 프로토콜이나 통합 방식을 변경할 수 있는 아답터를 제공하기 때문이다. EAI는 복잡한 메세지 처리나 변동, 라우팅같은 다양한 기능을 가지고 있었지만, 주로 이 기종간의 메세지 변환이 가장 많이 사용되었다.

어쨌거나 이런 EAI는 중앙 통제를 통해서 1:1 / 다:다로 통신되는 복잡한 토폴로지를 통합하는 의미가 있다.


EAI 시스템이 점점 더 많아지자. 시스템 통합 아키텍쳐도 패턴화 되었다. EIP (Enterprise Integration Pattern)이라는 형태로 정리되었는데, 아직도 참고할만한 구조가 많으니 관심이 있으면 참고하기 바란다.

https://www.enterpriseintegrationpatterns.com/patterns/messaging/toc.html

SOA / ESB

이 기종간의 통합이 많아지고, 시스템이 점점 분리되다 보니, 아예 이를 표준화하고자 하는 작업이 진행되었는데, 이것이 바로 SOA (Service Oriented Archtiecture / 서비스 지향 아키텍쳐) 이다.

SOA 아키텍쳐의 컨셉 자체는 MSA와 유사하지만, XML 기반의 웹서비스와 맞춰져서 웹서비스를 대표하는 아키텍쳐가 되어버렸다.

(사실 SOA는 아키텍쳐 구현 컨셉이지 XML/HTTP를 대표하는 것이 아니지만, 시대적으로 벤더들에 의해 웹서비스로 포장되었다. SOA는 시스템을 서비스로 나눈 다음 표준화된 인터페이스로 통신한다는 컨셉으로, 요즘의 MSA도 이 SOA의 부분 집합이라고 할 수 있다. )


웹서비스 기반으로 통신이 표준화되었기 때문에 서비스간의 통신은 EAI처럼 별도의 아답터가 필요없어졌다. 대신 서비스간의 통신을 서비스 버스라는 통신 백본을 이용하여 통신을 하는 구조가 되었다.




이론적으로는 매우 좋은 구조지만 웹서비스 자체가 스펙이 너무 복잡했고, 그 당시의 컴퓨팅 파워가 복잡한 XML을 파싱하기에는 충분하지 않았기 때문에 그다지 성공하지는 못한 아키텍쳐가 되었다.

특히나 ESB내에서 서비스간의 통신시에, 복잡한 XML 변환등을 사용하다가 ESB에 부하가 걸리게 되고, 제대로된 성능을 내지 못하는 결과를 낳게 되었다.

API Gateway

엔터프라이즈에 의해서 IT가 주도되는 시대가 끝나고 웹과 서비스의 시대가 오면서 개방형 API 즉, 오픈 API가 각광 받는 시대가 오면서 시스템 내부간의 통합도 중요했지만 외부로 API를 서비스 하는 클라이언트 대 서버간의 통합 그리고 외부 서버와 내부 서버와의 통합이 중요한 요건으로 대두되었다.

웹 기반의 서비스들은 복잡한 형태의 메세징을 필요로하지 않았기 때문에 XML을 버리고 상대적으로 간단한 JSON이 메인으로 사용되었고, 이를 HTTP 통신에 사용하면서 HTTP/JSON 기반의 REST 아키텍쳐가 유행하기 시작했다.

그래서  API 게이트 웨이가 외부로 서비스를 제공하기 위한 솔루션으로 제공되고, 시스템 내부간의 통합도 HTTP REST 를 이용하여 마치 ESB처럼 내부 버스로써 내부 시스템 통합을 지원하였다.



그러나 API 게이트웨이의 주요 목적은 앞에서 언급한 시스템간의 통합보다는, 클라이언트와 서버 중간에서 API에 대한 라우팅이나 인증 처리와 같이 내부 API를 외부 서비스로 제공하는데 촛점이 맞추어졌다.

물론 API에 대한 중간 통로 역할을 한다는 의미에서 ESB의 대안 모델로 사용이 가능하기 때문에, API 게이트웨이를 내부 서비스간 통신용으로 위치시키는 아키텍쳐도 있지만,  원래 목적 자체가 API를 외부에 서비스 하기 위한 목적으로 디자인된 아키텍쳐이기 때문에 여러모로 맞지 않는 부분이 있다.

특히나 대부분의 API 게이트 웨이는 게이트 웨이 인스턴스(클러스터)를 포진 시키는 방식이라서 서비스간의 통합 포인트가 많아서 복잡도가 올라가는 경우 API 게이트 웨이에 많은 부하가 걸려서 성능 저하가 발생하고, API 게이트 웨이가 장애가 날 경우 전체 서비스에 영향을 주는 (SPOF : Single Point of Failure) 가 된다는 단점이 있다.  

Service Mesh

이런 단점을 보안한 아키텍쳐가 서비스 매쉬 아키텍쳐이다.

  • API 게이트웨이와는 달리 외부로 서비스를 노출하기 보다는 내부 서비스간의 통신을 조율에 중점을 둔다.

  • 구조적으로 중앙 집중화 구조를 벗어나서, 분산형 아키텍쳐를 취하는 구조이다. 그래서 SPOF를 생성하지 않고 스케일한 서비스를 지원하기 좋다.


그래서 근래의 마이크로 서비스 아키텍쳐에서 안정적인 구조는 외부 서비스는 API 게이트 웨이를 통해서 노출하고, 내부 서비스는 서비스 매쉬를 통해서 통제하는 구조가 된다.



서비스 매쉬의 개념은 다음과 같다.

서비스가 서비스를 호출 하는 구조가 있을때


위의 그림과 같이 서비스가 서비스를 바로 직접 호출 하는 것이 아니라, 아래 그림과 같이 프록시를 둬서, 프록시를 통해서 호출을 하게 하는 구조이다.


이러한 구조를 가지게 되면, 네트워크 트래픽을 컨트롤 하는 것을 서비스의 소스 코드 변경없이도 가능하다. 예를 들어 서비스가 다른 대상 서비스를 호출할때 아래 그림과 같이, HTTP 헤더에서, 클라이언트의 종류에 따라 트래픽을 안드로이드용 서비스나 IOS용 서비스로 라우팅을 할 수 있다.


이러한 구조의 장점은 서비스를 호출하는 쪽이나 호출 받는 쪽이나 소스 코드 변환이 필요 없이 가능하다는 것이다.

서비스 매쉬의 가장 대표적인 솔루션은 istio 라는 솔루션으로 다음 글에서는 Istio에 대해서 설명하도록 하겠다.




Service Mesh

아키텍쳐 /대용량 아키텍쳐 | 2018.06.11 00:45 | Posted by 조대협

서비스 매쉬의 컨셉


기본 개념


MSA로 전환이 되면서, 내부 서비스간의 Orchestration 뿐 아니라, 

서비스 레지스트리, 중앙 로그 수집, 분산 트렌젝션 추적, 메세지 라우팅등 다양한 기능들이 필요하게되었는데,

이러한 구현은 ESB에서 근래에 API GW 등을 사용하는 접근으로 바뀌었지만, 적당한 솔루션이 없고, 중앙 집중화된 솔루션으로 인한 장애와 운영 복잡도에 따라 중앙 집중형이 아닌 Proxy 서버를 각 서비스 앞에 배치 시키는 형태의 접근 방법이 대두되고 있는데, 이를 service mesh라고 하며,

이에 대한 실 구현체로는 Isitio나 linkerd 와 같은 오픈 소스 프로젝트들이 진행되고 있다.


Service Mesh = Network Layer


서비스 매쉬는, TCP/IP위의 새로운 네트워크 레이어로 정의되기도 한다.

TCP L3/L4가 각 종단간의 머신(프로세스)를 연결하기 위한 메커니즘이라면 서비스 매쉬는 서비스간의 통신을 위한 메커니즘으로 볼 수 있다. 


아래 자료 참고 

The service mesh is a networking model that sits at a layer of abstraction above TCP/IP. It assumes that the underlying L3/L4 network is present and capable of delivering bytes from point to point. (It also assumes that this network, as with every other aspect of the environment, is unreliable; the service mesh must therefore also be capable of handling network failures.)

In some ways, the service mesh is analogous to TCP/IP. Just as the TCP stack abstracts the mechanics of reliably delivering bytes between network endpoints, the service mesh abstracts the mechanics of reliably delivering requests between services. Like TCP, the service mesh doesn’t care about the actual payload or how it’s encoded. The application has a high-level goal (“send something from A to B”), and the job of the service mesh, like that of TCP, is to accomplish this goal while handling any failures along the way.

Unlike TCP, the service mesh has a significant goal beyond “just make it work”: it provides a uniform, application-wide point for introducing visibility and control into the application runtime. The explicit goal of the service mesh is to move service communication out of the realm of the invisible, implied infrastructure, and into the role of a first-class member of the ecosystem—where it can be monitored, managed and controlled.

Isitio vs Linkerd

지원 하는 기능은 비슷한듯,분산로그 추적, 다이나믹 라우팅, 매트릭 수집 등. 그러나 구조적인 면에서 Isitio는 프록시를 Pod에 사이드 카로 배포하고 Linkerd는 K8s에서 Daemonset으로 배포해서 하나의 Pod가 노드의 모든 Pod의 메세지 라우팅을 담당하는 구조가 됨


정의 참고

https://www.thoughtworks.com/radar/techniques/service-mesh

https://blog.buoyant.io/2017/04/25/whats-a-service-mesh-and-why-do-i-need-one/#_ga=2.36506144.1424840283.1528645558-1445170731.1528645558