목록으로

Programming Notes

cgroup v1 CPU Shares에서 v2 CPU Weight로의 새로운 변환 공식

cgroup v1 CPU shares에서 cgroup v2 CPU weight로의 개선된 변환 공식 구현을 발표하게 되어 기쁩니다. 이 개선 사항은 cgroup v2 시스템에서 실행될 때 쿠버네티스 워크로드의 CPU 우선순위 할당과 관련된 중요한 문제들을 해결합니다. 배경...

cgroup v1 CPU shares에서 cgroup v2 CPU weight로의 개선된 변환 공식 구현을 발표하게 되어 기쁩니다. 이 개선 사항은 cgroup v2 시스템에서 실행될 때 쿠버네티스 워크로드의 CPU 우선순위 할당과 관련된 중요한 문제들을 해결합니다.

배경

쿠버네티스는 원래 cgroup v1을 염두에 두고 설계되었으며, CPU shares는 컨테이너의 CPU 요청을 millicpu 형태로 할당하여 간단하게 정의되었습니다.

예를 들어, 1 CPU (1024m)를 요청하는 컨테이너는 (cpu.shares = 1024)를 가집니다.

얼마 후, cgroup v1은 후속 버전인 cgroup v2로 대체되기 시작했습니다. cgroup v2에서는 CPU shares(범위는 2에서 262144, 또는 2¹에서 2¹⁸) 개념이 CPU weight(범위는 [1, 10000], 또는 10⁰에서 10⁴)로 대체되었습니다.

cgroup v2로의 전환과 함께, KEP-2254는 cgroup v1 CPU shares를 cgroup v2 CPU weight로 매핑하는 변환 공식을 도입했습니다. 이 변환 공식은 다음과 같이 정의되었습니다: cpu.weight = (1 + ((cpu.shares - 2) * 9999) / 262142)

이 공식은 [2¹, 2¹⁸] 범위의 값을 [10⁰, 10⁴]로 선형적으로 매핑합니다.

선형 변환 공식

이 접근 방식은 간단하지만, 선형 매핑은 몇 가지 중요한 문제를 야기하며 성능과 구성의 세분성 모두에 영향을 미칩니다.

이전 변환 공식의 문제점

현재 변환 공식은 두 가지 주요 문제를 생성합니다:

1. 비 쿠버네티스 워크로드에 대한 우선순위 감소

cgroup v1에서 CPU shares의 기본값은 1024이며, 이는 1 CPU를 요청하는 컨테이너가 쿠버네티스 범주 밖에 있는 시스템 프로세스와 동일한 우선순위를 가짐을 의미합니다. 그러나 cgroup v2에서 CPU weight의 기본값은 100이지만, 현재 공식은 1 CPU (1024m)를 겨우 ≈39 weight로 변환합니다. 이는 기본값의 40% 미만입니다.

예시:

  • 1 CPU (1024m)를 요청하는 컨테이너
  • cgroup v1: cpu.shares = 1024 (기본값과 동일)
  • cgroup v2 (현재): cpu.weight = 39 (기본값 100보다 훨씬 낮음)

이는 cgroup v2로 이동한 후, 쿠버네티스 (또는 OCI) 워크로드가 비 쿠버네티스 프로세스에 대해 사실상 CPU 우선순위를 낮추게 됨을 의미합니다. 이 문제는 쿠버네티스 범주 밖에 있는 많은 시스템 데몬을 실행하고, 특히 리소스 부족 상황에서 쿠버네티스 워크로드가 우선순위를 가지기를 기대하는 설정에서 심각할 수 있습니다.

2. 관리 불가능한 세분성

현재 공식은 적은 CPU 요청에 대해 매우 낮은 값을 생성하여, 컨테이너 내에서 세밀한 리소스 분배를 위한 하위 cgroup을 생성하는 능력을 제한합니다 (이는 앞으로 훨씬 쉬워질 수 있습니다. 자세한 내용은 KEP #5474를 참조하세요).

예시:

  • 100m CPU를 요청하는 컨테이너
  • cgroup v1: cpu.shares = 102
  • cgroup v2 (현재): cpu.weight = 4 (하위 cgroup 구성에는 너무 낮음)

cgroup v1에서는 100m CPU 요청이 102 CPU shares로 이어졌고, 이는 메인 컨테이너 내부에 하위 cgroup을 생성하여 서로 다른 프로세스 그룹에 세밀한 CPU 우선순위를 할당할 수 있었기 때문에 관리 가능했습니다. 하지만 cgroup v2에서는 4 shares는 세분성이 충분하지 않기 때문에 하위 cgroup 간에 분배하기 매우 어렵습니다.

비특권 컨테이너를 위한 쓰기 가능한 cgroup을 허용할 계획이 있기 때문에, 이 문제는 더욱 중요해집니다.

새로운 변환 공식

설명

새로운 공식은 더 복잡하지만, cgroup v1 CPU shares와 cgroup v2 CPU weight 간의 매핑을 훨씬 더 잘 수행합니다:

$$cpu.weight = \lceil 10^{(L^{2}/612 + 125L/612 - 7/34)} \rceil, \text{ where: } L = \log_2(cpu.shares)$$

이 공식은 다음 값들을 교차하는 2차 함수입니다:

  • (2, 1): 두 범위의 최소값.
  • (1024, 100): 두 범위의 기본값.
  • (262144, 10000): 두 범위의 최대값.

시각적으로, 새로운 함수는 다음과 같습니다:

2025-10-25-new-cgroup-v1-to-v2-conversion-formula-new-conversion.png

그리고 중요한 부분을 확대하면 다음과 같습니다:

2025-10-25-new-cgroup-v1-to-v2-conversion-formula-new-conversion-zoom.png

새로운 공식은 "선형에 가깝지만", 위의 세 가지 중요한 지점을 교차하도록 영리하게 범위를 매핑하도록 신중하게 설계되었습니다.

문제 해결 방법

  1. 향상된 우선순위 정렬:

    • 1 CPU (1024m)를 요청하는 컨테이너는 이제 cpu.weight = 102를 얻게 됩니다. 이 값은 cgroup v2의 기본값인 100에 가깝습니다.
    • 이는 쿠버네티스 워크로드와 시스템 프로세스 간의 의도된 우선순위 관계를 복원합니다.
  2. 향상된 세분성:

    • 100m CPU를 요청하는 컨테이너는 cpu.weight = 17을 얻게 됩니다. (여기에서 확인하세요).
    • 컨테이너 내에서 더 세밀한 리소스 분배를 가능하게 합니다.

채택 및 통합

이 변경 사항은 OCI 계층에서 구현되었습니다. 다시 말해, 이것은 쿠버네티스 자체에 구현된 것이 아니며, 따라서 새로운 변환 공식의 채택은 전적으로 OCI 런타임의 채택에 달려있습니다.

예를 들어:

  • runc: 새로운 공식은 버전 1.3.2부터 활성화됩니다.
  • crun: 새로운 공식은 버전 1.23부터 활성화됩니다.

기존 배포에 미치는 영향

중요: 일부 소비자는 기존 선형 변환 공식을 가정하고 있다면 영향을 받을 수 있습니다. 이전 공식을 기반으로 예상 CPU weight 값을 직접 계산하는 애플리케이션이나 모니터링 도구는 새로운 2차 변환을 반영하도록 업데이트가 필요할 수 있습니다. 이는 특히 다음 항목과 관련이 있습니다:

  • CPU weight 값을 예측하는 맞춤형 리소스 관리 도구.
  • 특정 weight 값을 검증하거나 예상하는 모니터링 시스템.
  • 프로그래밍 방식으로 CPU weight 값을 설정하거나 확인하는 애플리케이션.

쿠버네티스 프로젝트는 기존 툴링과의 호환성을 확인하기 위해 OCI 런타임을 업그레이드하기 전에 비프로덕션 환경에서 새로운 변환 공식을 테스트하는 것을 권장합니다.

더 자세한 정보는 어디에서 얻을 수 있나요?

이 개선 사항에 관심 있는 분들을 위해:

참여 방법

쿠버네티스 노드 레벨 기능에 참여하는 데 관심이 있으시다면, 쿠버네티스 노드 특별 이익 그룹에 참여하세요. 저희는 새로운 기여자들과 리소스 관리 문제에 대한 다양한 관점을 언제나 환영합니다.