-
[서비스메시] Istio로 트래픽 관리하기DevOps, 클라우드/Service Mesh 2024. 10. 5. 18:04
서비스메시
서비스메시를 가볍게 훑어보면서 느낀 점이 하나 있다.
쿠버네티스와 같은 기존의 오케스트레이션에 포함된 기능과 유사한 역할을 하는 것이 많다는 것이다.
물론, 내가 아직 명확한 유즈케이스를 직접 접해보지 못해서 그런 것이라 생각한다.
분명히 쿠버네티스 단독으로 해결하지 못하는 페인포인트가 있을 것이다.
그래도 서비스메시, 특히 Istio가 제공하는 트래픽 제어에 관한 내용을 살짝 정리해 보자.
세부적인 디테일은 따로.
서비스의 추상화
서비스가 파드에 대한 라우팅을 결정하는 것처럼, 버추얼서비스(VirtualService)도 서비스에 대한 라우팅을 결정한다.
아래의 예시처럼, VirtualService 리소스가 라우팅 정책을 적용해서 특정 서비스로 트래픽을 라우팅한다.
그리고 이렇게 라우팅된 트래픽에 대한 세부적인 정책을 적용하는 리소스가 DestinationRule이다.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: virtual-service-name namespace: default spec: hosts: - service.default.svc.cluster.local # 쿠버네티스에 등록된 서비스 DNS 호스트 http: - route: - destination: host: service.default.svc.cluster.local # 라우팅할 대상 서비스 DNS 1 subset: dr-1 # 사용할 DR 서브셋 명 weight: 90 - destination: host: service-2.default.svc.cluster.local # 라우팅할 대상 서비스 DNS 2 subset: dr-2 # 사용할 DR 서브셋 명 weight: 10 # 요렇게 uri 매칭도 할 수 있다. # match: # - uri: # prefix: "/v1"
위의 예시를 보면 다음과 같은 규칙들을 적용하고 있는 것을 볼 수 있다.
규칙 또는 정책 설명 라우팅 규칙 요청의 URI, 헤더, 쿼리 파라미터 등 기반으로 라우팅 규칙을 설정 트래픽 분산 버전 관리된 서비스 별로 트래픽을 분산하여 카나리 배포를 지원 Retry, Timeout 정책 실패한 요청을 자동 재시도, Timeout 설정 헤더 변조 요청-응답 헤더 변조 여기서 보여주는 쿠버네티스 서비스와의 차이는 다음과 같다.
- 쿠버네티스 서비스는 포드의 IP 주소를 발견하는 방법을 제공한다.
- 버추얼서비스는 프록시를 동적으로 재구성할 수 있게 해주며, 시스템을 재시작하지 않고도 트래픽을 조절한다.
그니까... 우리가 개발하고 운영하는 애플리케이션을 서비스 형태로 배포할 때에는 필연적으로 그 파드와 서비스에 대한 정의가 필요하다.
이렇게 구성된 서비스들을 재배포하거나 할 필요 없이 동적으로 라우팅할 수 있도록 추상화해 주는 것이다.apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: dr-name namespace: default spec: host: service # Service subsets: # Label selector로 동작 - labels: version: a name: dr-1 - labels: version: b name: dr-2 # 요런 식으로 요청에 대한 정책을 지정할 수 있다. trafficPolicy: loadBalancer: simple: ROUND_ROBIN connectionPool: http: maxRequestsPerConnection: 1 outlierDetection: consecutiveErrors: 5 interval: 1m # 연속 오류 탐지 interval baseEjectionTime: 30s # 인스턴스를 트래픽에서 제외시키는 시간 maxEjectionPercent: 50 # 트래픽 분배를 제외하는 인스턴스 비율
DestinationRule 역시 더 많은 정책을 설정할 수 있지만, 기본적으로 위의 예시에서 적용하는 것들은 다음과 같다.
규칙 또는 정책 설명 서킷 브레이커 특정 서비스로 인입되는 트래픽을 차단해 장애 전파 방지 로드 밸런싱 RR, 가중치 등 로드 밸런싱 지원 비정상 상태 감지 연속적으로 발생한 오류나 인스턴스 상태를 감지하고 트래픽 차단 등의 정책을 지정
시스템 복구를 감지하고, 복구 된 시스템으로 트래픽 라우팅여기서 조금 더 찾아보다가 궁금해진 점이 있었다.
VirtualService - Service - Pod 순으로 라우팅을 할 때, 노드 지역성에 기반한 라우팅은 없을까 하는 생각이 들었다.
또, 이런 지역성 라우팅이 Consul이나 Linkerd와 같은 다른 서비스메시에는 어떻게 되어있을까 하는 궁금증이 살짝 들었다.
근데 찾아보니 아래와 같은게 있더라.
자세한 것은 다음에 기회를 봐서 알아보도록 하자.
로드 밸런싱
우리가 분산 시스템, 분산 스토리지, 마이크로 서비스 등 네트워크 상에 분산되어 있는 시스템을 운용할 때 항상 나오는 개념이 있었다.
바로 해시다.
해시의 주요 목적 중 하나는 결국 입력 값을 항상 일관된 출력 값으로 내보내는게 주 목적이다.
실제 구현 방식은 잘 모르더라도 우리가 흔히 SHA와 같은 해시를 많이 접하고 사용한다고 생각한다.
해시 자체가 빠르게 값을 변환할 수 있지만, SHA와 같은 해시는 보안-암호학적 설계가 우선이었고 좀 더 성능-효율에 중심이 된 해시도 존재한다.
murmur 같은 해시들은 보안적 목적이 아니라, 분산 환경에서 빠르고 효율적으로 데이터를 분배하기 위한 목적으로 설계되었다고 한다.
어찌되었건, 클라이언트로부터의 요청에서는 IP, 헤더 등등의 데이터를 추출할 수 있고 이 데이터를 해싱해 사용하면 일관되게 트래픽을 나눌 수 있다.
Envoy 같은 경우는 Ring-Hash, Cookie-hashing, Maglev를 사용하고 있었는데, Ring-hash를 가중치 기반 라우팅과 함께 사용될 때 세션 어피니티가 정상적으로 동작하지 않는 문제가 있었다.
가중치 라우팅을 사용하면 가중치 규칙이 먼저 적용된 후에 세션 어피니티가 로드 밸런서가 적용되었다.
Envoy와 같은 프록시는 프록시에 인입되기 전과 인출된 후가 나뉜다.
클라이언트-서버의 관점으로 보면 프록시 이전 구간이 다운스트림이고, 프록시가 관리하면서 라우팅해주는 구간이 업스트림이다.
프록시에 묶여있는 서비스들이 이미 가중치 규칙이 적용된 트래픽만 수신하기에, Sticky-Session 과 같은 처리 이전에 전체 트래픽을 대상으로 이미 라우팅이 이루어진다.
해싱은 라우팅 정책(다운스트림)의 일부이고, 클러스터 자체의 고유 값이 아니기에 업스트림 로드밸런싱에서 관리하지 않는다.
이후에는 서로 격리된 프록시(LB)로 트래픽이 전달되고, 여기서 아무리 세션 분할을 걸어도 트래픽을 나눌 수 없게 되는 것이다.
이를 해결하기 위해서는 쿠키 기반 라우팅과 가중치 라우팅을 함께 사용할 때, 쿠키 기반 라우팅 정책을 선행해서 적용하면 된다고 한다.
이와 관련된 Envoy 공식 문서도 아래에 같이 첨부해놓는다.
그래서?
사실 우리가 Ingress, Service 와 같은 쿠버네티스 리소스를 접하다보면 어느 정도는 기능이 겹친다고는 볼 수 있다.
다만, 좀 더 세부적인 조정이 가능하고 서비스 영역이 아니라 서비서보다 앞서서 프록시 단에서 정책을 주입하고 서비스의 변경을 최소화 하는게 서비스메시의 주안점이 아닐까 싶다.
'DevOps, 클라우드 > Service Mesh' 카테고리의 다른 글
[서비스메시] Ambient Mesh에 대해서 (1) 2024.08.05 [서비스메시] 변수명은 중요하다. (0) 2024.07.28 [서비스메시] Istio, Envoy (0) 2024.07.13