Istio 톺아보기 #2 - 트래픽 관리 관련 CRD

2025. 5. 17. 16:57·[DevOps] - Kubernetes

https://dev-ryuon.tistory.com/122

 

Istio 톺아보기 #1 - 개요

서비스 메쉬란?서비스 메쉬는 MSA(마이크로 서비스 아키텍처)환경에서 서비스 간의 통신을 제어하고 관리할 수 있는 인프라 계층을 의미한다. 즉, 서비스 내의 애플리케이션 혹은 비즈니스 로직

dev-ryuon.tistory.com

  • Istio나 서비스 메쉬가 처음이신 분은 이전 게시글을 읽고오시면 이해하기 쉬울거에요!

 

개요


Istiod provides service discovery, configuration and certificate management. Istiod acts as a Certificate Authority (CA) and generates certificates to allow secure mTLS communication in the data plane.

  • Istio는 트래픽 라우팅 규칙을 통해 서비스 간의 트래픽 흐름을 쉽게 제어할 수 있다. 제어할 수 있는 기능으로는 아래와 같은 것들이 있다.
    • Circuit Breaker : 서킷브레이커(회로 차단기)는 서비스 장애 전파와 과부하를 방지하기 위한 패턴이다. DestinationRule CRD에서 설정할 수 있으며, 특정 서비스의 오류율이 임계치를 초과하면 해당 서비스로 흐르는 트래픽을 일시적으로 차단할 수 있다.
    • Timeout : 서비스간 요청이 일정 시간 내에 응답하지 않으면 실패로 간주하고 중단하는 기능이다. VirtualService CRD에서 설정할 수 있다.
    • Retries : 재시도 요청을 통해 실패한 요청에 대해 다시 시도할 수 있는 기능을 제공한다. VirtualService, DestinationRule CRD를 통해 제공하며, 서비스에 대한 신뢰성을 높힐 수 있다.
    • A/B testing : 단일 애플리케이션에 대해 두 개 이상의 버전을 동시에 배포하여 트래픽을 분산시키고 사용자의 반응을 비교하는 실험적 배포 방식이다. VirtualService에 대해 서비스의 버전별로 트래픽 비율을 분배하여 테스트할 수 있다.
    • Canary : 새로운 버전을 소수의 사용자에게 실험적으로 배포하고, 점진적으로 문제가 없을 경우 트래픽의 비중을 높히는 방식의 배포방식이다.
  • 메쉬 내의 트래픽의 목적지를 판단하려면, Istio는 엔드포인트를 알아야하고, 어떤 서비스로 트래픽이 전달되는지 규칙을 알아야 하기 때문에 Service Registry에 등록하게 된다. (메쉬 네트워크의 관리 대상이 되려면 Service Registry에 등록되어야 한다.)
    • istioctl install --set meshConfig.outboundTrafficPolicy.mode=[ALLOW_ANY,REGISTRY_ONLY] 옵션을 통해 Service Registry에 등록된 서비스만 메쉬 내트워크 내의 통신을 제한할지 아니면 모든 외부 트래픽을 허용할지 정할 수 있다.

 


 

Istio에서 제공되는 네트워크 관련 CRD


DestinationRule & VirtualService

  • DestinationRule과 VirtualService는 Istio에서 트래픽 라우팅을 하는데 있어서 핵심 기능이다.
  • VirtualService에서 라우팅 규칙이 평가된 뒤에, DestinationRule에서 트래픽을 실제 목적지까지 전달하는 역할을 수행한다.
    • 우선 DestinationRule에서 Pod의 레이블을 기반으로 subnet을 정의한다.
    • VirtualService에서 주어진 호스트(Kubernetes Service의 FQDN)와 DestinationRule을 통해 생성한 subnet을 통해 라우팅을 수행한다. (물론 VirtualService에서 subnet을 활용하지 않을 수도 있다.)

 

  • 먼저 위 예시를 보면 아래와 같이 이해할 수 있다.
    • DestinationRule CRD에서 version: v1 레이블을 가진 Pod들을 v1 subnet으로 정의한다.
    • 이어서 version: v2 레이블을 가진 Pod들도 v2 subnet으로 정의한다.
    • VirtualService에서 reviews 라는 도메인(hosts)으로 인그레스 트래픽이 들어왔을 때, 아래와 같은 목적지(destination)으로 트래픽을 전달한다.
      • reviews 라는 FQDN을 가진 Kubernetes Service로 트래픽을 전달한다.
      • 그 중에서, DestinationRule에서 정의한 v1 subnet들에만 부분적으로 전달한다. 즉, reviews Service의 Endpoint 대상인 Pod들 중에서 version: v1 레이블을 가진 Pod들만 필터링한다.

 

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: reviews-destination-rule
spec:
  host: reviews # reviews.prod.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3
  • DestinationRule에 대해 조금 더 연습해보자. 위 DestinationRule에서는 reviews (reviews.<namespace>.svc.cluster.local) 라는 FQDN을 가지는 Service 객체에 대하여 총 3개의 subnet을 정의했다. (label을 통해 버전별로(v1 ~ v3) subnet을 분리했다.)
  • 하지만, v2 subent은 RR 방식의 로드밸런싱 알고리즘을 적용했다. 즉, VirtualService를 통해 v2 subnet으로 트래픽이 전달될 경우, 해당 트래픽이 version: v2 레이블을 가진 Pod들에 대해서 라운드 로빈방식으로 전달할 수 있다.
    • 여기서 문서를 보지 않아도 알 수 있는 점은, RR 방식 이외에 로드밸런싱 알고리즘을 지원할 것이고, L7 기능을 제공한다는 점이다. (https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings-SimpleLB)

 

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3
  • 위 VirtualService는 외부로부터 reviews 라는 도메인으로 요청이 들어올 때, 라우팅 규칙을 정의했다.
    • hosts : VirtualService에서 트래픽을 받을 수 있는 호스트들의 나열이다. IP 주소, DNS 이름이 될 수 있으며 와일드카드(*) 접두어를 통해 매칭되는 다수의 서비스들도 정의할 수 있다.
    • http : HTTP/1.1, HTTP2, gRPC 프로토콜의 트래픽을 전달하기 위한 액션들을 정의한다. (http 이외에도 tcp, tls 필드를 통해 정의할 수 있다.)
      • match : VirtualService의 라우팅 규칙을 적용하기 위한 조건들을 의미한다.
      • route : match의 조건에 부합하는 트래픽들을 전달해야 하는 대상을 나타낸다. 위에 정의된 hosts 필드와는 다르게 실제로 Service Registry에 등록된 (메쉬 네트워크의 관리 대상으로 지정된 Service) 호스트여야 한다.
    • 위 YAML을 설명하면, HTTP 헤더에 end-user: jason 사용자에 대해서 version: v2 레이블을 가지는 reviews Service의 대상 Pod들로 트래픽을 전달하고, 그 외는 version: v3로 전달한다.

 

Gateway

  • Gateway는 서비스 메쉬의 인바운드, 아웃바운드 트래픽을 관리하는 역할을 가지고 있다.
  • VirtualService를 Gateway에 바인딩하여 메쉬 내 다른 데이터 플레인처럼 관리할 수 있다.
  • istioctl의 default profile을 통해 세팅하면 istio-ingressgateway를 기본으로 생성할 수 있다. (Istio Profile 관련 내용은 여기 참조)
    • Gateway CRD를 프로비저닝하기 이전에 istio-ingressgateway를 먼저 생성해야 한다. (이때, Envoy 프록시 Pod와 LoadBalancer 타입의 Service 객체가 생성된다.)
      • AWS 환경에서 세팅하는 경우, CLB가 생성되므로, 별도의 애노테이션을 설정하여 ALB / NLB로 프로비저닝할 수 있다. (Nginx Ingress Controller에서도 동일하다.)
    • Gateway CRD는 어떤 Ingress Gateway Pod가 어떻게 트래픽을 수신하고 처리할지 명시하는 역할을 한다. (즉, 실제로 외부 트래픽을 처리하는 주체는 istio-ingressgateway, Gateway CRD의 Controller 역할을 수행한다.)

 

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    app: my-gateway-controller
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      credentialName: ext-host-cert
  • selector : 어떤 레이블을 가진 Istio Ingress 혹은 Egress Gateway Pod를 디스커버리 하는 역할을 수행한다. 즉, app: my-gateway-controller 레이블이 있는 Pod를 Gateway CRD의 컨트롤러로 대상을 지정한다.
  • servers : 어떤 도메인(hosts)에 대하여 어떤 포트(port)를 리스닝 할 것인지를 명시한다.

 

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: virtual-svc
spec:
  hosts:
  - ext-host.example.com
  gateways:
  - ext-host-gwy
  # 라우팅 규칙 매칭 예시
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        host: reviews
  - match:
    - uri:
        prefix: /ratings
    route:
    - destination:
        host: ratings
  • Gateway만 딸랑 정의한다고 서비스 메쉬 내로 트래픽을 전달할 수 없기 때문에 VirtualService도 정의해야 한다. ("VirtualService를 Gateway에 바인딩하여 메쉬 내 다른 데이터 플레인처럼 관리할 수 있다.")
  • gateways 필드를 통해 어떤 Gateway CRD로부터 트래픽을 인입할지 명시하고, 해당 게이트웨어로부터 일치하는 도메인(hosts)에 대해 메쉬 내부 서비스로 트래픽을 라우팅하게 된다.

 

ServiceEntry

  • ServiceEntry는 메쉬 내부에 등록되지 않은 (Service Registry에 등록되지 않은) 외부 서비스를 수동으로 메쉬 내부의 관리 대상으로 등록하는 CRD이다.
  • 물론 Service Registry에 등록하지 않아도 메쉬 내부에서 외부로 트래픽을 전달하지 못하는 것은 아니지만, 서비스 메쉬의 기능을 온전히 활용할 수 없다.

 

apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS
  • hosts : Service Registry에 등록할 외부 도메인
  • location : 등록할 서비스에 대한 메쉬 내외부 구분 용도
    • MESH_EXTERNAL : 메쉬 외부로 인식하여 mTLS 비활성화 및 해당 서비스로 향하는 트래픽을 이그레스 트래픽으로 인식한다.

 

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: ext-res-dr
spec:
  host: ext-svc.example.com
  trafficPolicy:
    connectionPool:
      tcp:
        connectTimeout: 1s
  • 이렇게 외부 서비스도 Service Registry에 등록해두면 DestinationRule이나 VirtualService로 제어가 가능해진다.

 

Sidecar

  • 기본적으로 Istio는 서비스 메쉬 내의 모든 Envoy 프록시에 대해 모든 트래픽을 수용하게끔 설정되어 있다.
    • Sidecar CRD를 통해 수용가능한 포트와 프로토콜 집합을 정의하거나 트래픽이 도달할 수 있는 서비스 집합을 제한할 수 있다.

 

# 예시 1)
apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"
---
# 예시 2)
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: example-sidecar
  namespace: my-namespace
spec:
  workloadSelector:
    labels:
      app: my-app
  egress:
  - hosts:
    - "./b-service.my-namespace.svc.cluster.local"
    - "./c-service.my-namespace.svc.cluster.local"

 

  • 첫 번째 예시는 bookinfo 네임스페이스 내의 모든 서비스들은 동일한 네임스페이스 내의 Service들과 Istio Contol Plane (istio-system 네임스페이스의 모든 Service)에 대해서만 트래픽을 도달할 수 있도록 강제한다.
  • 두 번째 예시는 my-namespace 네임스페이스 내에서 app: my-app 레이블을 가진 Pod에만 적용된다. 해당 서비스(Pod)들은 my-namespace 내의 b-service, c-service Service 객체로만 트래픽을 허용하고 나머지 이그레스 트래픽은 차단된다.

 


 

다음 글에서는 트래픽을 제어하는 옵션(Timeout, Retries, Fault Injection, Circuit Breaker)들에 대해서 알아볼게요~!

'[DevOps] - Kubernetes' 카테고리의 다른 글

Harbor 레지스트리 구성하기 (feat. Helm Chart 연동)  (0) 2025.05.26
Istio 톺아보기 #1 - 개요  (0) 2025.05.17
라즈베리 파이로 홈 쿠버네티스 클러스터 구축 매뉴얼  (1) 2025.04.20
쿠버네티스 환경의 서비스 디스커버리  (0) 2024.05.26
'[DevOps] - Kubernetes' 카테고리의 다른 글
  • Harbor 레지스트리 구성하기 (feat. Helm Chart 연동)
  • Istio 톺아보기 #1 - 개요
  • 라즈베리 파이로 홈 쿠버네티스 클러스터 구축 매뉴얼
  • 쿠버네티스 환경의 서비스 디스커버리
Bebsae
Bebsae
  • Bebsae
    뱁새zip
    Bebsae
  • 전체
    오늘
    어제
    • 분류 전체보기 (108)
      • [DevOps] - Kubernetes (5)
      • [DevOps] - AWS (1)
      • [AI] - Machine Learning (19)
      • [AI] - Neural Network (7)
      • [CS] - Network (2)
      • [CS] - Data Structure (3)
      • [CS] - Design Pattern (6)
      • [Language] - Python (15)
      • [Library] - Numpy (7)
        • Quick Start (5)
        • API (2)
      • [Framework] - Django (3)
      • [Framework] - QGIS (6)
      • [Framework] - PyQT (4)
      • [Mathematics] - Linear Alge.. (14)
      • [Mathematics] - Statistical (2)
      • [ETC] - Python (3)
      • [ETC] - C++ (1)
      • [ETC] - Linux (1)
      • 논문 (5)
      • 회고록 (3)
      • 생산성 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    algebra
    numpy
    Learning
    디자인패턴
    분해
    QGIS
    MachineLearning
    DEEPLEARNING
    RNN
    선형대수
    linearalgebra
    Convolution
    decomposition
    신경망
    Python
    Linear
    Machine
    머신러닝
    파이썬
    교차검증
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Bebsae
Istio 톺아보기 #2 - 트래픽 관리 관련 CRD
상단으로

티스토리툴바