API Priority and Fairness

개요

API Priority and Fairness는 kube-apiserver로 들어가는 요청에 섬세한 제한을 거는 기능이다.
크게 보면 rate limiting이지만, APF는 최대 요청 제한에 대한 설정을 더 세밀하게 할 수 있도록 지원하며
또한 공정하게 처리될 트래픽을 분배하는 큐 알고리즘을 도입하여 특정 요청이 계속 처리되지 못하는 상황을 방지한다.

APF는 watch 요청에 대해서만 적용된다는 점 참고하자.
exec이나 log와 같은 커넥션이 긴 다른 요청에 대해선 간섭하지 않는다.

APF는 --enable-priority-and-fairness 인자로 전달하여 설정하며 기본 활성화 상태이다.
또한 관련 리소스가 존재하며 현재 v1 상태이다.

재귀적 서버 시나리오

apf는 재귀 서버 시나리오에서 신중하게 쓰여야 한다.
가령 A에서 요청을 처리하며 B에 부가적 요청을 날린다고 쳐보자.
또 B에서는 요청을 처리하며 A에게 더 부가적인 요청을 날릴 수도 있다.
이럴 때 APF는 해당 모든 요청들에 적용되기에, 지나치게 전체 요청 처리에 제약을 야기할 수 있다.
다음의 경우가 대표적이다.

이럴 때는 후속 요청에 대해 더 중요도를 높게 매겨서 제한에 덜 걸리게 만드는 것도 하나의 방법이 된다.
아니면 재귀적인 요청이 오가는 서버에 대해서는 제한을 걸지 않는 것도 좋다.

개념

동시성, 중요도(Priority Level)

단위 시간 동안 서버가 동시에 처리할 수 있는 양(concurrency capacity)은 정해져 있다.
이 수용량은 api 서버 인자 --max-requests-inflight--max-mutating-requests-inflight를 통해 설정할 수 있다.
아무튼 문서에서는 동시성의 기본 단위를 seat이라 하는데, 이는 열차나 비행기에 전체 탑승 인원이 "좌석"을 기반으로 결정된다는 점에서 착안된 용어다.
예를 들면 100개의 자리가 있다면 한번에 서버는 100개의 요청을 처리할 수 있을 것이다.
물론 어떤 요청은 처리에 시간이 오래 걸리거나 많은 연산을 수행해야 하여 더 많은 자리를 차지할 수도 있다.
그래서 자리는 그저 동시성 수용량을 부분으로 쪼개 이해하기 위한 개념 정도로 생각하면 될 듯하다.

APF는 이 동시성 수용량을 쪼개 그룹 별로 할당하는 역할을 수행한다.
API 서버로 들어오는 요청의 속성 기반으로 분류한 뒤, 분류된 그룹에 따라 정책을 적용하는 방식으로 분류된 그룹을 Priority Level(중요도라 번역하겠다)이라 부른다.
중요도는 요청을 동시에 처리할 수 있는 공간을 나눠가지는 단위이기에, 다른 중요도에 속한 요청들은 서로의 자원을 뺏는 일이 발생하지 않는다.
그래서 파드에서 오는 요청이 많더라도 파드 스케줄링을 위한 kubelet의 요청에는 영향이 가지 않도록 세팅하는 것이 가능하다.

중요도 별 동시성 제한은 주기적으로 조정된다.
가령 활용도가 낮은 중요도 그룹의 동시성 수용량을 줄이고 부하가 큰 중요도 그룹의 수용량을 넓혀준다!
조정이 일어나는 범위에 대해서는 제한을 두거나 설정하는게 가능한데, 아래 리소스에서 자세히 보도록 한다.

watch 요청에 대한 실행 시간 조정

APF는 watch 요청에 대해서만 신경을 쓰는데, 위 동시성을 다루는 개념에서 watch 동작은 추가적인 고려사항을 동반한다.
하나의 watch 요청은 지속적이고, 또 처리하는 데이터의 개수도 다를 수 있는데 얼마나 자리를 선점해야 할까?
APF에서는 watch 요청 초기에 보내지는 많은 알림을 일단 한 자리로 간주한다.

근데 watch를 하게 되면 감시하고자 하는 리소스에 새로운 오브젝트가 생성, 삭제가 될 때마다 알림이 발생한다.
APF에서는 이러한 쓰기 작업으로 인해 알림이 발생하는 것도 카운팅하는데, 대신 쓰기 작업이 일어나는 것을 기준으로 보내야 하는 알림 개수와 자리 선점 시간을 추가적으로 자리로서 고려한다.

중요도가 다른 그룹 간에는 서로 경합이 일어나지 않지만, 중요도 내의 여러 요청은 자원을 나눠써야 하는 입장이다.
또한 한 중요도에 많은 요청이 몰리면 당연히 버려지는 요청도 생기게 될 것이다.
APF는 이에 대해 큐를 사용한다.
특히 공정한 큐 알고리즘을 사용해 중요도 내 여러 요청들이 공평하게 수행될 수 있도록 돕는다.
구체적으로는 셔플 샤딩(큐에 해싱 나머지 연산을 이용해 배치)을 사용하는데, 알고리즘은 중요도 별로 유형을 달리 할 수 있다.
이러한 튜닝을 통해 큐에서 메모리를 더 사용하도록 공간을 넓힐 수도 있고, 아예 큐를 두지 않는 것도 가능하다.

각 요청은 요청자, 대상 네임스페이스 등을 구분자로 매칭되는 flow schema로 식별되는 플로우을 하나씩 지정받는다.
같은 중요 레벨의 플로우들은 거의 같은 가중치를 부여한다.
한 플로우에서 요청을 분류하면 그 다음에 큐에 배치한다.

관련 리소스

위의 개념을 바탕으로 APF에서는 두 가지 리소스를 제공한다.

PriorityLevelConfiguration

이건 중요도 그룹을 지정하는 리소스로, 그룹 별 동시성 수용량, 큐 튜닝 등의 설정을 할 수 있다.
중요도 수치를 설정할 수도 있는데, 이건 전체 동시성 양에서 비율적으로 산정된다.
그래서 이를 명목 상(nominal)의 숫자라고도 표현한다.

다음은 큐 관련 설정이다.

FlowSchema

요청의 속성을 조건으로 중요도 그룹에 매핑하는 설정 리소스이다.

apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: FlowSchema
metadata:
  name: health-for-strangers
spec:
  matchingPrecedence: 1000
  priorityLevelConfiguration:
    name: exempt
  rules:
    - nonResourceRules:
      - nonResourceURLs:
          - "/healthz"
          - "/livez"
          - "/readyz"
        verbs:
          - "*"
      subjects:
        - kind: Group
          group:
            name: "system:unauthenticated"

ByUser - 다른 유저의 수용량을 뺏지 않음
ByNamespace - 네임스페이스별 수용량을 뺏지 않음
설정 안하면 그냥 설정 안된다.
그럼 모든 요청이 하나의 단일 플로우로 인식될 것이다.

기본 APF

api 서버에는 mandatory, suggested 두 유형으로 먼저 APF 기능이 들어가 있다.

mandatory

여기에는 2개의 중요도가 들어있다.

suggested

하위 문서

이름 is-folder index noteType created
컨트롤러 - - knowledge 2024-09-12
CRD - - knowledge 2024-09-14
API Aggregation Layer false - knowledge 2024-12-29
CNI true - knowledge 2025-01-08
kubeconfig false - knowledge 2025-01-13
설치 false - knowledge 2025-01-14
CRI true - knowledge 2025-02-24
CEL false - knowledge 2025-03-17
쿠버네티스 API 구조 false - knowledge 2025-03-19
오브젝트 true 0 knowledge 2024-12-23
코어 컴포넌트 true 0 knowledge 2025-03-19
클러스터 성능 최적화 false 13 knowledge 2025-08-30
API Priority and Fairness false 14 knowledge 2025-08-30

관련 문서

EXPLAIN - 파생 문서

이름0related생성 일자

Dataview: No results to show for table query.

기타 문서

Z0-연관 knowledge, Z1-트러블슈팅 Z2-디자인,설계, Z3-임시, Z5-프로젝트,아카이브, Z8,9-미분류,미완
이름0코드타입생성 일자

Dataview: No results to show for table query.

참고