본문 바로가기
Kubernetes/Service Mesh

Istio란?(Istio, Envoy, Kiali)

by isn`t 2022. 3. 24.

Istio란?

서비스 메시(Service Mesh)가 MSA 환경에서 요구되면서 이를 구현하기 위한 수단으로 서비스 메시 구성을 돕는 도구들이 떠오르기 시작했으며, istio는 쿠버네티스 기반의 운영 환경을 가지고 있으면서 규모가 확장되어가고 있는 시스템에서 한 번쯤 고려해 봄직 한 오픈소스 서비스 메시 도구이다. 당연히 쿠버네티스에 한정된 것은 아니지만 병용하는 사례가 굉장히 많다.
AWS에도 App Mesh라는 서비스가 있는데 이건 다음에 비교해보기로.

*개인적인 의견이지만 오픈소스를 사용할 계획이 있다면 많이 쓰이는 도구를 사용하는 편이 그만큼 많은 레퍼런스를 찾을 수 있기 때문에 좋지 않나 싶음

기존 VM이나 물리서버 단위에서는 MSA에 비해 관리 포인트가 많지 않았다. 100대의 물리 서버에 애플리케이션을 설치했다면 100대의 서버를 모니터링 했지만, 한 서버당 마이크로서비스 20개로 쪼개졌다면 모니터링 대상이 2000개로 늘어나면서 MSA 단위에서 서비스간 연계나 문제 발생시 장애포인트를 찾기가 쉽지 않다.

istio의 공식 페이지에서 소개하고 있는 Istio Mesh의 구성도를 참조하면, 핵심은 Service 로 가는 모든 통신의 경로를 통제하고 모니터링하는 것이다. Proxy라고 표기되어 있는 사이드카가 붙어서 Ingress, Egress 트래픽이 모두 Proxy를 통해서 가도록 한다. 마찬가지로 Service A에서 Service B로 통신이 이루어 질 때도 Proxy A에서 Proxy B간의 통신으로 이루어진다. 따라서 관리자는 이 Proxy만 잘 관리하면 되는데, Istio는 이 Proxy를 Envoy라는 이름으로 부른다.

이렇게 Data Plane의 실제 데이터 처리는 Envoy를 통해서 동작하며, Envoy에 대한 제어는 Control plane인 Istiod 데몬에서 수행한다.

Istio의 도입 효과

개발자들은 통신에 대한 부담 없이 Service 영역에 대한 개발에 집중하고 DevOps나 SRE 팀이 Istio 영역을 관리하면서 다양한 기능을 제공하는 식으로 도입 효과를 볼 수 있다. 예를 들면 기존에는 개발 영역에서 특정 기능을 구현하기 위해서 애플리케이션 코드 수정이 필요했으나, Envoy에서 제공하는 통신과 관련된 기능들(카나리 배포를 위한 트래픽 제어라던가, Request에 대한 제한이라던가) Istio 단에서 제공하므로 그러한 수정 없이 기능 구현에만 집중할 수 있게 된다.

Istio를 소개하면서 언급했던 모니터링 관점에서 보자면 서비스간 발생하는 요청은 특정 path로 필터링함으로써 관리 포인트가 많은 MSA 환경에서 장애 발생시, 원인 파악이 보다 쉬워진다는 점도 장점이 되겠다.

Envoy = L7 Proxy

L7 Proxy로 Nginx나 HA Proxy를 많이 사용하는데, 서비스 메시(istio) 구성에서는 Envoy를 L7 Proxy 용도로 많이 사용한다. Envoy를 독립적으로 설치할 수 있는데, Envoy를 Istio가 매핑해서 관리하는 방식이기 때문이다. 따라서 Envoy가 어떻게 동작하는지 먼저 이해가 필요하다.

Envoy가 L7에서 동작하다보니 굉장히 세밀하게 트래픽을 컨트롤 할 수 있다.

static_resources:
 listeners:
 - name: listener_0
 address:
 socket_address:
 address: 0.0.0.0
 port_value: 10000
 filter_chains:
 - filters:
 - name: envoy.filters.network.http_connection_manager
 typed_config:
 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
 stat_prefix: ingress_http
 access_log:
 - name: envoy.access_loggers.stdout
 typed_config:
 "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
 http_filters:
 - name: envoy.filters.http.router
 route_config:
 name: local_route
 virtual_hosts:
 - name: local_service
 domains: ["*"]
 routes:
 - match:
 prefix: "/"
 route:
 host_rewrite_literal: www.envoyproxy.io
 cluster: service_envoyproxy_io


 clusters:
 - name: service_envoyproxy_io
 type: LOGICAL_DNS
 # Comment out the following line to test on v6 networks
 dns_lookup_family: V4_ONLY
 load_assignment:
 cluster_name: service_envoyproxy_io
 endpoints:
 - lb_endpoints:
 - endpoint:
 address:
 socket_address:
 address: www.envoyproxy.io
 port_value: 443
 transport_socket:
 name: envoy.transport_sockets.tls
 typed_config:
 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
 sni: www.envoyproxy.io

위의 예제는 Envoy 공식 페이지에서 가져온 예제 yaml 파일의 내용이다. 실제로 사용할 때는 이보다 더 세밀한 설정이 필요할 수 있다. 이렇게 Envoy의 동작을 yaml 파일로 정의할 수 있지만, Istio를 사용하면 Istio의 Control Plane에 정책을 적용하면 Istio가 알아서 Envoy에 필요한 Config를 내려보내주는 구조로 동작한다.

Modules in Envoy

예제에 정의된 필드의 내용은 아래 Envoy를 구성하는 모듈에 대해 간략히 이해하면 생각보다 쉽게 응용할 수 있을 것 같다.

  • DownStream : Ingress 트래픽
  • UpStream : Egress 트래픽(Envoy 입장에서는 Service쪽이 Egress)
  • Cluster : Envoy가 요청을 리다이렉트 해줄 백 단의 서비스 엔드포인트 집합
  • Listener : IP/Port 바인딩을 담당하고 새로운 TCP 연결/UDP 데이터그램 연결을 수락
  • router : Listener를 거쳐 받아들인 DownStream 요청을 어디로 보낼지 정의
  • filter : 요청을 처리하기 위한 일련의 파이프라인.
  • filter chain : 필터의 집합

Istio on Kubernetes

쿠버네티스 환경에서 Istio는 파드로 가는 트래픽을 가로채기 위해서 파드 내에 사이드카 컨테이너로 덧붙이는 형태로 동작한다. 그러나 우리가 배포할 모든 파드의 yaml 을 수정해서 추가로 컨테이너를 붙여주는 것은 현실적으로 불가능하며, 매우 비효율적이다.

kubectl label ns default istio-injection=enabled

위와 같이 네임스페이스 레벨에 레이블을 설정해두면, 해당 네임스페이스의 파드에는 자동으로 istio 컨테이너가 추가된다.

$ kubectl get pod,svc -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
pod/deploy-websrv-6d6d69d65-hsbht   2/2     Running   0          80s   172.16.184.4   k8s-w2   <none>           <none>

$ kubectl describe pod/deploy-websrv-6d6d69d65-hsbht
Name:         deploy-websrv-6d6d69d65-hsbht
Namespace:    default

...

Containers:
  deploy-websrv:
    ...
  istio-proxy:
    ...

실제로 배포한 결과를 확인해보면 파드 내에 istio-proxy 컨테이너가 자동으로 추가되어 있음을 확인할 수 있다. 그래서 pod/deploy-websrv-6d6d69d65-hsbht 에서도 READY 카운트가 2/2로 표기된다.

Kiali (Kubernetes add on for istio)

웹 대시보드 형태로 Istio 정책을 제어하고 Istio 동작을 확인할 수 있는 기능을 지원


Kiali는 Prometheus와 grafana에 연계해서 메트릭을 가져오고 대시보드에 애니메이션을 보여주기 때문에 함께 구성되어야 한다.

Reference

[Envoy] https://www.envoyproxy.io/docs/envoy/latest/
[Istio] https://istio.io/latest/docs/
[Notion of Gasida] Gasida님 작성하신 KANS 자료 참고