Ssoon

[3주차] 복원력(애플리케이션 네트워킹 문제 해결) : Istio로 Circuit breaking 본문

Istio Hands-on Study [1기]

[3주차] 복원력(애플리케이션 네트워킹 문제 해결) : Istio로 Circuit breaking

구구달스 2025. 4. 20. 21:13
CloudNet@ 가시다님이 진행하는 Istio Hands-on Study [1기]

⚡️ Istio로 Circuit Breaking 구현하기:
시스템 보호와 안정성 강화

분산 시스템에서는 서비스 장애가 연쇄적으로 퍼져 전체 시스템을 마비시킬 수 있습니다.

Circuit Breaking은 이러한 연쇄 장애(Cascading Failures)를 방지하기 위해 비정상 서비스로의 트래픽을 차단하는 강력한 패턴입니다.


🌐 Circuit Breaking의 개념과 중요성

  • Circuit Breaking은 전기 회로의 차단기처럼 동작합니다. 집에서 전기 회로가 과부하되면 차단기가 작동해 추가 손상을 막는 것처럼, 분산 시스템에서는 비정상 서비스로의 요청을 차단해 시스템을 보호합니다.
    예를 들어, simple-web이 simple-backend를 호출할 때 simple-backend가 연속적으로 에러를 반환한다면, 계속된 요청(Retry 등)은 시스템에 부담을 주고 복구를 방해할 수 있습니다.
  • Circuit Breaking은 이런 상황에서 요청을 중단해 비정상 서비스가 복구할 시간을 줍니다.
    이를 통해 연쇄 장애를 방지하고, 네트워크 호출이 실패할 수 있다는 현실을 애플리케이션이 처리하도록 돕습니다.
Circuit Breaking은 비정상 서비스로의 트래픽을 차단해 연쇄 장애를 방지하고,
시스템 복구를 돕는 패턴입니다.

🛡️ Istio의 Circuit Breaking 메커니즘

  • Istio는 명시적인 "Circuit Breaker" 설정은 없지만, 두 가지 제어 방식을 통해 Circuit Breaking을 구현합니다:
    • Connection Pool 관리: 특정 서비스로의 연결 수와 대기 중인 요청 수를 제한해 과부하를 방지합니다.
    • Outlier Detection: 비정상 엔드포인트를 감지하고 일정 시간 동안 트래픽을 차단해 서비스를 보호합니다.
  • 이 두 기능은 서비스가 느려지거나 장애가 발생할 때 요청을 빠르게 차단(Fail Fast)하거나 비정상 엔드포인트를 제외해 시스템 안정성을 유지합니다.
Istio는 Connection Pool 관리와 Outlier Detection을 통해
Circuit Breaking을 구현해 비정상 서비스를 보호합니다.

 

그림 : 비정상 동작하는 엔드포인트를 감지하고 트래픽을 차단하는 Circuit Breaking 과정을 보여줍니다.


🔌 Connection Pool로 요청 제한

  • 첫 번째 Circuit Breaking 제어 방식은 Connection Pool 설정을 통해 서비스로의 연결 수대기 요청 수를 제한하는 것입니다.
    예를 들어, 특정 서비스에 10개의 요청이 진행 중인데 이 수가 계속 늘어난다면, 추가 요청은 서비스를 과부하시키므로 차단해야 합니다.
  • Istio에서는 DestinationRule의 connectionPool 설정을 사용해 이를 제어합니다.
    요청이 너무 많이 쌓이면 Istio는 즉시 실패(Fail Fast) 응답을 반환해 클라이언트를 보호하고, 상위 서비스의 부담을 줄입니다.
Connection Pool 설정은 연결 수와 대기 요청 수를 제한해 과부하를 방지하며,
초과 요청을 빠르게 차단합니다.

🩺 Outlier Detection으로 비정상 엔드포인트 제외

  • 두 번째 제어 방식은 Outlier Detection을 통해 비정상 엔드포인트를 감지하고 일정 시간 동안 트래픽을 차단하는 것입니다. 특정 엔드포인트가 연속적인 실패를 반환하면, Istio는 해당 엔드포인트를 Load Balancing 풀에서 제외합니다.
    모든 엔드포인트가 비정상으로 판단되면, 회로가 "오픈"된 상태가 되어 트래픽이 완전히 차단됩니다.
  • Outlier Detection은 DestinationRule에 설정하며, 연속 에러 수, 제외 시간 등을 조정할 수 있습니다.
    이를 통해 비정상 엔드포인트로의 요청을 줄이고, 정상 엔드포인트로 트래픽을 집중시킵니다.
Outlier Detection은 비정상 엔드포인트를 감지해 트래픽을 차단하며,
모든 엔드포인트가 비정상일 경우 회로를 "오픈"해 시스템을 보호합니다.

📌핵심 요약

  • Circuit Breaking은 비정상 서비스로의 트래픽을 차단해 연쇄 장애를 방지하고 시스템 복구를 돕는 필수 패턴입니다.
  • Istio는 Connection Pool 설정으로 연결 수와 대기 요청 수를 제한해 과부하를 방지하고, Outlier Detection으로 비정상 엔드포인트를 제외해 트래픽을 관리합니다.
  • Connection Pool은 초과 요청을 빠르게 차단(Fail Fast)하며, Outlier Detection은 비정상 엔드포인트를 감지해 회로를 "오픈"할 수 있습니다.
  • 이 두 기능은 서비스가 느려지거나 장애가 발생할 때 시스템 안정성을 유지하는 데 핵심적인 역할을 합니다. Istio의 Circuit Breaking은 분산 시스템의 신뢰성을 높이는 강력한 도구입니다.

🛡️ Istio로 느린 서비스 보호하기:
Connection Pool 제어를 통한 Circuit Breaking

분산 시스템에서 느린 서비스는 요청이 쌓이게 만들어 연쇄 장애를 유발할 수 있습니다.

Circuit Breaking은 이러한 상황에서 트래픽을 제한해 시스템을 보호합니다.

Istio의 Connection Pool 설정을 사용해 느린 서비스를 제어하고, Circuit Breaking을 구현하는 방법을 설명합니다.


🛠️ 테스트 환경 설정

  • Circuit Breaking을 테스트하기 위해 환경을 준비합니다.
    먼저 simple-backend-2 서비스를 스케일 다운해 Pod를 0으로 설정합니다:
kubectl scale deploy/simple-backend-2 --replicas=0
  • 다음으로, simple-backend-1 서비스에 1초 지연을 추가해 느린 응답을 시뮬레이션합니다:
kubectl apply -f ch6/simple-backend-delayed.yaml
  • 이전 실습에서 사용한 DestinationRule이 있다면 모두 삭제합니다:
kubectl delete destinationrule --all
  • 이제 환경이 준비되었습니다. simple-backend는 단일 Pod로 실행되며, 응답에 1초 지연이 있습니다.
테스트를 위해 simple-backend-2를 비활성화하고,
simple-backend-1에 1초 지연을 추가해 느린 서비스를 시뮬레이션합니다.

🔍 기본 부하 테스트

  • Connection Pool 설정 없이 기본 부하 테스트를 수행해 서비스 동작을 확인합니다.
    Fortio를 사용해 1개의 연결(-c 1)초당 1개요청(-qps 1)30초 동안 보냅니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 1 -qps 1 http://localhost/

결과 예시:

# target 50% 1.27611
# target 75% 1.41565
# target 90% 1.49938
# target 99% 1.54961
# target 99.9% 1.55464
Sockets used: 1 (for perfect keepalive, would be 1)
Jitter: true
Code 200 : 30 (100.0 %)
All done 30 calls (plus 1 warmup) 1056.564 ms avg, 0.9 qps
  • 응답은 모두 HTTP 200이며, 평균 응답 시간은 약 1초로 안정적입니다.
    이는 예상대로 느린 서비스가 요청을 처리하는 데 약 1초가 걸리기 때문입니다.
본 부하 테스트에서 느린 서비스는 모든 요청을 성공적으로 처리하지만,
응답 시간이 약 1초로 느립니다.

⚙️ Connection Pool로 Circuit Breaking 설정

  • 이제 DestinationRule을 사용해 Connection Pool을 설정하고 Circuit Breaking을 활성화합니다.
    다음 설정은 연결 수와 요청 수를 엄격히 제한합니다:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: simple-backend-dr
spec:
  host: simple-backend.istioinaction.svc.cluster.local
  trafficPolicy: #트래픽 정책 설정이 시작
    connectionPool:
      tcp:
        maxConnections: 1 #대상 서비스에 대해 최대 1개의 TCP 연결만 허용
      http:
        http1MaxPendingRequests: 1 #최대 1개의 대기중인(pending) HTTP/1.1 요청만 허용
        maxRequestsPerConnection: 1 #하나의 연결당 처리할 수 있는 최대 요청 수를 1개로 제한
        maxRetries: 1 #요청이 실패했을 때 최대 1번만 재시도
        http2MaxRequests: 1 #HTTP/2 프로토콜 사용 시 허용되는 최대 요청 수를 1개로 제한
  • 설정을 적용합니다:
kubectl apply -f ch6/simple-backend-dr-conn-limit.yaml

설정 설명

  • maxConnections: 연결 수의 최대치. 이 값을 초과하면 연결 오버플로우가 발생합니다. 실제로는 Load Balancing 풀의 엔드포인트 수에 따라 추가 연결이 허용될 수 있습니다.
  • http1MaxPendingRequests: 대기 중인 요청 수의 최대치. 연결이 부족해 대기 중인 요청이 이 값을 초과하면 Circuit Breaker가 작동합니다.
  • http2MaxRequests: 모든 엔드포인트에 걸친 병렬 요청 수의 최대치. 이름은 HTTP/2를 의미하지만, HTTP/1.1에도 적용됩니다 (Istio 이슈 #27473 참조).
  • maxRequestsPerConnection: 연결당 최대 요청 수.
  • maxRetries: 최대 재시도 횟수.

 

  • 동일한 부하 테스트를 다시 실행합니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 1 -qps 1 http://localhost/

결과:

Sockets used: 1 (for perfect keepalive, would be 1)
Jitter: true
Code 200 : 30 (100.0 %)
All done 30 calls (plus 1 warmup) 1027.857 ms avg, 1.0 qps
  • 1개의 연결과 초당 1개의 요청으로는 제한에 걸리지 않아 모든 요청이 성공합니다.
Connection Pool 설정으로 연결 수와 요청 수를 제한했으며,
낮은 부하에서는 Circuit Breaker가 작동하지 않습니다.

📈 부하 증가로 Circuit Breaking 테스트

  • 이제 부하를 높여 Circuit Breaking이 작동하는지 확인합니다.
    연결 수를 2개(-c 2), 초당 요청 수를 2개(-qps 2)로 설정합니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 2 -qps 2 http://localhost/

결과:

Sockets used: 27 (for perfect keepalive, would be 2)
Jitter: true
Code 200 : 31 (55.4 %)
Code 500 : 25 (44.6 %)
All done 56 calls (plus 2 warmup) 895.900 ms avg, 1.8 qps
  • 44.6%의 요청이 HTTP 500 에러로 실패했습니다.
    이는 Connection Pool 제한(maxConnections: 1, http1MaxPendingRequests: 1, http2MaxRequests: 1)을 초과Circuit Breaker가 작동했기 때문입니다.
부하를 증가시키자 Connection Pool 제한을 초과해 Circuit Breaker가 작동하며,
일부 요청이 HTTP 500 에러로 실패했습니다.

📊 Circuit Breaking 원인 분석

  • HTTP 500 에러가 Circuit Breaking 때문인지, 상위 서비스의 장애 때문인지 확인하려면 Istio Proxy(Envoy)의 통계를 분석해야 합니다.
    기본적으로 Istio는 통계 수집을 제한
    해 Prometheus 부담을 줄이지만, 추가 통계를 활성화할 수 있습니다.
  • simple-web의 Deployment에 sidecar.istio.io/statsInclusionPrefixes 어노테이션을 추가Circuit Breaking 관련 통계를 수집합니다:
template:
  metadata:
    annotations:
      sidecar.istio.io/statsInclusionPrefixes: "cluster.outbound|80||simple-backend.istioinaction.svc.cluster.local"
    labels:
      app: simple-web
  • 설정을 적용합니다:
kubectl apply -f ch6/simple-web-stats-incl.yaml
  • 통계를 초기화합니다:
kubectl exec -it deploy/simple-web -c istio-proxy \
  -- curl -X POST localhost:15000/reset_counters
  • 다시 부하 테스트를 실행합니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 2 -qps 2 http://localhost/

결과:

Sockets used: 25 (for perfect keepalive, would be 2)
Jitter: true
Code 200 : 31 (57.4 %)
Code 500 : 23 (42.6 %)
All done 54 calls (plus 2 warmup) 1020.465 ms avg, 1.7 qps
  • 통계를 확인합니다:
kubectl exec -it deploy/simple-web -c istio-proxy \
  -- curl localhost:15000/stats | grep simple-backend | grep overflow

결과:

<omitted>.upstream_cx_overflow: 59
<omitted>.upstream_cx_pool_overflow: 0
<omitted>.upstream_rq_pending_overflow: 23
<omitted>.upstream_rq_retry_overflow: 0
  • upstream_cx_overflow: 연결 수 초과(59회)
  • upstream_rq_pending_overflow: 대기 요청 수 초과(23회)

 

  • 23개의 요청이 대기 요청 제한을 초과Circuit Breaker가 작동했으며, 이는 부하 테스트에서 실패한 요청 수(23)와 일치합니다.
Istio Proxy의 통계를 분석해
Circuit Breaking이 대기 요청 초과로 인해 발생했음을 확인했습니다.

🔧 Connection Pool 조정

  • Circuit Breaking을 줄이기 위해 http2MaxRequests를 2로 늘립니다.
kubectl patch destinationrule simple-backend-dr --type merge \
  --patch '{"spec": {"trafficPolicy": {"connectionPool": {"http": {"http2MaxRequests": 2}}}}}'
  • 통계를 초기화하고 부하 테스트를 다시 실행합니다:
kubectl exec -it deploy/simple-web -c istio-proxy \
  -- curl -X POST localhost:15000/reset_counters
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 2 -qps 2 http://localhost/

결과:

Sockets used: 4 (for perfect keepalive, would be 2)
Jitter: true
Code 200 : 32 (94.1 %)
Code 500 : 2 (5.9 %)
All done 34 calls (plus 2 warmup) 1786.089 ms avg, 1.1 qps
  • 통계 확인:
kubectl exec -it deploy/simple-web -c istio-proxy \
  -- curl localhost:15000/stats | grep simple-backend | grep overflow

결과:

<omitted>.upstream_cx_overflow: 32
<omitted>.upstream_cx_pool_overflow: 0
<omitted>.upstream_rq_pending_overflow: 2
<omitted>.upstream_rq_retry_overflow: 0
  • 실패한 요청이 2개로 줄었습니다. 이제 http1MaxPendingRequests를 2로 늘려봅니다.
kubectl patch destinationrule simple-backend-dr --type merge \
  --patch '{"spec": {"trafficPolicy": {"connectionPool": {"http": {"http1MaxPendingRequests": 2}}}}}'
kubectl exec -it deploy/simple-web -c istio-proxy \
  -- curl -X POST localhost:15000/reset_counters
fortio load -H "Host: simple-web.istioinaction.io" \
  -quiet -jitter -t 30s -c 2 -qps 2 http://localhost/

결과:

Sockets used: 2 (for perfect keepalive, would be 2)
Jitter: true
Code 200 : 33 (100.0 %)
All done 33 calls (plus 2 warmup) 1859.655 ms avg, 1.1 qps
  • 모든 요청이 성공했습니다. Connection Pool 제한을 완화Circuit Breaking이 발생하지 않도록 조정했습니다.
Connection Pool의 제한을 완화(http2MaxRequests: 2, http1MaxPendingRequests: 2)해
Circuit Breaking을 줄이고 모든 요청을 성공시켰습니다.

🔔 Circuit Breaking 발생 시 애플리케이션 처리

  • Circuit Breaking으로 요청이 실패하면, Istio Proxy는 응답에 x-envoy-overloaded 헤더를 추가합니다.
    이를 확인하려면 엄격한 Connection Pool 설정(maxConnections: 1, http1MaxPendingRequests: 1, http2MaxRequests: 1)으로 되돌리고, 부하 테스트 중 단일 요청을 보냅니다:
curl -v -H "Host: simple-web.istioinaction.io" http://localhost/

응답 예시:

{
  "name": "simple-web",
  "uri": "/",
  "type": "HTTP",
  "ip_addresses": ["10.1.0.101"],
  "start_time": "2020-09-22T20:01:44.949194",
  "end_time": "2020-09-22T20:01:44.951374",
  "duration": "2.179963ms",
  "body": "Hello from simple-web!!!",
  "upstream_calls": [
    {
      "uri": "http://simple-backend:80/",
      "headers": {
        "Content-Length": "81",
        "Content-Type": "text/plain",
        "Date": "Tue, 22 Sep 2020 20:01:44 GMT",
        "Server": "envoy",
        "x-envoy-overloaded": "true"
      },
      "code": 503,
      "error": "Error processing upstream request: http://simple-backend:80//, expected code 200, got 503"
    }
  ],
  "code": 500
}
  • x-envoy-overloaded: true 헤더는 Circuit Breaking으로 요청이 실패했음을 나타냅니다.
    애플리케이션은 이 헤더를 확인해 Fallback 전략(예: 다른 서비스 호출, 기본 응답 반환)을 실행할 수 있습니다.
Circuit Breaking으로 실패한 요청은 x-envoy-overloaded 헤더를 포함하며,
애플리케이션은 이를 활용해 Fallback 전략을 구현할 수 있습니다.

📌핵심 요약

  • Istio의 Connection Pool 설정은 느린 서비스로의 요청을 제한Circuit Breaking을 구현합니다.
  • 실습에서는 simple-backend-1에 1초 지연을 추가하고, DestinationRule로 maxConnections, http1MaxPendingRequests, http2MaxRequests를 1로 설정해 엄격한 제한을 적용했습니다.
  • 부하 테스트에서 높은 부하(-c 2, -qps 2)로 인해 Circuit Breaker가 작동해 요청의 42.6%가 HTTP 500 에러로 실패했습니다.
  • Istio Proxy 통계(upstream_rq_pending_overflow)를 통해 Circuit Breaking 원인을 확인했고, 제한을 완화(http2MaxRequests: 2, http1MaxPendingRequests: 2)해 모든 요청을 성공시켰습니다.
  • Circuit Breaking 발생 시 x-envoy-overloaded 헤더를 통해 애플리케이션이 이를 감지하고 Fallback 전략을 적용할 수 있습니다.
  • Istio의 Connection Pool 제어는 느린 서비스를 보호하고 시스템 안정성을 높이는 강력한 도구입니다.

🩺 Istio로 비정상 서비스 보호하기:
Outlier Detection을 통한 Circuit Breaking

분산 시스템에서 비정상 서비스는 전체 시스템의 안정성을 위협할 수 있습니다.

Istio의 Outlier Detection은 비정상 엔드포인트를 감지하고 트래픽을 차단해 시스템을 보호하는 강력한 기능입니다.

Outlier Detection을 사용해 비정상 서비스를 제외하는 방법을 설명합니다.

 


🛠️ 테스트 환경 초기화

  • Outlier Detection을 테스트하기 위해 환경을 초기화합니다.
    먼저 simple-backend 서비스를 정상 상태로 복구하고, 이전에 사용한 DestinationRule을 모두 삭제합니다:
kubectl apply -f ch6/simple-backend.yaml
kubectl delete destinationrule --all
  • simple-web 서비스는 이전에서 설정한 확장 통계(sidecar.istio.io/statsInclusionPrefixes)를 유지합니다.
    확실히 하기 위해 해당 설정을 적용합니다:
kubectl apply -f ch6/simple-web-stats-incl.yaml
  • Outlier Detection의 동작을 명확히 확인하기 위해 Istio의 기본 Retry를 비활성화하고, 기존 VirtualService도 삭제합니다:
istioctl install --set profile=demo \
  --set meshConfig.defaultHttpRetryPolicy.attempts=0
kubectl delete vs simple-backend-vs
  • 마지막으로, simple-backend-1 서비스에 75% 확률로 HTTP 500 에러를 반환하도록 설정해 비정상 동작을 시뮬레이션합니다:
kubectl apply -f ch6/simple-backend-periodic-failure-500.yaml
테스트를 위해 simple-backend를 초기화하고, Retry를 비활성화하며,
simple-backend-1에 HTTP 500 에러를 추가해 비정상 서비스를 시뮬레이션합니다.

🔍 기본 부하 테스트: 비정상 서비스의 영향

  • Outlier Detection 없이 부하 테스트를 수행해 비정상 서비스의 영향을 확인합니다.
    Fortio를 사용해 10개의 연결(-c 10)초당 20개의 요청(-qps 20)30초 동안 보냅니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -allow-initial-errors -quiet -jitter -t 30s -c 10 -qps 20 http://localhost/

결과 예시:

Sockets used: 197 (for perfect keepalive, would be 10)
Jitter: true
Code 200 : 412 (68.7 %)
Code 500 : 188 (31.3 %)
All done 600 calls (plus 10 warmup) 189.855 ms avg, 19.9 qps
  • 31.3%의 요청이 HTTP 500 에러로 실패했습니다.
    이는 simple-backend-1주기적 장애(HTTP 500) 때문입니다. Retry가 비활성화된 상태이므로 실패가 그대로 나타납니다.
비정상 서비스(simple-backend-1)로 인해 약 31.3%의 요청이 HTTP 500 에러로 실패하며,
Outlier Detection이 없으면 에러가 지속됩니다.

⚙️ Outlier Detection 설정

  • Outlier Detection을 설정비정상 엔드포인트를 제외합니다. DestinationRule에 다음 설정을 추가합니다:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: simple-backend-dr
spec:
  host: simple-backend.istioinaction.svc.cluster.local
  trafficPolicy:
    outlierDetection: #이상점 탐지(Outlier Detection) 설정이 시작
                      #비정상적인 인스턴스(Pod)를 식별하고 일시적으로 트래픽에서 제외
      consecutive5xxErrors: 1 #연속으로 1개의 5xx 오류(서버 오류)가 발생하면 해당 인스턴스를 이상점으로 간주
      interval: 5s #이상점 탐지를 수행하는 시간 간격을 5초로 설정합니다
      baseEjectionTime: 5s #이상점으로 판별된 인스턴스를 기본적으로 5초 동안 트래픽에서 제외
      maxEjectionPercent: 100 #최대 100%의 인스턴스까지 트래픽에서 제외
                              #모든 인스턴스가 이상점으로 판별되면 모두 트래픽에서 제외될 수 있습니다.

설정 설명

  • consecutive5xxErrors: 연속적인 5xx 에러 수. 1로 설정해 단일 에러로도 엔드포인트를 제외합니다(실제 환경에서는 더 높은 값 권장).
  • interval: 엔드포인트 상태를 확인하는 주기(5초).
  • baseEjectionTime: 제외된 엔드포인트가 제외되는 기본 시간. n번째 제외 시 n * baseEjectionTime 동안 제외됩니다.
  • maxEjectionPercent: 제외 가능한 엔드포인트의 최대 비율. 100%로 설정해 모든 엔드포인트를 제외 가능하도록 합니다(회로 "오픈" 상태).

 

  • 설정을 적용합니다:
kubectl apply -f ch6/simple-backend-dr-outlier-5s.yaml
Outlier Detection을 설정해 단일 5xx 에러로 엔드포인트를 5초 동안 제외하며,
모든 엔드포인트를 제외 가능하도록 설정했습니다.

 

그림 : 비정상 엔드포인트를 감지해 일정 시간 동안 Load Balancing 풀에서 제외하는 Outlier Detection 과정을 보여줍니다.


📈 Outlier Detection 테스트

  • Outlier Detection 적용 후 동일한 부하 테스트를 실행합니다:
fortio load -H "Host: simple-web.istioinaction.io" \
  -allow-initial-errors -quiet -jitter -t 30s -c 10 -qps 20 http://localhost/

결과:

Sockets used: 22 (for perfect keepalive, would be 10)
Jitter: true
Code 200 : 589 (98.2 %)
Code 500 : 11 (1.8 %)
All done 600 calls (plus 10 warmup) 250.173 ms avg, 19.7 qps
  • 에러율이 31.3%에서 1.8%로 크게 감소했습니다.
    이는 Outlier Detection이 simple-backend-1의 비정상 엔드포인트를 제외대부분의 요청이 정상 엔드포인트로 전달되었기 때문입니다.
  • 통계를 확인해 Outlier Detection의 동작을 분석합니다:
kubectl exec -it deploy/simple-web -c istio-proxy -- \
  curl localhost:15000/stats | grep simple-backend | grep outlier

결과 예시:

<omitted>.outlier_detection.ejections_active: 0
<omitted>.outlier_detection.ejections_consecutive_5xx: 3
<omitted>.outlier_detection.ejections_detected_consecutive_5xx: 3
<omitted>.outlier_detection.ejections_enforced_consecutive_5xx: 3
<omitted>.outlier_detection.ejections_enforced_total: 3
<omitted>.outlier_detection.ejections_total: 3
  • simple-backend-1이 3번 제외되었으며, 이는 5초 간격(interval: 5s) 동안 비정상 엔드포인트로 요청이 전달되어 11개의 에러가 발생한 것과 관련 있습니다.
Outlier Detection은 비정상 엔드포인트를 제외해 에러율을 1.8%로 줄였으며,
통계로 제외 횟수와 원인을 확인했습니다.

🔄 Retry와 Outlier Detection 조합

  • 아직 1.8%의 에러가 남아 있습니다. 이를 해결하기 위해 Istio의 기본 Retry를 활성화합니다:
istioctl install --set profile=demo \
  --set meshConfig.defaultHttpRetryPolicy.attempts=2
  • 다시 부하 테스트를 실행하면 에러가 사라질 가능성이 높습니다.
    RetryOutlier Detection이 엔드포인트를 제외하기 전에 발생한 에러재시도해 성공률을 높입니다.
Retry와 Outlier Detection을 조합하면 초기 에러를 재시도해 에러율을 더 줄이고,
비정상 엔드포인트를 효과적으로 제외할 수 있습니다.

📌핵심 요약

  • Istio의 Outlier Detection은 비정상 엔드포인트를 감지Load Balancing 풀에서 제외함으로써 시스템 안정성을 높입니다.
  • 실습에서는 simple-backend-1에 75% 확률로 HTTP 500 에러를 추가해 비정상 서비스를 시뮬레이션했습니다.
  • Outlier Detection 없이 부하 테스트에서 31.3%의 에러가 발생했지만, DestinationRule로 consecutive5xxErrors: 1, interval: 5s, baseEjectionTime: 5s, maxEjectionPercent: 100을 설정한 후 에러율이 1.8%로 감소했습니다.
  • 통계 분석을 통해 엔드포인트가 3번 제외되었음을 확인했으며, Retry를 추가하면 잔여 에러를 제거할 수 있습니다.
  • Outlier Detection은 비정상 서비스를 보호하고 연쇄 장애를 방지하는 강력한 도구로, Retry와 함께 사용하면 더욱 효과적입니다.

 

Comments