Skip to Content
Infra & DevOpsK8s CPU Quota Throttling 커널 패치
☁️ Infra & DevOps2019년 11월 21일

K8s CPU Quota Throttling 커널 패치

#kubernetes#infra-devops#cpu-throttling#kernel#kubecon

1. 자원은 남는데 CPU가 멱살 잡히는 현상

프로덕션 수준 K8s 클러스터에서 자바 애플리케이션(Spring Boot) 파드들을 운영할 때 가장 미스터리한 불만 사항 하나가 있었습니다. 분명히 “전체 파드의 CPU 사용량이 제한치(Limits)의 절반에도 못 미쳤는데 지연 시간(Latency)이 튀고 렉이 걸린다”는 것입니다.

당시 모니터링 시스템(Prometheus) 로그를 보면 메트릭 리소스 지표 자체는 매우 널널했습니다. 그러나 실제 패킷 레이턴시는 늘어지고 있었고, 원인을 알 수 없는 ‘CPU Throttling(자원 쓰로틀링)’ 현상이 KubeCon 글로벌 세션 화두 중 하나로 떠올랐습니다.

2. CFS(Completely Fair Scheduler) 버그 개념 및 원인 파악

쿠버네티스의 노드 환경은 Linux Cgroup V1의 CFS(Completely Fair Scheduler)를 기반으로 파드의 CPU Limit(Quota) 기능을 제어합니다. 그런데 이 리눅스 커널의 CFS 스케줄러 자체에 충격적인 결함(Bug)이 숨어 있었습니다. 멀티 코어(Multi-Core) 노드에서 CPU Quota 제한 값이 설정된 프로세스가 스레딩(Threading)을 처리할 때, 설정된 Quota 값에 도달하지 않았음에도 불구하고 선제적으로 쓰로틀링을 걸어버려 프로세스가 자원을 할당받지 못해 굶는(Starvation) 이슈가 발생한 것입니다. CPU를 아무리 넉넉하게 예약해 줬어도, 단기간 스레드를 폭발시키는 자바(JVM) 앱 같은 특성상 커널 스케줄러가 엄격한 버그 로직으로 쓰로틀링을 남발해 버리는 구조적 결함이었습니다.

3. 리눅스 커널 패치 적용 및 우회 방법 및 대응

해당 이슈는 인프라 매니페스트 단에서 고칠 수 없는 OS 레벨의 Kernel Scheduler Issue이기에 무조건 Kernel Patch(업그레이드)가 유일한 근본 해결책이었습니다.

1. 근본 해결: OS 커널 패치 버전 적용

패치 픽스가 백포팅되어 적용된 각 벤더별 최소 커널(Kernel) 릴리즈 버전은 다음과 같습니다.

  • Main-line: 버그 픽스 완전 반영 5.4 이상
  • Linux-stable: 4.14.154+, 4.19.84+, 5.3.9+
  • Distro Kernel (Ubuntu): 5.3.0-24+, 4.15.0-67+
  • Distro Kernel (RHEL 7): kernel-3.10.0-1062.8.1.el

2. 임시 회피책 (Workaround)

프로덕션 레벨에서 커널을 즉각 함부로 올릴 수 없다면, 두 가지 슬픈 임시 방편을 써야 합니다.

  • Limit 삭제 방안: 아예 K8s Deployment에서 컨테이너의 CPU Limit 자체를 서술하지 않는다. (Guaranteed 등급의 우대 포기 및 클러스터 오버커밋 허용이라는 치명적인 아키텍처 손실 발생)
  • Quota를 무한정 높게 잡는 방안: Limit을 앱이 원래 쓰는 것의 3~4배 이상으로 비현실적으로 크게 잡아 CFS 발동 조건 자체를 우회.

4. 성능 복구 완료 및 회고

인프라에 떠다니는 클라우드 솔루션도, 화려한 오케스트레이션 툴(K8s)도 결국 그 근본적인 한계 상황에 도달하면 밑단의 무거운 리눅스 OS(Kernel Cgroup 버그 등)의 파도 속에 휩쓸릴 수밖에 없음을 뼈저리게 느낀 일화였습니다. 성능 모니터링을 전공하는 조직의 입장에서도 APM 지표의 단순 % 만을 믿어서는 안 되며, 리눅스 시스템 층위의 cfs_quota_us 이벤트까지 딥-다이빙할 수 있는 역량이 필수불가결하다는 교훈을 남겼습니다.

(당시 KubeCon 2019 및 커뮤니티 토론 로그)

Last updated on