API Rate Limiting

API Rate Limiting

Cilium 에이전트 API 호출의 빈도 제한(rate limiting)이 어떻게 동작하는지 설명할게요. 리소스 소비를 제어하기 위해 API 호출의 속도와 병렬 실행 수를 조절하는 방법을 알아봐요.

출처: API Rate Limiting

본문

노드별 Cilium 에이전트는 본질적으로 이벤트 기반(event-driven)으로 동작해요. 예를 들어, 새 워크로드가 노드에 스케줄링되면 CNI 플러그인이 호출되고, 그에 따라 IP 주소를 할당하고 Cilium 엔드포인트를 만들기 위해 Cilium 에이전트에 API 호출을 하게 돼요. 또 다른 예는 네트워크 정책이나 서비스 정의의 로딩인데, 이러한 정의가 변경되면 이벤트가 생성되어 Cilium 에이전트에 수정이 필요함을 알려줘요.

이벤트 기반이기 때문에 Cilium 에이전트가 수행하는 작업량은 수신하는 외부 이벤트의 속도에 크게 의존해요. Cilium 에이전트가 소비하는 리소스를 제한하려면 API 호출의 속도와 허용되는 병렬 실행 수를 제한하는 것이 도움이 될 수 있어요.

기본 빈도 제한 (Default Rate Limits)

현재 다음 API 호출이 빈도 제한의 대상이에요.

API Call Limit Burst Max Parallel Min Parallel Max Wait Duration Auto Adjust Estimated Processing Duration
PUT /endpoint/{id} 0.5/s 4 4 15s True 2s
DELETE /endpoint/{id} 4 4 True 200ms
GET /endpoint/{id}/* 4/s 4 4 2 10s True 200ms
PATCH /endpoint/{id}* 0.5/s 4 4 15s True 1s
GET /endpoint 1/s 4 2 2 True 300ms

구성 (Configuration)

api-rate-limit 옵션을 사용해 기본 구성의 개별 설정을 덮어쓸 수 있어요.

--api-rate-limit endpoint-create=rate-limit:2/s,rate-burst:4

API 호출과 구성 매핑

API Call Config Name
PUT /endpoint/{id} endpoint-create
DELETE /endpoint/{id} endpoint-delete
GET /endpoint/{id}/* endpoint-get
PATCH /endpoint/{id}* endpoint-patch
GET /endpoint endpoint-list

구성 파라미터

Configuration Key Example Default Description
rate-limit 5/m None 시간 단위당 허용되는 요청 수. 형식은 <number>/<duration>.
rate-burst 4 None rate limiter가 허용하는 API 요청의 버스트.
min-wait-duration 10ms 0 각 API 호출이 처리되기 전에 대기해야 하는 최소 대기 시간.
max-wait-duration 15s 0 API 호출이 실패하기 전에 대기할 수 있는 최대 시간.
estimated-processing-duration 100ms 0 평균 API 호출의 예상 처리 시간. 자동 조정에 사용됨.
auto-adjust true false rate-limit, rate-burst, parallel-requests의 자동 조정 활성화.
parallel-requests 4 0 허용되는 병렬 API 호출 수.
min-parallel-requests 2 0 자동 조정 시 병렬 요청의 하한.
max-parallel-requests 6 0 자동 조정 시 병렬 요청의 상한.
mean-over 10 10 자동 조정을 위한 평균 처리 시간 계산에 사용되는 API 호출 수.
log true false 처리된 각 API 호출에 대해 Info 메시지를 기록.
delayed-adjustment-factor 0.25 0.5 rate-burst와 parallel-requests의 느린 조정을 위한 계수.
max-adjustment-factor 10.0 100.0 자동 조정된 값이 구성된 초기 기본 값에서 벗어날 수 있는 최대 배수.

유효한 시간 단위 값 (Valid duration values)

rate-limit 옵션은 <number>/<duration> 형식의 값을 기대하며, 여기서 <duration>은 ParseDuration()으로 파싱할 수 있는 값이에요. 지원되는 단위는 ns, us, ms, s, m, h예요.

예시:

  • rate-limit:10/2m

  • rate-limit:3.5/h

  • rate-limit:1/100ms

자동 조정 (Automatic Adjustment)

정적 값은 Cilium 에이전트가 다양한 머신 유형에서 실행되기 때문에 상대적으로 쓸모없어요. 사용 가능한 CPU 코어 수나 메모리를 기반으로 빈도 제한을 도출하는 것도, Cilium 에이전트가 CPU와 메모리 제약을 받을 수 있기 때문에 오해를 부를 수 있어요.

그래서 모든 API 호출 빈도 제한은, 구성된 예상 처리 시간에 최대한 근접하게 유지하는 것을 목표로 한도가 자동 조정돼요. 이 처리 시간은 각 API 호출 그룹에 대해 지정되고 지속적으로 모니터링돼요.

각 API 호출이 완료될 때마다 새 한도가 계산돼요. 이를 위해 조정 계수(adjustment factor)가 계산돼요.

AdjustmentFactor := EstimatedProcessingDuration / MeanProcessingDuration
AdjustmentFactor = Min(Max(AdjustmentFactor, 1.0/MaxAdjustmentFactor), MaxAdjustmentFactor)

이 조정 계수는 rate-limit, rate-burst, parallel-requests에 적용되며, 평균 처리 시간이 예상 처리 시간에 더 가까워지도록 유도해요.

delayed-adjustment-factor가 지정되면, 이 추가 계수는 rate-burst와 parallel-requests의 증가를 늦추는 데 사용돼요. 두 값 모두 일반적으로 rate-limit보다 느리게 조정돼야 하기 때문이에요.

NewValue = OldValue * AdjustmentFactor
NewValue = OldValue + ((NewValue - OldValue) * DelayedAdjustmentFactor)

메트릭 (Metrics)

빈도 제한 대상인 모든 API 호출은 API Rate Limiting 메트릭을 노출해요. 예시:

cilium_api_limiter_adjustment_factor                  api_call="endpoint-create"                                                0.695787
cilium_api_limiter_processed_requests_total           api_call="endpoint-create" outcome="success" return_code="200"            7.000000
cilium_api_limiter_processing_duration_seconds        api_call="endpoint-create" value="estimated"                              2.000000
cilium_api_limiter_processing_duration_seconds        api_call="endpoint-create" value="mean"                                   2.874443
cilium_api_limiter_rate_limit                         api_call="endpoint-create" value="burst"                                  4.000000
cilium_api_limiter_rate_limit                         api_call="endpoint-create" value="limit"                                  0.347894
cilium_api_limiter_requests_in_flight                 api_call="endpoint-create" value="in-flight"                              0.000000
cilium_api_limiter_requests_in_flight                 api_call="endpoint-create" value="limit"                                  0.000000
cilium_api_limiter_wait_duration_seconds              api_call="endpoint-create" value="max"                                    15.000000
cilium_api_limiter_wait_duration_seconds              api_call="endpoint-create" value="mean"                                   0.000000
cilium_api_limiter_wait_duration_seconds              api_call="endpoint-create" value="min"                                    0.000000

로그 출력 이해하기 (Understanding the log output)

API rate limiter는 rate 서브시스템 아래에 로그를 남겨요. 예시 메시지는 아래에서 볼 수 있어요.

level=info msg="API call has been processed" name=endpoint-create processingDuration=772.847247ms subsys=rate totalDuration=14.923958916s uuid=d34a2e1f-1ac9-11eb-8663-42010a8a0fe1 waitDurationTotal=14.151023084s

모든 API rate limiting 메시지에 대한 설명은 다음과 같아요.

"Processing API request with rate limiter"

요청이 rate limiter에 접수됐다는 뜻이에요. 연관된 HTTP 컨텍스트(호출자의 요청)는 아직 타임아웃되지 않았어요. 요청은 이제 rate limiter의 구성에 따라 빈도 제한될 거예요. 계산된 대기 시간에 따라 대기 단계로 들어가요.

"API request released by rate limiter"

요청이 빈도 제한을 달성하기 위해 계산된 대기 시간을 모두 마쳤다는 뜻이에요. 이제 실제 HTTP API 동작이 일어나요. 즉, 이 요청은 429 HTTP 상태 코드로 호출자에게 되돌려지지 않았어요.

요청이 rate limiter의 구성된 범위 내에서 처리될 때 흔히 나타나는 메시지예요.

"API call has been processed":

API rate limiter가 요청을 처리했고 실제 HTTP API 동작이 끝났다는 뜻이에요. 요청이 더 이상 적극적으로 대기 중이거나, 다시 말해 더 이상 빈도 제한되지 않는다는 뜻이에요. 이것은 실제 HTTP 동작이 성공했음을 의미하는 게 아니라, 단지 이 요청이 처리됐다는 것만을 뜻해요.

"Not processing API request due to cancelled context"

기본 HTTP 컨텍스트(요청)가 취소됐다는 뜻이에요. 즉, 호출자가 요청을 포기했어요. 대부분 HTTP 요청이 타임아웃됐음을 의미해요. 호출자에게 429 HTTP 응답 상태 코드가 반환되며, 호출자가 이를 받을 수도 있고 못 받을 수도 있어요.

"Not processing API request. Wait duration for maximum parallel requests exceeds maximum"

이미 너무 많은 병렬 요청이 진행 중이어서 rate limiter가 요청을 거부했다는 뜻이에요. 호출자는 429 HTTP 상태 응답을 받게 돼요.

한 번에 너무 많은 병렬 요청을 막는 rate limiter의 역할이 수행될 때 흔히 나타나는 메시지예요.

"Not processing API request. Wait duration exceeds maximum"

요청의 대기 시간이 구성된 최대 대기 시간을 초과할 것이므로 rate limiter가 요청을 거부했다는 뜻이에요. 예를 들어 최대 대기 시간이 5s인데 rate limiter의 백로그 때문에 이 요청이 10s를 기다려야 한다면, 이 요청은 버려져요. 호출자에게 429 HTTP 응답 상태 코드가 반환돼요.

rate limiter가 들어오는 요청을 Cilium으로 보내는 속도를 조절하는 역할을 수행할 때 가장 흔히 나타나는 메시지예요.

"Not processing API request due to cancelled context while waiting"

요청이 계산된 대기 시간을 기다린 후 연관된 컨텍스트가 취소됐기 때문에 rate limiter가 요청을 거부했다는 뜻이에요. 대부분은 요청이 rate limiter에 의해 적극적으로 지연되는 동안 HTTP 타임아웃이 발생했다는 의미예요. 호출자에게 429 HTTP 응답 상태 코드가 반환돼요.

더 알아보기 (Learn more)