[3주차] 복원력(애플리케이션 네트워킹 문제 해결) : Client-side 로드 밸런싱
🚀 Istio로 구현하는 Client-Side Load Balancing
서비스가 점점 커지면서 요청을 효율적으로 분산하는 일이 중요
Istio를 사용하면 Client-Side Load Balancing을 통해 클라이언트가 직접 요청을 분산시킬 수 있어, 시스템의 확장성과 안정성을 높일 수 있습니다.
🌐 Client-Side Load Balancing이란?
- Client-Side Load Balancing은 클라이언트가 서비스의 여러 엔드포인트를 직접 선택해 요청을 분산하는 방식입니다.
중앙 집중식 로드 밸런서를 거치지 않기 때문에 병목 현상이나 단일 장애 지점을 줄이고, 클라이언트가 최적의 엔드포인트로 바로 요청을 보낼 수 있습니다. 이를 통해 서비스의 확장성과 유연성이 크게 향상됩니다. - Istio는 Service Discovery와 Endpoint Discovery를 활용해 클라이언트 측 프록시에 최신 엔드포인트 정보를 제공합니다. 이를 통해 클라이언트는 항상 최적의 경로로 요청을 보낼 수 있습니다.
Client-Side Load Balancing은 클라이언트가 직접 엔드포인트를 선택해 요청을 분산하는 방식으로,
병목 현상을 줄이고 서비스 확장성을 높입니다.
그림 : simple-web 프록시가 simple-backend의 엔드포인트 정보를 알고, 이를 기반으로 요청을 분산하는 과정
🛠️ Load Balancing 알고리즘 설정하기
- Istio에서는 DestinationRule 리소스를 통해 클라이언트가 사용할 Load Balancing 알고리즘을 설정할 수 있습니다.
Istio는 Envoy 프록시를 기반으로 하며, 지원하는 알고리즘은 다음과 같습니다:- Round Robin (기본값): 요청을 순차적으로 엔드포인트에 분배합니다.
- Random: 무작위로 엔드포인트를 선택합니다.
- Weighted Least Request: 가장 적은 요청을 처리 중인 엔드포인트에 우선적으로 요청을 보냅니다.
- 이제 DestinationRule을 통해 Round Robin 방식을 설정하는 예제를 살펴보겠습니다.
DestinationRule을 사용하면 Round Robin, Random 등
다양한 Load Balancing 알고리즘을 설정할 수 있습니다.
🧑💻 Client-Side Load Balancing 시작하기
- Istio 환경에서 Client-Side Load Balancing을 설정하는 과정을 단계별로 알아보겠습니다.
먼저, 실습 환경을 준비합니다.
1️⃣ 환경 초기화
- 이전 실습에서 사용한 리소스를 정리합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl delete gw,vs,deploy,svc,destinationrule --all -n istioinaction
No resources found
2️⃣ 샘플 서비스 배포
- simple-backend와 simple-web 서비스를 배포하고, 외부 요청을 처리할 Gateway와 VirtualService를 설정합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch6/simple-backend.yaml -n istioinaction
kubectl apply -f ch6/simple-web.yaml -n istioinaction
serviceaccount/simple-backend created
service/simple-backend created
deployment.apps/simple-backend-1 created
deployment.apps/simple-backend-2 created
serviceaccount/simple-web created
service/simple-web created
deployment.apps/simple-web created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch6/simple-web-gateway.yaml -n istioinaction
gateway.networking.istio.io/simple-web-gateway created
virtualservice.networking.istio.io/simple-web-vs-for-gateway created
- 리소스가 정상적으로 실행 중인지 확인합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get pod -n istioinaction -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
simple-backend-1-7449cc5945-qvxrd 1/2 Running 0 4s 10.10.0.18 myk8s-control-plane <none> <none>
simple-backend-2-6876494bbf-8nvs9 2/2 Running 0 4s 10.10.0.16 myk8s-control-plane <none> <none>
simple-backend-2-6876494bbf-l8hfl 2/2 Running 0 4s 10.10.0.17 myk8s-control-plane <none> <none>
simple-web-7cd856754-9zg6n 2/2 Running 0 3m31s 10.10.0.15 myk8s-control-plane <none> <none>
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get gw,vs -n istioinaction
NAME AGE
gateway.networking.istio.io/simple-web-gateway 3m34s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/simple-web-vs-for-gateway ["simple-web-gateway"] ["simple-web.istioinaction.io"] 3m34s
- 도메인 질의를 위한 임시 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ echo "127.0.0.1 simple-web.istioinaction.io" | sudo tee -a /etc/hosts
cat /etc/hosts | tail -n 3
[sudo] password for ssoon:
127.0.0.1 simple-web.istioinaction.io
127.0.0.1 catalog.istioinaction.io
127.0.0.1 webapp.istioinaction.io
127.0.0.1 simple-web.istioinaction.io
3️⃣ DestinationRule로 Round Robin 설정
- simple-backend 서비스에 Round Robin 알고리즘을 적용하는 DestinationRule을 정의합니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch6/simple-backend-dr-rr.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: simple-backend-dr
spec:
host: simple-backend.istioinaction.svc.cluster.local #DestinationRule이 적용될 서비스
#쿠버네티스 클러스터 내의 전체 도메인 이름(FQDN)으로,
'istioinaction' 네임스페이스에 있는 'simple-backend' 서비스를 가리킵니다.
trafficPolicy: #이 서비스로 향하는 트래픽에 대한 정책을 정의
loadBalancer: #여러 인스턴스(복제본) 간에 트래픽을 분배하는 방식
simple: ROUND_ROBIN #라운드 로빈 방식의 로드 밸런싱을 사용
- 이 설정을 적용합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch6/simple-backend-dr-rr.yaml -n istioinaction
destinationrule.networking.istio.io/simple-backend-dr created
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get destinationrule simple-backend-dr -n istioinaction \
-o jsonpath='{.spec.trafficPolicy.loadBalancer.simple}{"\n"}'
ROUND_ROBIN
샘플 서비스를 배포하고 DestinationRule로 Round Robin Load Balancing을 설정하면,
클라이언트 요청이 여러 엔드포인트에 순차적으로 분배됩니다.
🔍 Load Balancing 동작 확인
- 이제 설정한 Load Balancing이 실제로 작동하는지 확인해보겠습니다.
simple-web 서비스가 simple-backend를 호출하도록 설정했으며, simple-backend는 여러 복제본으로 실행 중입니다. - 다음 명령어로 서비스를 호출하면 JSON 응답이 반환됩니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ curl -s http://simple-web.istioinaction.io:30000 | jq ".upstream_calls[0].body"
"Hello from simple-backend-1"
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ curl -s http://simple-web.istioinaction.io:30000 | jq ".upstream_calls[0].body"
"Hello from simple-backend-2"
- 응답에서 simple-web가 simple-backend-1을 호출한 것을 확인할 수 있습니다.
여러 번 호출하면 simple-backend-1과 simple-backend-2가 번갈아 응답합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ for in in {1..10}; do curl -s http://simple-web.istioinaction.io:30000 | jq ".upstream_calls[0].body"; done
"Hello from simple-backend-2"
"Hello from simple-backend-2"
"Hello from simple-backend-1"
"Hello from simple-backend-2"
"Hello from simple-backend-2"
"Hello from simple-backend-1"
"Hello from simple-backend-1"
"Hello from simple-backend-2"
"Hello from simple-backend-2"
"Hello from simple-backend-2"
- 이 결과는 요청이 Round Robin 방식으로 simple-backend의 두 엔드포인트에 균등하게 분배되었음을 보여줍니다.
Round Robin 알고리즘을 적용하면 요청이 여러 엔드포인트에 순차적으로 분배되어,
Client-Side Load Balancing이 효과적으로 작동합니다.
🛡️ 서비스 안정성 향상
- Client-Side Load Balancing은 단순히 요청을 분산하는 것을 넘어, 서비스의 안정성을 높이는 데 기여합니다.
예를 들어, 특정 엔드포인트의 응답 시간이 느려지거나 장애가 발생하면, Istio의 Load Balancing 알고리즘을 통해 더 빠르고 안정적인 엔드포인트로 요청을 보낼 수 있습니다. - 이를 확인하기 위해 Load Generator를 사용해 simple-backend의 지연 시간을 변경하고, Istio의 Load Balancing 전략을 조정해 최적의 설정을 찾아볼 수 있습니다.
예를 들어, Weighted Least Request 알고리즘을 사용하면 요청이 가장 적게 처리 중인 엔드포인트로 우선적으로 보내져 성능이 개선됩니다.
Client-Side Load Balancing은 느린 엔드포인트를 피하고
안정적인 엔드포인트로 요청을 분배해 서비스 안정성을 높입니다.
📌핵심 요약
- Istio의 Client-Side Load Balancing은 클라이언트가 직접 엔드포인트를 선택해 요청을 분산하는 방식으로, 중앙 집중식 로드 밸런서의 병목 현상을 줄이고 서비스 확장성을 높입니다.
- DestinationRule을 통해 Round Robin, Random, Weighted Least Request와 같은 알고리즘을 설정할 수 있으며, 이를 통해 요청이 여러 엔드포인트에 효율적으로 분배됩니다.
- 실습에서는 simple-web와 simple-backend 서비스를 배포하고, Round Robin 알고리즘을 적용해 요청이 균등하게 분배되는 것을 확인했습니다.
- 또한, Load Balancing은 느린 엔드포인트를 피하고 안정적인 엔드포인트로 요청을 보내 서비스 안정성을 높이는 데 기여합니다.
⏱️ Istio로 실전 시나리오 설정하기:
서비스 지연과 Load Balancing
서비스가 실제 환경에서 어떻게 동작하는지 이해하려면, 요청 처리 시간에 영향을 미치는 다양한 요인을 고려해야 합니다.
서비스 지연을 추가하고, 이를 Fortio라는 도구로 분석해 Load Balancing의 효과를 확인
🌍 실제 환경에서 서비스 지연의 원인
- 실제 서비스 환경에서는 요청 처리 시간이 일정하지 않습니다. 이는 다양한 내부 및 외부 요인 때문입니다.
내부 요인
- Request Size: 요청 크기가 클수록 처리 시간이 길어질 수 있습니다.
- Processing Complexity: 복잡한 연산은 더 많은 시간을 요구합니다.
- Database Usage: 데이터베이스 쿼리 시간이 응답 시간을 늘릴 수 있습니다.
- Calling Other Services: 다른 서비스 호출 시 그 서비스의 응답 시간에 의존합니다.
외부 요인
- Garbage Collections: 갑작스러운 메모리 정리로 서비스가 일시 중단될 수 있습니다.
- Resource Contention: CPU, 네트워크 등의 자원 경합이 발생할 수 있습니다.
- Network Congestion: 네트워크 혼잡은 요청 전송을 지연시킵니다.
이러한 요인들을 시뮬레이션하기 위해, 우리는 서비스 응답에 지연 시간과 변동성을 추가할 것입니다.
서비스 지연은 요청 크기, 연산 복잡도, 자원 경합, 네트워크 혼잡 등 다양한 요인에 의해 발생하며,
이를 시뮬레이션해 Load Balancing의 효과를 확인할 수 있습니다.
🔍 서비스 호출로 응답 시간 확인하기
- 먼저, simple-web 서비스를 호출해 기본적인 응답 시간을 확인해보겠습니다.
아래 명령어를 사용해 서비스를 호출하고 응답 시간을 측정합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ time curl -s -o /dev/null -H "Host: simple-web.istioinaction.io" localhost
real 0m0.007s
user 0m0.006s
sys 0m0.000s
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ time curl -s -o /dev/null -H "Host: simple-web.istioinaction.io" localhost
real 0m0.007s
user 0m0.001s
sys 0m0.004s
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ time curl -s -o /dev/null -H "Host: simple-web.istioinaction.io" localhost
real 0m0.007s
user 0m0.000s
sys 0m0.002s
- 각 호출마다 응답 시간이 약간씩 다릅니다. 이는 서비스 처리에 자연스러운 변동성이 있음을 보여줍니다.
이러한 변동성은 특정 엔드포인트에서 일시적인 지연이 발생할 때 Load Balancing이 어떻게 도움을 줄 수 있는지를 테스트하기에 적합합니다.
서비스 호출을 통해 응답 시간의 변동성을 확인할 수 있으며,
이는 Load Balancing의 효과를 테스트하는 기반이 됩니다.
Figure 6.5: Variable response times in service calls
설명: simple-web 서비스를 여러 번 호출했을 때 응답 시간이 달라지는 것을 보여줍니다. 이는 실제 환경에서의 지연과 변동성을 시뮬레이션합니다.
🛠️ Fortio로 부하 테스트 준비하기
- 변동성이 있는 환경에서 Load Balancing의 효과를 더 잘 확인하려면, 단순한 호출이 아닌 지속적인 부하를 생성해야 합니다. 이를 위해 Fortio라는 CLI 부하 생성 도구를 사용하겠습니다. Fortio는 서비스에 부하를 주고 응답 시간을 분석하는 데 유용합니다.
Fortio 설치
- Fortio는 다양한 플랫폼에서 사용 가능하며, 아래 링크에서 다운로드할 수 있습니다: Fortio Releases
kubectl -n default run fortio --image=fortio/fortio:1.6.8 \
--restart='Never' -- load -H "Host: simple-web.istioinaction.io" \
-jitter -t 60s -c 10 -qps 1000 \
http://istio-ingressgateway.istio-system/
# windows 설치
1. 다운로드 https://github.com/fortio/fortio/releases/download/v1.69.3/fortio_win_1.69.3.zip
2. 압축 풀기
3. Windows Command Prompt : fortio.exe server
4. Once fortio server is running, you can visit its web UI at http://localhost:8080/fortio/
Fortio로 서비스 호출 테스트
- C:\Windows\System32\drivers\etc\hosts 파일에 simple-web.istioinaction.io 을 추가합니다.
C:\Windows\System32\drivers\etc\hosts
# 추가
127.0.0.1 simple-web.istioinaction.io
- Fortio가 제대로 동작하는지 확인하기 위해, 다음 명령어로 simple-web 서비스를 호출합니다:
C:\Users\ssoon\Downloads\fortio_win_1.69.3>fortio curl http://simple-web.istioinaction.io:30000
11:00:32.171 r1 [INF] scli.go:122> Starting, command="Φορτίο", version="1.69.3 h1:G1cy4S0/+JKwd1fuAX+1jKdWto4fPpxAdJHtHrWzF1w= go1.23.8 amd64 windows", go-max-procs=16
HTTP/1.1 200 OK
date: Fri, 25 Apr 2025 02:00:32 GMT
content-length: 895
content-type: text/plain; charset=utf-8
x-envoy-upstream-service-time: 158
server: istio-envoy
{
"name": "simple-web",
"uri": "/",
"type": "HTTP",
"ip_addresses": [
"10.10.0.15"
],
...
Fortio를 사용하면 지속적인 부하를 생성해 Load Balancing의 효과를 테스트할 수 있습니다.
📌핵심 요약
- 실제 서비스 환경에서는 요청 크기, 연산 복잡도, 자원 경합, 네트워크 혼잡 등 다양한 요인으로 인해 응답 시간이 달라집니다.
- 이를 시뮬레이션하기 위해 simple-web 서비스를 호출해 응답 시간의 변동성을 확인하고, Fortio를 사용해 지속적인 부하를 생성했습니다.
- Fortio는 부하 테스트를 통해 Client-Side Load Balancing이 지연이 있는 엔드포인트를 어떻게 처리하는지 분석하는 데 유용합니다.
- 이 과정을 통해 Load Balancing이 서비스 안정성과 성능 향상에 어떻게 기여하는지 확인할 수 있습니다.
🚀 Istio로 다양한
Client-Side Load Balancing 전략 테스트하기
서비스 성능은 사용하는 Load Balancing 전략에 따라 크게 달라질 수 있습니다.
Fortio를 사용해 Round Robin, Random, Least Connection 전략을 테스트하고, 각 전략이 서비스 지연에 어떤 영향을 미치는지 설명
🛠️ 테스트 시나리오 설정하기
- Fortio를 사용해 초당 1,000개의 요청을 10개의 연결로 60초 동안 보내는 부하 테스트를 진행할 것입니다.
Fortio는 각 호출의 지연 시간을 추적하고, 히스토그램과 백분위 수(latency percentile)로 결과를 보여줍니다. - 테스트를 위해 simple-backend-1 서비스에 최대 1초의 지연을 추가해, 가비지 컬렉션(Garbage Collection)이나 애플리케이션 지연과 같은 상황을 시뮬레이션합니다. 이를 통해 Round Robin, ** REFERENCE TO Random **, Least Connection 전략이 지연에 어떻게 반응하는지 비교합니다.
- 먼저, 지연이 추가된 simple-backend-1 서비스를 배포합니다:
- 의도적으로 평균 1초 정도의 지연을 가지며 10ms의 분산을 갖도록 설정
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch6/simple-backend-delayed.yaml
...
spec:
serviceAccountName: simple-backend
containers:
- env:
- name: "LISTEN_ADDR"
value: "0.0.0.0:8080"
- name: "SERVER_TYPE"
value: "http"
- name: "NAME"
value: "simple-backend"
- name: "MESSAGE"
value: "Hello from simple-backend-1"
- name: "TIMING_VARIANCE" #응답 시간에 추가될 무작위 지연의 범위를 정의
value: "10ms"
- name: "TIMING_50_PERCENTILE"
value: "1000ms" #50% 백분위 응답 시간을 1초(1000ms)로 설정합니다. 즉 응답의 절반은 이 값을 기준으로 지연됩니다.
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: nicholasjackson/fake-service:v0.17.0
imagePullPolicy: IfNotPresent
name: simple-backend
ports:
- containerPort: 8080
name: http
protocol: TCP
securityContext:
privileged: false
- 배포 후 재시작
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch6/simple-backend-delayed.yaml -n istioinaction
deployment.apps/simple-backend-1
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl rollout restart deployment -n istioinaction simple-backend-1
deployment.apps/simple-backend-1 restarted
- jaeger 에서 1초 지연 확인
지연이 추가된 서비스를 배포하고, Fortio로 부하 테스트를 설정해
다양한 Load Balancing 전략의 효과를 비교합니다.
🌐 Fortio 서버 모드로 테스트 실행하기
- Fortio를 서버 모드로 실행하면 웹 대시보드를 통해 테스트를 설정하고 결과를 시각화할 수 있습니다.
다음 명령어로 Fortio 서버를 시작합니다:
fortio server
- 브라우저에서 http://localhost:8080/fortio 로 접속해 테스트 파라미터를 입력합니다.
Round Robin 테스트
- 첫 번째 테스트는 Round Robin 전략입니다. Fortio UI에서 다음 파라미터를 입력합니다:
- Title : roundrobin
- URL : http://simple-web.istioinaction.io:30000
- QPS : 1000
- Duration : 60s
- Threads : 10
- Jitter: Check
- No Catch-up : Uncheck
- Extra Headers
- User-Agent: fortio
- Timeout : 2000ms
- Start 버튼을 클릭해 테스트를 시작하고, 60초 후 결과가 저장됩니다. 결과는 히스토그램으로 표시됩니다.
Round Robin 결과:
# target 50% 0.187014
# target 75% 1.01115
# target 90% 1.03025
# target 99% 1.04171
# target 99.9% 1.04286
- 부하 테스트(load testing) 결과의 지연 시간(latency) 분포를 보여주고 있습니다. 각 백분위수(percentile)별 응답 시간을 초 단위로 표시하고 있습니다:
- 0% (중간값): 0.187014초 - 요청의 절반이 이 시간 이내에 처리됨
75%: 1.01115초 - 요청의 75%가 이 시간 이내에 처리됨
90%: 1.03025초 - 요청의 90%가 이 시간 이내에 처리됨
99%: 1.04171초 - 요청의 99%가 이 시간 이내에 처리됨
99.9%: 1.04286초 - 요청의 99.9%가 이 시간 이내에 처리됨
- 0% (중간값): 0.187014초 - 요청의 절반이 이 시간 이내에 처리됨
- 일부 요청(50%와 75% 사이)에서 지연이 발생하는 패턴을 보여줍니다
Round Robin 테스트는 요청을 순차적으로 분배하며,
지연이 있는 엔드포인트로 인해 상위 백분위에서 높은 지연 시간이 관찰됩니다.
🔄 Random Load Balancing 테스트
- 이제 Random 전략을 테스트합니다. DestinationRule을 Random 알고리즘으로 변경합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch6/simple-backend-dr-random.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: simple-backend-dr
spec:
host: simple-backend.istioinaction.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: RANDOM
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$
kubectl apply -f ch6/simple-backend-dr-random.yaml -n istioinaction
destinationrule.networking.istio.io/simple-backend-dr configured
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get destinationrule simple-backend-dr -n istioinaction \
-o jsonpath='{.spec.trafficPolicy.loadBalancer.simple}{"\n"}'
RANDOM
- Fortio UI로 돌아가 다음 파라미터를 입력합니다:
- Title : random
- URL : http://simple-web.istioinaction.io:30000
- QPS : 1000
- Duration : 60s
- Threads : 10
- Jitter: Check
- No Catch-up : Uncheck
- Extra Headers
- User-Agent: fortio
- Timeout : 2000ms
- Start 버튼을 클릭해 테스트를 실행합니다. 결과는 다음과 같습니다.
# target 50% 0.185431
# target 75% 1.00267
# target 90% 1.09289
# target 99% 1.14703
# target 99.9% 1.15244
- 부하 테스트(load testing) 결과의 지연 시간(latency) 분포를 보여주고 있습니다. 각 백분위수(percentile)별 응답 시간을 초 단위로 표시하고 있습니다:
- 50% (중간값): 0.185431초 - 요청의 절반이 이 시간 이내에 처리됨
75%: 1.00267초 - 요청의 75%가 이 시간 이내에 처리됨
90%: 1.09289초 - 요청의 90%가 이 시간 이내에 처리됨
99%: 1.14703초 - 요청의 99%가 이 시간 이내에 처리됨
99.9%: 1.15244초 - 요청의 99.9%가 이 시간 이내에 처리됨
- 50% (중간값): 0.185431초 - 요청의 절반이 이 시간 이내에 처리됨
- 일부 요청(50%와 75% 사이)에서 지연이 발생하는 패턴을 보여줍니다
Random 전략은 요청을 무작위로 분배하지만,
지연이 있는 엔드포인트로 요청이 갈 확률이 여전히 존재합니다.
⚖️ Least Connection Load Balancing 테스트
- 마지막으로 Least Connection 전략을 테스트합니다.
DestinationRule을 Least Connection 알고리즘으로 변경합니다:
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ cat ch6/simple-backend-dr-least-conn.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: simple-backend-dr
spec:
host: simple-backend.istioinaction.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_CONN
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl apply -f ch6/simple-backend-dr-least-conn.yaml -n istioinactionnn.yaml -n istioinaction
destinationrule.networking.istio.io/simple-backend-dr configured
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-QMAIJOE:~/aews-labs/istio-in-action/book-source-code-master$ kubectl get destinationrule simple-backend-dr -n istioinaction \
-o jsonpath='{.spec.trafficPolicy.loadBalancer.simple}{"\n"}'
LEAST_CONN
- Fortio UI에서 다음 파라미터를 입력합니다:
- Title : least_conn
- URL : http://simple-web.istioinaction.io:30000
- QPS : 1000
- Duration : 60s
- Threads : 10
- Jitter: Check
- No Catch-up : Uncheck
- Extra Headers
- User-Agent: fortio
- Start 버튼을 클릭해 테스트를 실행합니다. 결과는 다음과 같습니다:
# target 50% 0.175578
# target 75% 0.192974
# target 90% 1.02031
# target 99% 1.17257
# target 99.9% 1.18779
- Fortio를 사용한 성능 테스트의 응답 시간 분포를 나타냅니다. 각 퍼센타일(percentile)마다 응답 시간(초 단위)을 보여줍니다:
- 50% 퍼센타일(중앙값): 0.175578초 - 모든 요청의 절반이 이 시간 이내에 완료됨
75% 퍼센타일: 0.192974초 - 요청의 75%가 이 시간 이내에 완료됨
90% 퍼센타일: 1.02031초 - 요청의 90%가 이 시간 이내에 완료됨
99% 퍼센타일: 1.17257초 - 요청의 99%가 이 시간 이내에 완료됨
99.9% 퍼센타일: 1.18779초 - 요청의 99.9%가 이 시간 이내에 완료됨
- 50% 퍼센타일(중앙값): 0.175578초 - 모든 요청의 절반이 이 시간 이내에 완료됨
- 50%와 75% 퍼센타일 사이의 응답 시간이 비교적 비슷한 반면(약 0.017초 차이), 75%에서 90% 퍼센타일로 넘어갈 때 응답 시간이 크게 증가한다는 것입니다(약 0.83초 증가). 이는 대부분의 요청은 빠르게 처리되지만, 일부 요청에서 지연이 발생함
Least Connection 전략은 처리 중인 연결이 적은 엔드포인트로 요청을 우선적으로 보내,
중위 지연 시간(50%, 75%)이 다른 전략보다 낮지만, 상위 백분위에서는 여전히 지연이 관찰됩니다.
📌핵심 요약
- Fortio를 사용해 Round Robin, Random, Least Connection Load Balancing 전략을 테스트했습니다.
- 지연이 추가된 simple-backend-1 서비스를 배포해 실제 환경을 시뮬레이션하고, 초당 1,000개의 요청을 60초 동안 보내는 부하 테스트를 진행했습니다. 결과는 다음과 같습니다:
- Round Robin: 요청을 순차적으로 분배하지만, 지연이 있는 엔드포인트로 인해 상위 백분위 지연 시간이 높음.
- Random: 요청을 무작위로 분배하지만, 지연 엔드포인트로 요청이 갈 가능성이 있어 비슷한 결과.
- Least Connection: 연결이 적은 엔드포인트로 요청을 보내 중위 지연 시간(50%, 75%)이 낮지만, 상위 백분위에서는 지연 영향이 남음.
- Least Connection 전략이 중위 지연 시간에서 가장 나은 성능을 보였으나, 지연이 심한 환경에서는 추가적인 최적화(예: Circuit Breaking)가 필요할 수 있습니다.
⚖️ Istio의 Load Balancing
알고리즘 이해하기
서비스의 성능은 어떤 Load Balancing 알고리즘을 사용하느냐에 따라 크게 달라집니다.
이번 글에서는 각 알고리즘이 어떻게 동작하는지, 왜 Least Connection이 더 나은 성능을 보였는지 설명합니다.
📊 테스트 결과 분석
- 이전 부하 테스트에서 확인한 결과는 다음과 같은 점을 보여줍니다:
- 다양한 결과: 각 Load Balancing 알고리즘은 실제 서비스 지연 상황에서 서로 다른 성능을 보였습니다.
- 히스토그램과 백분위 차이: 지연 시간 분포와 백분위 수치가 알고리즘마다 달랐습니다.
- Least Connection의 우수성: Least Connection 전략이 Round Robin과 Random보다 더 나은 성능을 보였습니다.
- 왜 이런 차이가 발생했을까?
부하 테스트 결과는 Load Balancing 알고리즘에 따라 성능이 다르며,
Least Connection이 가장 효율적인 결과를 보여줍니다.
🔄 Round Robin과 Random 알고리즘
- Round Robin과 Random은 구현이 간단하고 이해하기 쉬운 Load Balancing 알고리즘입니다.
- Round Robin: 요청을 엔드포인트에 순차적으로 분배합니다. 예를 들어, 첫 번째 요청은 엔드포인트 1로, 두 번째는 엔드포인트 2로 보내는 방식입니다.
- Random: 무작위로 엔드포인트를 선택해 요청을 분배합니다.
- 두 알고리즘 모두 요청 분배가 균등할 것처럼 보이지만, 실제로는 엔드포인트의 상태를 고려하지 않습니다.
엔드포인트가 Garbage Collection이나 Resource Contention으로 인해 지연을 겪을 수 있습니다.
Round Robin과 Random은 이런 런타임 동작을 반영하지 않아 지연이 있는 엔드포인트로 요청을 보내는 경우가 발생합니다.
Round Robin과 Random은 간단하지만 엔드포인트의 런타임 상태를 고려하지 않아
지연이 있는 환경에서 비효율적일 수 있습니다.
⚡ Least Connection 알고리즘
- Least Connection 알고리즘(Envoy 에서는 Least Request로 구현)은 엔드포인트의 현재 상태를 고려해 요청을 분배합니다. 이 알고리즘은 다음과 같이 동작합니다:
- 각 엔드포인트의 활성 요청 수(Active Requests)를 추적합니다.
- 요청을 보낼 때, 활성 요청이 가장 적은 엔드포인트를 선택합니다.
- Envoy의 Least Request 구현은 Power of Two Choices 기법을 사용합니다.
두 개의 엔드포인트를 무작위로 선택한 후, 활성 요청이 더 적은 엔드포인트를 선택합니다.
이 방식은 모든 엔드포인트를 스캔하는 것보다 효율적이며, 좋은 성능을 제공합니다. - 이러한 방식 덕분에 Least Connection은 지연이 있는 엔드포인트를 피하고, 더 빠르게 응답하는 엔드포인트로 요청을 보내 성능을 최적화합니다.
Least Connection은 활성 요청 수를 기반으로 요청을 분배해 지연이 있는 엔드포인트를 피하며,
Power of Two Choices로 효율성을 높입니다.
🛑 Fortio 서버 종료
- 테스트가 모두 완료되었으므로, Fortio 웹 UI를 더 이상 사용할 필요가 없습니다.
다음 명령어로 Fortio 서버를 종료합니다:
Ctrl-C
테스트 완료 후 Fortio 서버를 종료해 리소스를 정리합니다.
📌핵심 요약
- Round Robin, Random, Least Connection Load Balancing 알고리즘은 각기 다른 방식으로 요청을 분배합니다.
- Round Robin은 순차적으로, Random은 무작위로 요청을 보내지만, 엔드포인트의 런타임 상태를 고려하지 않아 지연이 있는 환경에서 비효율적입니다.
- 반면, Least Connection은 활성 요청 수를 추적해 가장 빠른 엔드포인트로 요청을 보내 성능을 최적화합니다.
- Envoy의 Power of Two Choices 기법은 효율성을 더욱 높여줍니다.
- 부하 테스트 결과, Least Connection이 중위 지연 시간에서 가장 나은 성능을 보였으며, 이는 실제 서비스 환경에서 안정성과 성능을 향상시키는 데 유용합니다.