What is istio?

2021-10-26

What is istio?

Do you know Service Mesh?

What is Service Mesh

service-mesh

서비스 메쉬(Service Mesh)란 API 등을 사용하여 마이크로 서비스 간 통신을 안전하고, 빠르고, 신뢰할 수 있게 만들기 위해 설계된 전용 인프라 계층이다. Service Mesh는 보통 Application 서비스에 경량화 프록시(Proxy)를 사이드카(sidecar) 방식으로 배치하여 서비스 간 통신을 제어하며, Service Discovery, Load Balancing, Dynamic Request Routing, Circuit Breacking, Retry and Timeout, TLS, Distributed Tracing, Metric 수집, Access Control, A/B Testing 기능 등을 지원한다.

kind-of-service-mesh

그렇다면 Service Mesh는 왜 필요할까? 시스템의 규모에 따라 다르지만, MSA 시스템에서 수십개의 마이크로 서비스가 동작할 수 있고 그보다 많은 인스턴스들이 동작할 수 있기 때문에 관리하기가 매우 복잡하다. 또한 인스턴스가 수행되는 네트워크 간의 레이턴시, 신뢰성, 안전성 등을 보장할 수도 없다. 이러한 문제점들은 어플리케이션 계층에서 해결할 수도 있지만(예를 들면 Hystrix, Resilience4j 등을 활용한 Circuit Breaker 기능 추가), 그렇게 되면 Application 언어 및 런타임에 종속성이 생기고, 기능 변경 등을 할 때마다 비용이 발생한다.

그렇기 때문에 마이크로 서비스 운영할 때에는 별도의 소스 수정이 필요없이 인프라 레벨에서 안정적으로 관리할 수 있는 Service Mesh가 필요하다.

이해를 돕기 위한 예제

MSA의 구조가 점점 커지고 관리하는 포인트가 많아지는것은 피할 수 없다.

따라서 우리는 항상 똑같은 질문을 하게 될것이다.

  • 서비스가 몇개더라?
  • 무슨 서비스가 있지?
  • 서비스당 인스턴스가 몇개 사용되고 있지?
  • 로드밸런싱은 어떻게하지?

등등등…

그리고 외부 API를 호출하는 경우에 장애가 있다면 장애가 자연스레 전파된다

A -> B -> 외부 API를 호출하는 구조를 가정해보자

외부 API가 Ddos 공격을 받거나 무언가 문제가 생겨 장애가 시작된다면

외부 API를 호출하는 B는 응답을 받지 못해 계속 요청을 하며 타임아웃 예정 스레드가 증가할것이고

그로인해 A는 타임아웃을 기다리는 스레드가 증가하게 될것이다.

근데 또 어디선가 A를 호출한다면? 그대로 또 장애가 전파가 될것이다.

문제 해결

이런 문제를 해결하기 위해 고민하기 시작했고 몇몇 해결 방법을 제시했다

그중 많이 선택된 솔루션은 넷플릭스 제품들이다.

  • Service Discovery Parttern
    • Registry에서 각 인스턴스 정보 관리
    • 인스턴스 정보를 가져와 로드밸런싱
    • Ex: Netflix Eureka (+ Ribbon)
  • Circuit Braker Pattern
    • 일정 수치 이상 에러가 발생시 fallback method 실행
    • 장애 전파 차단으로 시스템 보호
    • Ex: Nteflix Hystix

문제 끝?

위 방법으로 공통된 문제는 해결할 수 있지만 몇몇 문제들이 존재한다

  1. 이걸 다 개발자가 직접 개발해야한다.
  2. 내가 만든 앱이 솔루션을 지원해야하고, 또 다른 앱 모두가 솔루션을 지원해야한다.
  3. 저 많은것을 학습해야한다.

자연스럽게 내가 개발하지 않고 할 수 있는 방법을 생각해볼 수 있는데

그 방법으로는 코드 레벨이 아닌 인프라 레벨에서 처리하는 방법을 떠올리게 된다.

여기서 오늘의 주제인 istio가 등장한다.

istio

그렇다면 istio가 뭐고 어떤 구조길래 인프라 레벨에서 위에서 말한 문제점들을 해결할 수 있을까?

istio가 뭔지 조금 더 살펴보자면 istio는 서비스 매쉬(Service Mesh)를 구현할 수 있는 오픈소스 솔루션이다.

istio를 사용하면 서비스 코드 변경 없이 로드밸런싱, 서비스 간 인증, 모니터링 등을 적용하여 마이크로 서비스를 쉽게 관리할 수 있다.

마이크로 서비스 간의 모든 네트워크 통신을 담당할 수 있는 프록시인 Envoy를 사이드카 패턴으로 마이크로 서비스들에 배포한 다음, 프록시들의 설정값 저장 및 관리/감독을 수행하고, 프록시들에 설정값을 전달하는 컨트롤러 역할을 수행한다.

istio-arch

각각의 마이크로 서비스에 사이드카 패턴으로 배포된 Envoy 프록시를 데이타 플레인(Data Plane)이라고 하고, 데이타 플레인을 컨트롤 하는 부분은 컨트롤 플레인(Control Plane)이라고 한다.

What is Sidecar Pattern

sidecar-1

Sidecar pattern은 (컨테이너 배포방식의 경우) 모든 응용 프로그램 컨테이너에 추가로 sidecar 컨테이너가 배포된다.

Sidecar 컨테이너에서는 어플리케이션 컨테이너에 관련된 확장된 기능들을 추가할 수 있으며, 어플리케이션의 핵심 로직과는 관련없는 기능들을 추가/제거 할 수 있다.

그리고 Sidecar는 서비스에 들어오거나 나가는 모든 네트워크 트래픽을 처리하게 된다. 가장 큰 특징은, 비즈니스 로직이 포함된 실제 서비스와 sidecar이 병렬로 구성되어있기 때문에, 서비스 호출에서 서비스가 직접 서비스를 호출하는 것이 아니라 proxy 를 통해서 호출하게 된다는 점이다.

따라서, 대규모의 MSA 환경이라고 하여도 개발자가 별도의 작업 없이 비즈니스 로직과 관련없는 서비스의 연결 뿐만 아니라, 로깅, 모니터링, 보안, 트래픽 제어와 같은 다양한 이점을 누릴 수 있다.

이러한 이점을 통해 유연한 관리가 가능해진다.

sidecar-2

  • 장점
    • 어플리케이션 언어와 다른 언어로 개발가능하다.
    • 하나의 사이드 컨테이너를 개발하게 되면 다른 어플리케이션에서도 사용가능하다.
    • 어플리케이션 컨테이너의 성능에 거의 영향을 주지 않고 모니터링 가능하다.
    • 확장성있는 기능을 사이드카를 통해 개발 가능하다.
  • 단점 -어플리케이션이 사이드카와 통신하는 비용(시간, 리소스)이 0(Zero)가 아니다. 성능이 중요한 어플리케이션읃 이 비용을 무시할 수 없다.
    • 작은 어플리케이션의 경우, 배보다 배꼽이 커질 수 있다.

재사용할 수 있다는 메리트가 큰 패턴이며, 예를들어 사이드카 컨테이너에서 로깅과 모니터링 + NGINX 기능을 제공한다면 어플리케이션 컨테이너에서는 다른 부분에 더 집중할 수 있다는 점이 있다.

Mesh-Agonostic VS Mesh-aware

mesh-agnostic

mesh-agnostic

mesh-aware

mesh-aware

istio 구성 요소

Proxy

proxy-1 proxy-2

Service Mesh의 컨셉에서는 서비스간에 호출이 필요할 경우 직접 호출이 아닌 Proxy를 통한 호출을 해야한다.

Data Plane & Control Plane

서비스가 증가하면 프록시의 수도 당연히 증가하게 된다. 프록시 수의 증가는 또 다시 관리 포인트가 된다.

이 문제를 해결하기 위해서는 각 프록시에 대한 config를 한곳에서 관리하는 구조를 취해야 한다.

control-config

istio-arch

Envoy

Istio는 envoy 프록시를 사용한다. 이는 Lyft사에 의해 개발 되었으며 다양한 기능을 제공한다.

  • TCP, HTTP1, HTTP2, gRPC protocol 지원
  • TLS client certification
  • L7 라우팅 지원 및 URL 기반, 버퍼링, 서버간 부하 분산량 조절
  • Auto retry / Circuit Breaker 지원 / 다양한 로드밸런싱 기능 제공
  • Zipkin을 통한 분산 트랜잭션 성능 측정 제공
  • Dynamic configuration 지원, 중앙 레지스트리에 설정 및 설정 정보를 동적으로 읽어옴
  • MongoDB에 대한 L7 라우팅 기능
  • 서비스들은 Envoy proxy와 함께 Data Plane을 구성할 수 있다.

Traffic Management

istio는 pilot(service discovery)과 envoy proxy를 활용해 트래픽을 컨트롤 하게 된다.

pilot을 통해 envoy proxy는 트래픽을 관련 서비스로 전달 한다. 또한 기본적인 디스커버리와 로드밸런싱 외에 트래픽의 특정 비율을 새 버전의 Pod으로 보내는 등 더 많은 세밀한 규칙을 지정 할 수 있다.

envoy를 통해 트래픽 관리를 하는 여러 기능들이 있는데, 이 기능들을 사용하기전에 알아야할 필수 요소들 3가지가 있다.

  • Gateway
  • Virtual Service
  • DestinationRule

traffic-management

Gateway

Gateway는 외부로부터 트래픽을 받으며 가장 앞단에 존재한다. mesh에 대한 inbound 및 outbound traffic을 관리하여 mesh에 진입하거나 나갈 트래픽을 지정할 수 있다. gateway는 서비스에 붙는 envoy 처럼 sidecar 로 실행 되는 것이 아니고, standalone envoy proxy 형태로 생성된다.

Istio를 사용한다고 해서 외부에서 들어오는 트래픽을 반드시 Istio gateway를 사용해야 하는 것은 아니다. 기존의 Kubernetes Ingress를 그대로 사용할 수 도 있다.

gateway를 virtual service에 바인딩 하여야 의도한 대로 동작한다. routing rule은 아래 virtual service에 정의하여야 한다.

Virtual Service

istio traffic routing 기능의 핵심 구성 요소이고, istio의 트래픽 관리를 유연하게 만드는 핵심적인 역할을 한다.

virtual service는 k8s service로 요청이 라우팅 되는 방법을 구성할 수 있다. 또한 워크로드에 트래픽을 보내기 위한 다양한 트래픽 라우팅 규칙을 지정하는 방법들을 제공한다.

virtual service 가 없는 경우, envoy는 모든 서비스 인스턴스 간에 round robin 로드 밸런싱을 사용해 트래픽을 분산 시킨다.(모든 서비스에 virtual service를 등록하는걸 권장)

client는 virtual service에 요청을 보내고, envoy는 virtual service rule에 따라 각기 다른 버전으로 라우팅 하는 형태이다. (ex. 20%는 새 버전, 80%는 이전 버전으로 라우팅)

이를 통해 새 서비스 버전으로 전송되는 트래픽의 비율을 점차적으로 늘릴 수 있다.(아래에서 다시 설명) 또한 http/1.1, http2, grpc, tcp 까지 라우팅 규칙을 구성할 수 있다.

Destination Rule

Virtual Service 와 함께 destination rule은 isio의 트래픽 라우팅 기능의 핵심 부분이다.

virtual service가 k8s service로 트래픽을 보내도록 라우팅 했다면, destination rule은 그 서비스 내에서 어느 Pod으로 트래픽을 보낼지, 그리고 어떻게 트래픽을 보낼 것인지 에 대한 정의이다.

Random, Weighted, least request 등 설정에따라 다양하게 트래픽을 보낼 수 있다.


!(phantasmicmeans 기술 블로그)[https://phantasmicmeans.tistory.com/79#comment13024247]