cgroup v2에 대하여
cgroup v2에 대하여 (About cgroup v2)
Linux에서 제어 그룹(control groups, cgroups)은 프로세스에 할당되는 리소스를 제한해요.
kubelet과 그 아래의 컨테이너 런타임은 cgroup과 연동해서 파드와 컨테이너의 리소스 관리를 강제해야 해요. 여기에는 컨테이너화된 워크로드에 대한 cpu/memory 요청과 한도(request/limit)가 포함돼요.
Linux에는 cgroup v1과 cgroup v2라는 두 가지 버전의 cgroup이 있어요. cgroup v2는 cgroup API의 새로운 세대예요.
출처: 문서
본문
cgroup v2란 무엇인가?
cgroup v2는 Linux cgroup API의 다음 버전이에요. cgroup v2는 향상된 리소스 관리 기능을 갖춘 통합 제어 시스템을 제공해요.
cgroup v2는 cgroup v1보다 다음과 같은 여러 개선점을 제공해요.
- API의 단일 통합 계층 구조 설계
- 컨테이너에 더 안전한 하위 트리 위임
- PSI(Pressure Stall Information) 같은 최신 기능
- 여러 리소스에 걸친 향상된 리소스 할당 관리와 격리
- 서로 다른 유형의 메모리 할당(네트워크 메모리, 커널 메모리 등)에 대한 통합 회계
- 페이지 캐시 write back 같은 비즉각적 리소스 변경에 대한 회계
일부 쿠버네티스 기능은 향상된 리소스 관리와 격리를 위해 전적으로 cgroup v2를 사용해요. 예를 들어 MemoryQoS 기능은 메모리 QoS를 개선하며 cgroup v2 프리미티브에 의존해요.
cgroup v2 사용하기
cgroup v2를 사용하는 권장 방법은 기본적으로 cgroup v2를 활성화하고 사용하는 Linux 배포판을 쓰는 것이에요.
배포판이 cgroup v2를 사용하는지 확인하려면 'Linux 노드에서 cgroup 버전 확인' 문서를 참고하세요.
요구 사항
cgroup v2는 다음과 같은 요구 사항이 있어요.
- OS 배포판이 cgroup v2를 활성화함
- Linux 커널 버전이 5.8 이상
- 컨테이너 런타임이 cgroup v2를 지원함. 예: containerd v1.4 이상, cri-o v1.20 이상
- 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/grub의 GRUB_CMDLINE_LINUX에 systemd.unified_cgroup_hierarchy=1을 추가하고, 이어서 sudo update-grub을 실행하면 돼요. 다만 권장하는 방법은 기본적으로 cgroup v2를 이미 활성화한 배포판을 사용하는 것이에요.
cgroup v2로 마이그레이션하기
cgroup v2로 마이그레이션하려면 요구 사항을 충족하는지 확인한 다음, 기본적으로 cgroup v2를 활성화하는 커널 버전으로 업그레이드해요.
kubelet은 OS가 cgroup v2에서 실행 중임을 자동으로 감지하고 추가 구성 없이 그에 맞게 동작해요.
노드에서든 컨테이너 내부에서든 사용자가 cgroup 파일시스템에 직접 접근하지 않는 한, cgroup v2로 전환할 때 사용자 경험의 눈에 띄는 차이는 없어야 해요.
cgroup v2는 cgroup v1과 다른 API를 사용하므로, cgroup 파일시스템에 직접 접근하는 애플리케이션이 있다면 cgroup v2를 지원하는 최신 버전으로 업데이트해야 해요. 예를 들어:
- 일부 서드파티 모니터링·보안 에이전트는 cgroup 파일시스템에 의존할 수 있어요. 이러한 에이전트를 cgroup v2를 지원하는 버전으로 업데이트하세요.
- 파드와 컨테이너를 모니터링하는 독립형 DaemonSet으로 cAdvisor를 실행한다면, v0.43.0 이상으로 업데이트하세요.
- Java 애플리케이션을 배포한다면 cgroup v2를 완전히 지원하는 버전을 사용하세요: OpenJDK / HotSpot: jdk8u372, 11.0.16, 15 이상 / IBM Semeru Runtimes: 8.0.382.0, 11.0.20.0, 17.0.8.0 이상 / IBM Java: 8.0.8.6 이상.
uber-go/automaxprocs패키지를 사용한다면 사용하는 버전이 v1.5.1 이상인지 확인하세요.- Node.js 애플리케이션을 배포한다면 cgroup v2 메모리 한도를 감지하는 버전을 선호하세요. Node.js는 v20.3.0부터 (libuv를 통해) cgroup v2 메모리 한도를 읽어요. v18 릴리스 라인은 cgroup v2 메모리 한도를 안정적으로 감지하지 못해요. 이 지원이 없는 버전은 파드에 적용된 한도 대신 호스트의 전체 메모리를 읽어, 힙 크기가 잘못 계산되어 OOM(메모리 부족) 종료를 유발할 수 있어요. 영향을 받는 버전에서는 예를 들어
--max-old-space-size플래그로 힙 크기를 명시적으로 설정하세요.
Linux 노드에서 cgroup 버전 확인하기
cgroup 버전은 사용 중인 Linux 배포판과 OS에 구성된 기본 cgroup 버전에 따라 달라져요. 배포판이 어떤 cgroup 버전을 사용하는지 확인하려면 노드에서 stat -fc %T /sys/fs/cgroup/ 명령을 실행하세요.
stat -fc %T /sys/fs/cgroup/
cgroup v2라면 출력은 cgroup2fs예요.
cgroup v1이라면 출력은 tmpfs예요.
cgroup v1의 폐기 (Deprecation of cgroup v1)
쿠버네티스는 cgroup v1을 폐기(deprecate)했어요. 제거는 쿠버네티스 폐기 정책을 따를 예정이에요.
kubelet은 기본적으로 cgroup v1 노드에서 더 이상 시작되지 않아요. 이 설정을 비활성화하려면 클러스터 관리자가 kubelet 구성 파일에서 failCgroupV1을 false로 설정해야 해요.