cgroup v2에 대하여

cgroup v2에 대하여 (About cgroup v2)

Linux에서 컨트롤 그룹(control groups)은 프로세스에 할당되는 리소스를 제한해요.

kubelet과 그 아래의 컨테이너 런타임은 Pod와 컨테이너의 리소스 관리(컨테이너화된 워크로드에 대한 cpu/memory 요청과 리밋 포함)를 적용하려면 cgroup과 인터페이스해야 해요.

Linux에는 cgroup의 두 가지 버전이 있어요: cgroup v1과 cgroup v2. cgroup v2는 cgroup API의 새로운 세대예요.

출처: Kubernetes 공식 문서 — About cgroup v2

cgroup v2란 무엇인가 (What is cgroup v2?)

FEATURE STATE: Kubernetes v1.25 [stable]

cgroup v2는 Linux cgroup API의 다음 버전이에요. cgroup v2는 향상된 리소스 관리 기능을 갖춘 통합된 제어 시스템을 제공해요.

cgroup v2는 cgroup v1보다 여러 가지 개선점을 제공합니다. 예를 들면:

  • API에서 단일 통합 계층 구조(unified hierarchy) 설계
  • 컨테이너에 대한 더 안전한 서브트리 위임(sub-tree delegation)
  • PSI(Pressure Stall Information) 같은 최신 기능
  • 여러 리소스에 걸친 향상된 리소스 할당 관리와 격리
    • 다양한 유형의 메모리 할당(네트워크 메모리, 커널 메모리 등)에 대한 통합 회계
    • 페이지 캐시 쓰기-백(page cache write back) 같은 비즉시(non-immediate) 리소스 변경에 대한 회계

일부 Kubernetes 기능은 향상된 리소스 관리와 격리를 위해 cgroup v2만 독점적으로 사용해요. 예를 들어 MemoryQoS 기능은 메모리 QoS를 개선하고 cgroup v2 프리미티브에 의존해요.

cgroup v2 사용하기 (Using cgroup v2)

cgroup v2를 사용하는 권장 방법은 기본적으로 cgroup v2를 활성화하고 사용하는 Linux 배포판을 쓰는 거예요.

자신의 배포판이 cgroup v2를 쓰는지 확인하려면 Linux 노드에서 cgroup 버전 식별하기를 참고하세요.

요구사항 (Requirements)

cgroup v2에는 다음과 같은 요구사항이 있어요:

  • OS 배포판이 cgroup v2를 활성화
  • Linux 커널 버전이 5.8 이상
  • 컨테이너 런타임이 cgroup v2를 지원. 예를 들어:
  • kubelet과 컨테이너 런타임이 systemd cgroup 드라이버를 사용하도록 구성

Linux 배포판의 cgroup v2 지원

cgroup v2를 사용하는 Linux 배포판 목록은 cgroup v2 문서를 참고하세요.

  • Container Optimized OS (M97 이후)
  • Ubuntu (21.10 이후, 22.04+ 권장)
  • Debian GNU/Linux (Debian 11 bullseye 이후)
  • Fedora (31 이후)
  • Arch Linux (2021년 4월 이후)
  • RHEL 및 RHEL 계열 배포판 (9 이후)

자신의 배포판이 cgroup v2를 사용하는지 확인하려면 배포판 문서를 참고하거나 Linux 노드에서 cgroup 버전 식별하기의 지침을 따르세요.

커널 cmdline 부팅 인자를 수정해서 Linux 배포판에서 cgroup v2를 수동으로 활성화할 수도 있어요. 배포판이 GRUB을 쓴다면 /etc/default/grubGRUB_CMDLINE_LINUXsystemd.unified_cgroup_hierarchy=1을 추가하고 sudo update-grub을 실행하면 돼요. 다만 권장 방법은 기본적으로 cgroup v2를 활성화하는 배포판을 쓰는 거예요.

cgroup v2로 마이그레이션하려면 요구사항을 충족하는지 확인한 뒤, 기본적으로 cgroup v2를 활성화하는 커널 버전으로 업그레이드하세요.

kubelet은 OS가 cgroup v2에서 실행 중임을 자동으로 감지하고 추가 구성 없이 그에 맞춰 동작해요.

사용자가 cgroup 파일 시스템에 직접 접근하는 경우(노드에서든 컨테이너 안에서든)를 제외하면 cgroup v2로 전환했을 때 사용자 경험상 눈에 띄는 차이는 없어야 해요.

cgroup v2는 cgroup v1과 다른 API를 사용해요. 따라서 cgroup 파일 시스템에 직접 접근하는 애플리케이션이 있다면 cgroup v2를 지원하는 최신 버전으로 업데이트해야 합니다. 예를 들면:

  • 일부 서드파티 모니터링·보안 에이전트가 cgroup 파일시스템에 의존할 수 있어요. cgroup v2를 지원하는 버전으로 에이전트를 업데이트하세요.
  • Pod와 컨테이너를 모니터링하기 위해 cAdvisor를 독립형 DaemonSet으로 실행한다면 v0.43.0 이상으로 업데이트하세요.
  • Java 애플리케이션을 배포한다면 cgroup v2를 완전히 지원하는 버전을 선호하세요:
  • uber-go/automaxprocs 패키지를 쓴다면 사용하는 버전이 v1.5.1 이상인지 확인하세요.
  • Node.js 애플리케이션을 배포한다면 cgroup v2 메모리 리밋을 감지하는 버전을 선호하세요. Node.js는 libuv를 통해 Node.js v20.3.0부터 cgroup v2 메모리 리밋을 읽어요. v18 릴리스 라인은 cgroup v2 메모리 리밋을 안정적으로 감지하지 못해요. 이 지원이 없는 버전은 Pod에 적용된 리밋 대신 호스트의 총 메모리를 읽을 수 있고, 이는 힙 크기가 잘못 잡혀 OOM(메모리 부족) 종료로 이어질 수 있어요. 영향을 받는 버전에서는 예를 들어 --max-old-space-size 플래그로 힙 크기를 명시적으로 설정하세요.

Linux 노드에서 cgroup 버전 식별하기 (Identify the cgroup version on Linux Nodes)

cgroup 버전은 사용 중인 Linux 배포판과 OS에 구성된 기본 cgroup 버전에 따라 달라져요. 노드에서 stat -fc %T /sys/fs/cgroup/ 명령을 실행해서 배포판이 어떤 cgroup 버전을 쓰는지 확인할 수 있습니다:

stat -fc %T /sys/fs/cgroup/

cgroup v2의 경우 출력은 cgroup2fs예요.

cgroup v1의 경우 출력은 tmpfs예요.

cgroup v1의 폐기 (Deprecation of cgroup v1)

FEATURE STATE: Kubernetes v1.35 [deprecated]

Kubernetes는 cgroup v1을 폐기했어요. 제거는 Kubernetes 폐기 정책을 따릅니다.

Kubelet은 기본적으로 cgroup v1 노드에서 더 이상 시작되지 않아요. 이 설정을 비활성화하려면 클러스터 관리자가 kubelet 구성 파일에서 failCgroupV1을 false로 설정해야 합니다.

다음으로 볼 것 (What's next)

더 알아보기 (Learn more)