목록으로

Programming Notes

Kubernetes v1.36: 쿠버네티스 PSI 메트릭 GA 정식 출시

2018년 리눅스 커널에 처음 구현된 이후, **PSI(Pressure Stall Information, 리소스 압박 정보)**는 사용자가 장애가 발생하기 전에 리소스 포화 상태를 식별하는 데 필요한 고정밀 신호를 제공해 왔습니다. 기존의 사용률(utilization) 메트릭과 달리, PSI는 작업이 지연된 상태와 손실된 시간을 CPU, 메모리, I/O 전반에 걸쳐 시간 백분율로 깔끔하게 정리하여 보여줍니다.

최근 출시된 Kubernetes v1.36을 통해 에코시스템 전반의 사용자들은 노드, 파드(Pod), 컨테이너 수준에서 리소스 경합을 관찰할 수 있는 안정적이고 신뢰할 수 있는 인터페이스를 갖게 되었습니다. 이 포스트에서는 이 기능이 프로덕션 환경에서 사용될 준비가 되었음을 입증한 개선 사항과 성능 테스트 결과를 자세히 살펴보겠습니다.

사용률 그 이상: 왜 PSI인가?

CPU나 메모리 사용량만 모니터링하는 것은 때로 오해를 불러일으킬 수 있습니다. 노드의 CPU 사용률이 100% 미만으로 보고되더라도, 특정 작업은 스케줄링 지연으로 인해 심각한 레이턴시를 겪고 있을 수 있습니다. PSI는 다음과 같은 정보를 제공하여 이러한 간극을 메워줍니다.

  • 누적 합계(Cumulative Totals): 지연(stalled) 상태에서 보낸 절대 시간.
  • 이동 평균(Moving Averages): 10초, 60초, 300초 창을 통해 운영자가 일시적인 급증과 지속적인 리소스 압박을 구분할 수 있게 합니다.

안정성 입증: 대규모 성능 테스트

텔레메트리(원격 측정) 기능이 정식 버전(GA)으로 승격될 때 흔히 우려하는 점은 메트릭 수집 및 제공에 필요한 리소스 오버헤드입니다. 이를 해결하기 위해 SIG Node는 다양한 머신 유형에서 고밀도 워크로드(80개 이상의 파드)를 대상으로 광범위한 성능 검증을 실시했습니다.

테스트는 각각 Kubelet과 커널 수준 수집의 영향을 분리하기 위해 두 가지 주요 시나리오에 집중했습니다.

  1. 커널 PSI ON / Kubelet 기능 OFF vs 커널 PSI ON / Kubelet 기능 ON (Kubelet 오버헤드)
  2. 커널 PSI OFF / Kubelet 기능 ON vs 커널 PSI ON / Kubelet 기능 ON (커널 오버헤드)

시나리오 1: Kubelet 오버헤드

먼저, 4코어 머신(Case 1)에서 Kubelet 사용량을 확인했습니다. 이 환경에서 리눅스 커널은 기본적으로(psi=1) 두 클러스터 모두에서 압박 정보를 추적하고 있었지만, KubeletPSI 기능 게이트를 전환하여 Kubelet이 이러한 메트릭을 능동적으로 쿼리하고 노출하는 것이 리소스 사용에 영향을 미치는지 확인했습니다. 그래프에 나타난 동기화된 버스트(burst)는 크기와 빈도 면에서 거의 동일하며, 이는 Kubelet의 수집 로직이 매우 가볍고 표준 관리 작업(housekeeping) 주기에 원활하게 통합됨을 확인시켜 줍니다. 이 기능이 기존 리소스 사용에 영향을 미치지 않으며, 일반적인 0.1 코어 또는 전체 노드 용량의 2.5% 내로 유지되므로 프로덕션 규모의 배포에 안전하다는 것을 입증합니다.

Kubelet PSI 기능이 꺼져 있을 때와 켜져 있을 때, 그리고 커널 PSI가 항상 켜져 있을 때의 Kubelet CPU 사용률을 비교하는 선 그래프

(Case 1) Kubelet CPU 사용률 비교

그림 2: Kubelet CPU 사용률 비교.

다음으로 동일한 실행에서 시스템 오버헤드를 평가했습니다. 아래 그래프에서 볼 수 있듯이, Kubelet PSI가 활성화된 경우(빨간색)의 시스템 CPU 사용량 라인은 비활성화된 경우(파란색)와 동일한 패턴을 따르며 베이스라인에서 예상되는 수준의 미미한 증가만 보입니다. 이는 OS가 PSI를 추적하고 있는 상태(약 2.5 코어 사용 시점)에서 쿠버네티스가 해당 cgroup 메트릭을 읽는 행위가 성능에 미치는 영향이 무시할 수 있는 수준임을 보여줍니다.

PSI 기능이 꺼져 있을 때와 켜져 있을 때, 그리고 커널 PSI가 기본적으로 ON일 때의 시스템 CPU 사용률을 비교하는 선 그래프

(Case 1) 시스템 CPU 사용률 비교

그림 1: 노드 시스템 CPU 사용률 비교.

시나리오 2: 커널 오버헤드

다음으로, 리눅스 커널에서 PSI를 활성화할 때 발생하는 근본적인 오버헤드를 4코어 머신에서 평가했습니다. psi=1(COS 기본값)로 부팅된 클러스터와 psi=0인 클러스터를 비교하여 OS 수준 기록 유지의 정확한 비용을 분리했습니다. 80개 파드 밀도의 과중한 I/O 및 CPU 부하 상태에서도 커널 활성화 클러스터와 비활성화 클러스터 간의 시스템 CPU 차이는 일관되게 0.037 코어에서 0.125 코어, 즉 전체 노드 용량의 0.925% - 3.125% 사이를 유지했습니다. 단 한 번 **0.225 코어(5.6%)**까지 급증했으나 몇 초 내에 다시 제어되었습니다. 이는 내부 커널 추적이 부하 상태에서도 매우 효율적임을 확인해 줍니다.

시간 경과에 따른 커널 PSI ON 및 OFF 상태에서의 노드 시스템(커널) CPU 사용률 비교 선 그래프

(Case 2) 노드 시스템 CPU 사용률 비교

그림 3: 노드 시스템 CPU 사용률 비교.

그림 4는 이러한 메트릭의 주요 수집기 역할을 하는 Kubelet 프로세스 자체를 확대한 것입니다. 결과에 따르면 Kubelet이 cgroup 계층 구조에서 데이터를 집계하기 위해 주기적인 *스윕(sweep)*을 수행하는 동안에도 CPU 사용량은 눈에 띄게 낮게 유지되었으며, 급증 지점은 서로 겹치고 1초 이상 **0.25 코어(전체 용량의 6.25%)**를 초과하는 경우는 없었습니다.

시간 경과에 따른 커널 PSI 기능이 꺼져 있을 때와 켜져 있을 때의 Kubelet CPU 사용률 비교 선 그래프

(Case 2) Kubelet CPU 사용률 비교

그림 4: Kubelet CPU 사용률 비교.

베타(1.34)와 스테이블(1.36) 사이의 개선 사항

  • GA를 위한 더 지능적인 메트릭 출력: Kubelet이 PSI에 대한 기본 OS 지원을 처리하는 방식이 개선되었습니다. 이전에는 쿠버네티스에서 기능이 활성화되어 있어도 기본 리눅스 커널이 PSI를 지원하지 않으면(psi=0), Kubelet이 오해의 소지가 있는 0 값 메트릭을 출력했습니다. 이는 누락된 값이 아닌 실제 메트릭으로 읽힐 때 잘못된 알람을 유발할 수 있었습니다. v1.36에서 Kubelet은 이제 보고하기 전에 cgroup 구성을 통해 OS 수준의 PSI 지원 여부를 감지합니다. 이를 통해 노드에서 실제로 지원될 때만 압박 메트릭이 수집되고 출력되도록 보장하며, 모니터링 및 알림 시스템에 더 깨끗한 데이터를 제공합니다.

시작하기

쿠버네티스 클러스터에서 PSI 메트릭을 사용하려면 노드가 다음 요구 사항을 충족해야 합니다.

  1. 노드가 리눅스 커널 버전 4.20 이상을 실행 중이고 cgroup v2를 사용하고 있어야 합니다.
  2. OS 수준에서 PSI가 활성화되어 있어야 합니다 (커널이 CONFIG_PSI=y로 컴파일되어야 하며 psi=0 파라미터로 부팅되지 않아야 함).

v1.36부터 Kubelet PSI 메트릭은 정식 버전(GA)으로 제공되며, 별도의 기능 게이트를 활성화할 필요가 없습니다.

OS 전제 조건이 충족되면 프로메테우스 호환 모니터링 솔루션으로 /metrics/cadvisor 엔드포인트를 스크레이핑하거나 Summary API를 쿼리하여 새로운 PSI 메트릭을 수집하고 시각화할 수 있습니다. PSI는 리눅스 커널 기능이므로 윈도우 노드에서는 이러한 메트릭을 사용할 수 없다는 점에 유의하세요. 클러스터에 리눅스와 윈도우 노드가 혼합되어 있을 수 있으며, 윈도우 노드에서는 Kubelet이 PSI 메트릭을 단순히 생략합니다.

최신 버전의 쿠버네티스를 실행 중이고 권한이 있는 노드 관리자라면, 컨트롤 플레인의 API 서버를 통해 Kubelet의 HTTP API로 프록시하여 Summary API에서 실시간 압박 데이터를 확인할 수 있습니다.

주의: Kubelet으로 프록시하는 것은 권한이 필요한 작업입니다. 이에 대한 액세스 권한을 부여하는 것은 보안 위험이 따르므로, 아래 명령을 실행하기 전에 적절한 관리 권한이 있는지 확인하십시오.

CONTAINER_NAME="example-container"
kubectl get --raw "/api/v1/nodes/$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')/proxy/stats/summary" | jq '.pods[].containers[] | select(.name=="'"$CONTAINER_NAME"'") | {name, cpu: .cpu.psi, memory: .memory.psi, io: .io.psi}'

더 읽어보기

이러한 메트릭이 어떻게 계산되고 노출되는지 더 자세히 알고 싶다면 다음 리소스를 확인하세요.

  1. 공식 커널 문서
  2. 쿠버네티스 문서의 PSI 이해하기
  3. cAdvisor 메트릭 구현

감사의 말

PSI 메트릭 지원은 SIG Node의 협력적인 노력을 통해 개발되었습니다. v1.33의 알파, v1.34의 베타를 거쳐 v1.36의 GA에 이르기까지 이 기능의 설계, 구현, 테스트, 리뷰 및 문서화를 도와주신 모든 기여자분께 특별히 감사드립니다.

이 기능에 대한 피드백을 제공하려면 Kubernetes Node Special Interest Group에 참여하거나, 공식 슬랙 채널(#sig-node) 토론에 참여하거나, GitHub에 이슈를 제출해 주세요.

피드백

피드백이 있거나 이 기능을 사용한 경험을 공유하고 싶다면 다음 논의에 참여해 주세요.

SIG Node는 프로덕션 환경에서 이 기능을 사용해 본 여러분의 경험담을 듣고 싶습니다!