본문 바로가기
IT/k8s

[인프라] Knative 성능 벤치마크, 실제 트래픽 증가에 따른 서빙 체크 포인트

by 수누다 2026. 6. 27.

[인프라] Knative 성능 벤치마크, 실제 트래픽 증가에 따른 서빙 체크 포인트

Knative 성능 벤치마크를 직접 해보려는 분들은 대개 비슷한 고민을 하더라고요. 평소엔 조용한 서비스인데, 특정 시간에 요청이 몰리면 Knative Serving이 어디까지 버텨주는지, 그리고 서버리스(Serverless)의 자동 확장이 정말 실전에 맞게 움직이는지 확인하고 싶은 거죠. 저도 홈랩에서 처음 테스트했을 때는 "오토스케일링이 알아서 되겠지" 하고 가볍게 봤다가, 콜드 스타트와 동시성 때문에 삽질 좀 했습니다 ㅎㅎ

특히 운영 입장에서 중요한 건 숫자 하나가 아니라 트래픽 증가 구간에서 어떤 컴포넌트가 먼저 흔들리는지를 아는 겁니다. CPU가 먼저 차는지, Activator가 병목이 되는지, Ingress 레이어에서 지연이 생기는지 봐야 하거든요. 이번 글에서는 제가 실제로 자주 쓰는 방식대로, 과장된 수치 없이 Knative 성능 벤치마크를 어떻게 설계하고 해석하면 되는지 정리해보겠습니다.

Knative 성능 벤치마크를 위한 Knative Serving 아키텍처와 트래픽 흐름 다이어그램

Knative Serving의 요청 흐름과 오토스케일링 관련 컴포넌트를 한눈에 보는 구성도입니다.

1. 왜 Knative Serving 성능 테스트가 까다로운가

쉽게 말해 Knative는 단순한 Deployment 하나를 때리는 구조가 아닙니다. 요청은 보통 Route, Revision, Queue-Proxy, 그리고 상황에 따라 Activator를 거치게 됩니다. 그래서 같은 애플리케이션 코드를 올려도 일반 Kubernetes Deployment와 응답 패턴이 꽤 다르게 나옵니다.

  • Scale to Zero: 유휴 상태에선 파드를 0으로 줄였다가 다시 띄웁니다.
  • Concurrency 기반 확장: CPU만 보는 게 아니라 요청 동시성도 핵심 기준입니다.
  • Revision 단위 배포: 새 설정이 들어가면 새 리비전이 생기므로 비교 테스트가 편합니다.
  • 네트워크 경로 증가: 인그레스와 프록시 홉이 늘어나면 지연 해석이 달라집니다.

여기서 중요한 포인트! Knative 성능 벤치마크는 "최대 RPS가 얼마냐"만 보는 테스트가 아닙니다. 트래픽이 늘어날 때 응답 시간이 어떻게 변하는지, 그리고 자동 확장이 몇 초 안에 따라붙는지를 함께 봐야 의미가 있습니다.

2. 벤치마크 전에 잡아야 할 기준

제가 직접 해보니, 테스트 전에 기준을 안 잡으면 결과가 거의 쓸모가 없더라고요. 처음엔 저도 그냥 부하 도구부터 돌렸었는데, 나중에 보니까 어떤 값이 애플리케이션 때문인지, 어떤 값이 플랫폼 때문인지 분리가 안 되더라고요.

2-1. 최소한 이 네 가지는 고정하세요

  1. 애플리케이션 응답 형태: CPU 바운드인지, I/O 바운드인지 구분합니다.
  2. 동시성 목표: containerConcurrency를 명시할지 결정합니다.
  3. 오토스케일 기준: target concurrency, min/max scale 범위를 정합니다.
  4. 측정 구간: 콜드 스타트 포함 여부와 워밍 상태를 분리합니다.

실무에서는 보통 두 번 봅니다. 한 번은 콜드 스타트 포함 시나리오, 한 번은 이미 파드가 떠 있는 상태죠. 이 둘을 섞으면 해석이 틀어집니다.

2-2. 어떤 지표를 보면 되나

지표 왜 중요한가 해석 팁
RPS/Throughput 전체 처리량 확인 상승하다가 평평해지면 병목 가능성이 큽니다.
P95, P99 Latency 꼬리 지연 확인 평균보다 훨씬 중요할 때가 많습니다.
Pod Count 확장 반응 확인 요청 증가와 함께 자연스럽게 늘어나는지 봅니다.
Error Rate 품질 저하 감지 5xx가 생기면 네트워크/백엔드 구간을 같이 확인합니다.

3. 실전용 테스트 환경 구성

이 글에서는 가장 단순한 HTTP echo 계열 서비스 대신, 약간의 대기 시간을 줄 수 있는 애플리케이션을 두고 확인하는 방식을 권장합니다. 이유는 간단합니다. 너무 가벼운 앱은 네트워크 오버헤드만 보이고, 너무 무거운 앱은 앱 병목만 보여서 Knative 특성이 잘 안 드러나거든요.

아래 예시는 Knative Service 리소스입니다. 실제 테스트에선 여러분이 보유한 검증된 컨테이너 이미지를 넣으시면 됩니다.

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: benchmark-app
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/min-scale: "0"
        autoscaling.knative.dev/max-scale: "10"
        autoscaling.knative.dev/target: "10"
    spec:
      containerConcurrency: 10
      containers:
        - image: gcr.io/knative-samples/helloworld-go:latest
          ports:
            - containerPort: 8080
          env:
            - name: TARGET
              value: "knative-benchmark"

배포는 일반적인 kubectl 흐름으로 진행하면 됩니다.

kubectl apply -f knative-service.yaml
kubectl get ksvc benchmark-app
kubectl get revision
kubectl get pods -w

테스트 전에는 라우트 URL을 먼저 확인해 두세요.

kubectl get ksvc benchmark-app -o jsonpath='{.status.url}'
Knative 성능 벤치마크 설정에서 오토스케일링 파라미터를 설명하는 구성 이미지

서비스 정의에서 동시성, 최소/최대 스케일, 타깃 값을 어떻게 잡는지 보여주는 이미지입니다.

4. 트래픽 증가 시나리오를 이렇게 나누면 해석이 쉬워집니다

제가 실제로 써보니까 한 번에 큰 부하를 주는 것보다, 단계형(step load)으로 올리는 편이 훨씬 유용했습니다. 트래픽 증가 구간에서 어느 시점부터 지연이 튀는지 보여주기 좋거든요.

  1. 기본 응답 확인: 단일 요청으로 정상 동작과 헤더를 확인합니다.
  2. 저부하 구간: 낮은 동시성으로 워밍 상태 지연을 봅니다.
  3. 중간 부하 구간: 오토스케일이 개입하기 시작하는지 봅니다.
  4. 고부하 구간: P95/P99 지연과 에러율 변화를 봅니다.
  5. 유휴 복귀: 다시 요청을 끊고 scale to zero 동작을 확인합니다.

간단한 부하 테스트는 hey 같은 도구로도 충분합니다. 특별히 복잡한 시나리오가 아니라면 시작은 이걸로 해보세요.

URL=$(kubectl get ksvc benchmark-app -o jsonpath='{.status.url}')
hey -z 30s -c 10 "$URL"
hey -z 30s -c 30 "$URL"
hey -z 30s -c 50 "$URL"

좀 더 긴 시나리오를 만들고 싶다면 k6 같은 도구를 쓰는 것도 좋습니다. 아래는 단계적으로 가상 사용자 수를 올리는 예시입니다.

import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 5 },
    { duration: '30s', target: 20 },
    { duration: '30s', target: 50 },
    { duration: '30s', target: 0 }
  ]
};

export default function () {
  http.get(__ENV.TARGET_URL);
  sleep(1);
}
k6 run -e TARGET_URL="$URL" load-test.js

여기서 핵심은 숫자를 크게 만드는 게 아닙니다. 같은 서비스 정의로 트래픽 증가 패턴을 반복 가능하게 재현하는 게 훨씬 더 중요합니다.

5. ⚠️ 제가 자주 겪었던 문제와 해결 방법

이 부분이 사실 제일 중요합니다. 테스트는 돌렸는데 결과가 이상하게 튀는 경우가 많거든요. 저도 처음엔 앱 코드 문제인 줄 알았는데, 실제로는 Knative 레이어나 클러스터 리소스 설정이 원인이었던 적이 꽤 있었습니다.

5-1. 콜드 스타트와 워밍 테스트를 섞어버린 경우

가장 흔한 실수입니다. 첫 요청 지연이 큰데 그걸 전체 성능 저하로 오해하는 거죠. 해결은 단순합니다.

  • 콜드 스타트 측정은 유휴 상태 이후 첫 요청만 따로 봅니다.
  • 워밍 성능은 미리 몇 번 호출한 뒤 별도 구간에서 측정합니다.
  • Knative 성능 벤치마크 결과표도 두 항목으로 나누는 편이 좋습니다.

5-2. containerConcurrency를 기본값에만 맡긴 경우

애플리케이션이 요청당 메모리를 많이 쓰거나, 반대로 가벼운 API인데 너무 보수적으로 잡혀 있으면 확장 패턴이 왜곡됩니다. 특히 Queue-Proxy를 거치는 구조에서는 동시성 설정이 생각보다 체감에 크게 들어옵니다.

5-3. 클러스터 노드 자원이 먼저 부족한 경우

이건 홈랩에서 진짜 자주 나옵니다. Knative가 못 버틴 게 아니라, 노드가 새 파드를 올릴 여유가 없는 겁니다. CPU 요청량(requests)과 제한(limits), 이미지 풀링 시간, 스토리지 성능을 같이 봐야 합니다.

5-4. Ingress 레이어의 영향

Ingress 설정에 따라 지연 차이가 보일 수 있습니다. 그래서 가능하면 애플리케이션 로그만 보지 말고, 인그레스 컨트롤러와 Knative 관련 컨트롤 플레인 상태도 같이 체크하세요.

kubectl get pods -A
kubectl top pods -A
kubectl describe ksvc benchmark-app
kubectl logs -l serving.knative.dev/service=benchmark-app --all-containers=true
Knative 성능 벤치마크 결과에서 파드 수 증가와 지연 시간 변화를 보는 대시보드 이미지

트래픽 상승에 따라 파드 수와 지연 시간이 어떻게 변하는지 같이 보는 대시보드 예시입니다.

6. 결과는 어떻게 읽어야 하나

벤치마크 결과를 볼 때 제가 제일 먼저 보는 건 평균이 아니라 P95/P99 Latency입니다. 평균은 멀쩡한데 꼬리 지연만 확 튀는 경우가 꽤 많거든요. 사용자는 그 느린 요청을 체감합니다.

보통 해석은 이렇게 가져가면 됩니다.

관찰 현상 의심 지점 다음 액션
RPS는 유지되는데 P95만 상승 오토스케일 반응 지연 또는 큐잉 증가 target concurrency와 min scale 검토
고부하에서 5xx 발생 앱 리소스 부족, 인그레스, 백엔드 의존성 애플리케이션 로그와 노드 상태 확인
첫 요청만 매우 느림 콜드 스타트 scale to zero 정책과 워밍 전략 분리 검토
파드 수가 기대보다 안 늘어남 오토스케일 설정 또는 클러스터 자원 한계 autoscaler 설정과 스케줄링 상태 확인

제가 직접 해보니 좋은 결과란 "숫자가 무조건 높은 상태"가 아니라, 트래픽 증가에 따라 파드 수와 지연이 예측 가능하게 움직이는 상태더라고요. 운영은 재현성과 설명 가능성이 정말 중요하거든요.

7. 검증 체크리스트와 운영 관점 팁

실전 반영 전에 아래 체크리스트를 한 번 돌려보시면 좋습니다. 여기서 중요한 포인트! Knative 성능 벤치마크는 한 번 하고 끝내는 문서가 아니라, 리비전이 바뀔 때마다 비교 기준으로 남겨야 합니다.

  • ✅ 동일한 이미지와 동일한 요청 패턴으로 반복 테스트했는가
  • ✅ 콜드 스타트와 워밍 상태를 분리했는가
  • ✅ P95/P99, 에러율, 파드 수를 함께 기록했는가
  • ✅ 노드 자원 부족과 애플리케이션 병목을 구분했는가
  • ✅ Revision 단위로 결과를 보관했는가

추가로, 이전 글에서 다뤘던 Kubernetes 리소스 요청량 설계와 함께 보시면 훨씬 이해가 빠릅니다. 다음 글에서는 Knative Serving에서 min scale과 scale to zero를 운영 비용 관점에서 어떻게 조정하는지 이어서 다뤄볼 예정입니다.

8. 자주 묻는 질문

Q1. 부하 도구는 무엇을 써야 하나요?

가볍게 시작할 땐 hey면 충분합니다. 요청 패턴을 더 세밀하게 만들고 싶으면 k6가 편하더라고요.

Q2. Scale to Zero는 벤치마크에서 꺼야 하나요?

목적에 따라 다릅니다. 운영 현실을 보고 싶다면 켠 상태도 꼭 측정해야 합니다. 다만 워밍 성능과 섞지는 마세요.

Q3. 수치가 환경마다 너무 다르게 나오는데 정상인가요?

네, 정상입니다. 클러스터 크기, 네트워크, 인그레스 종류, 이미지 크기, 앱 특성이 모두 영향을 줍니다. 그래서 절대값보다 비교 기준이 중요합니다.

Knative 성능 벤치마크 결과 해석 체크리스트와 비교 요약 인포그래픽

콜드 스타트, 워밍 성능, 파드 확장, 지연 구간을 한 번에 정리한 요약 인포그래픽입니다.

9. 마무리

이번 글에서는 실전 기준으로 Knative 성능 벤치마크를 어떻게 설계하고, 트래픽 증가 상황에서 무엇을 봐야 하는지 정리해봤습니다. 처음엔 저도 "오토스케일이 되니까 그냥 잘 되겠지" 싶었는데, 실제로 써보니까 동시성 설정, 콜드 스타트 분리, 인그레스 영향, 클러스터 자원 상태를 같이 봐야 결과가 말이 되더라고요.

결국 중요한 건 화려한 숫자보다 반복 가능한 테스트 절차입니다. 여러분 환경에서도 먼저 작은 단계형 테스트부터 시작해 보세요. 드디어 됐다! 싶은 순간이 오면, 그다음엔 리비전 비교와 비용 최적화까지 연결하시면 됩니다. 운영 관점에서 보면 이 흐름이 제일 오래 갑니다. 혹시 비슷한 삽질 하신 적 있으신가요? 그런 경험이 오히려 제일 좋은 기준이 되더라고요.