Kubernetes Tools/Istio

[Istio 가이드 ep.36] 6부 트러블슈팅 #1 | VirtualService & DestinationRule 디버깅

ygtoken 2025. 3. 18. 12:11
728x90

🔹 개요

이번 글에서는 Istio에서 VirtualService와 DestinationRule을 디버깅하는 방법을 살펴보겠습니다.
Istio의 트래픽 관리 기능은 주로 VirtualService와 DestinationRule을 통해 설정되는데,
잘못된 설정이 적용되면 라우팅 오류, 서비스 미접근, 트래픽 미러링 실패 등의 문제가 발생할 수 있습니다.

이 글에서는 VirtualService 및 DestinationRule의 주요 문제 원인, 디버깅 방법 및 해결책을 설명하겠습니다.


🔹 1. VirtualService와 DestinationRule의 역할

1.1 VirtualService란?

VirtualService는 Istio에서 트래픽을 특정 서비스로 라우팅하는 규칙을 정의하는 리소스입니다.
VirtualService를 설정하면, 서비스 간 트래픽을 특정 경로로 보내거나, Canary 배포 및 트래픽 분할을 수행할 수 있습니다.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-service
  namespace: default
spec:
  hosts:
    - my-service.default.svc.cluster.local
  http:
    - route:
        - destination:
            host: my-service
            subset: v1  # DestinationRule에 정의된 subset으로 트래픽 라우팅
          weight: 100

1.2 DestinationRule이란?

DestinationRule은 VirtualService에서 정의한 트래픽을 특정 서브셋(Subset)으로 라우팅하는 규칙을 설정하는 리소스입니다.
VirtualService가 트래픽을 보낼 대상이 어디인지 지정하는 역할을 합니다.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-service
  namespace: default
spec:
  host: my-service
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

💡 VirtualService에서 subset: v1을 사용하면, 트래픽이 version: v1 레이블을 가진 Pod으로 전달됩니다.


🔹 2. VirtualService 및 DestinationRule 디버깅 방법

2.1 VirtualService와 DestinationRule의 현재 설정 확인

Istio에서 현재 적용된 VirtualService 및 DestinationRule을 확인하려면 다음 명령어를 실행합니다.

kubectl get virtualservice -n default
kubectl get destinationrule -n default

 

출력 예제:

NAME           GATEWAYS   HOSTS                          AGE
my-service     []         ["my-service.default.svc.cluster.local"]   10m
NAME           HOST                           AGE
my-service     my-service.default.svc.cluster.local   10m

💡 VirtualService와 DestinationRule이 정상적으로 존재하는지 먼저 확인해야 합니다.


2.2 VirtualService에서 트래픽이 정상적으로 라우팅되는지 확인

VirtualService 설정이 올바르게 적용되었는지 확인하려면 다음 명령어를 실행합니다.

kubectl describe virtualservice my-service -n default

 

출력 예제:

Name:         my-service
Namespace:    default
Hosts:        my-service.default.svc.cluster.local
Gateways:     <none>
HTTP Routes:
  Match:
  Route:
    Destination: my-service Subset: v1

💡 Route: Destination: my-service Subset: v1이 올바르게 설정되어 있는지 확인해야 합니다.


2.3 DestinationRule에서 서브셋(Subset)이 올바르게 설정되었는지 확인

DestinationRule에서 정의한 서브셋(Subset)이 올바르게 적용되었는지 확인하려면 다음 명령어를 실행합니다.

kubectl describe destinationrule my-service -n default

 

출력 예제:

Name:         my-service
Namespace:    default
Host:         my-service.default.svc.cluster.local
Subsets:
  Name: v1
  Labels: version=v1
  Name: v2
  Labels: version=v2

💡 서브셋이 정상적으로 정의되어 있는지 확인해야 합니다.


2.4 Istio Proxy를 통해 트래픽 흐름 확인

VirtualService와 DestinationRule이 올바르게 설정되었지만 트래픽이 예상대로 전달되지 않는다면,
Istio Proxy(Envoy)에서 트래픽 흐름을 확인해야 합니다.

kubectl logs <pod-name> -c istio-proxy -n default | grep "my-service"

 

출력 예제:

[2024-03-17T12:45:00.123Z] "GET /api" 200 - upstream_cluster="outbound|80||my-service.default.svc.cluster.local"

💡 upstream_cluster="outbound|80||my-service.default.svc.cluster.local"이 존재하면 정상적으로 라우팅되고 있는 것입니다.


🔹 3. VirtualService & DestinationRule 트러블슈팅 실전 예제

3.1 트래픽이 올바른 서브셋(Subset)으로 전달되지 않는 경우

🛠️ 해결 방법: DestinationRule이 올바르게 설정되었는지 확인하고, 레이블을 검증해야 합니다.

① DestinationRule에서 서브셋이 존재하는지 확인

kubectl get destinationrule my-service -n default -o yaml

 

출력 예제:

spec:
  host: my-service
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

② 실제 Pod의 레이블 확인

kubectl get pods -l version=v1 -n default

 

출력 예제:

NAME            READY   STATUS    RESTARTS   AGE
my-service-v1   1/1     Running   0          5m

💡 서브셋 v1이 version=v1 레이블을 가진 Pod으로 연결되는지 확인해야 합니다.


3.2 VirtualService에서 트래픽이 특정 서브셋으로 전달되지 않는 경우

🛠️ 해결 방법: VirtualService의 라우팅 규칙을 점검해야 합니다.

① VirtualService의 트래픽 분배 설정 확인

kubectl get virtualservice my-service -n default -o yaml

 

출력 예제:

spec:
  hosts:
    - my-service.default.svc.cluster.local
  http:
    - route:
        - destination:
            host: my-service
            subset: v1
          weight: 50
        - destination:
            host: my-service
            subset: v2
          weight: 50

② 트래픽 분배 비율이 잘못 설정되었는지 확인

  • weight: 50, 50 → 트래픽이 v1과 v2로 50%씩 분배됨
  • 특정 서브셋으로 100% 트래픽을 보내려면 다음과 같이 설정해야 함
spec:
  hosts:
    - my-service.default.svc.cluster.local
  http:
    - route:
        - destination:
            host: my-service
            subset: v1
          weight: 100

💡 트래픽이 올바르게 전달되지 않는다면 weight 설정을 점검해야 합니다.


📌 결론

  • VirtualService는 트래픽 라우팅 규칙을 정의하며, DestinationRule은 서브셋을 설정합니다.
  • 트래픽이 예상과 다르게 전달될 경우, VirtualService와 DestinationRule의 설정을 점검해야 합니다.
  • Istio Proxy 로그(istio-proxy 컨테이너)를 확인하면 트래픽 흐름을 분석할 수 있습니다.
  • Pod의 레이블이 DestinationRule의 서브셋과 일치하는지 확인해야 합니다.
728x90