[Linux] cgroup, cpu
위 글을 읽고, 이해하고 싶어서 추가로 한 공부까지 남긴다.
# 먼저 개념부터
1. cgroup이란? - control groups
- 프로세스들을 그룹화하고, 그 그룹들의 시스템 리소스(cpu, mem, 네트워크 대역폭 등) 사용을 관리/제한/모니터링할 수 있는 리눅스 커널 기능
2. cgroup 서브시스템
- cgroup은 서브시스템으로 구성된 프레임워크이다.
- cgroup 자체만으로는 자원을 그룹화하고 관리하는 구조와 기능을 제공할 뿐, 실제 자원 제어는 서브시스템들에 의해 이루어짐
- 서브시스템 종류 : cpu, cpuacct, cpuset, memory, blkio, ns ... 등등
- 서브시스템은 컨트롤러라고도 불림. (cgroup v1에서는 서브시스템, v2에서는 컨트롤러 용어가 주로 사용되었다고 함)
3. cgroup과 파일시스템의 관계
- cgroup은 리눅스 커널의 기능이자 자원 관리 메커니즘.
- -> `/sys/fs/cgroup/` 이란 파일시스템을 통해 사용자와 상호작용할 수 있다.
- 즉, `/sys/fs/cgroup/` 내 파일들을 확인하거나 수정함으로써 각 cgroup들의 속성을 확인하고 설정할 수 있음.
4. cgroup v1, v2 차이
- cgroup v1
- 각 서브시스템은 서로 다른 계층 구조에서 독립적으로 관리됨.
- 유연성은 있지만 복잡성이 증가하며 자원 관리의 일관성이 떨어질 수 있음.
- ex) `/sys/fs/cgroup/memory/memory.usage_in_bytes`
- 여러 서브시스템 간의 독립적 운영으로 인해 관리가 복잡 > 설정 오류 발생 가능성이 있음 > 성능과 자원 사용량을 관리하는데 비효율적
- 각 서브시스템은 서로 다른 계층 구조에서 독립적으로 관리됨.
- cgroup v2
- 모든 컨트롤러는 단일 계층 구조를 공유함.
- 관리와 설정이 간단해지고, 계층간 일관성을 보장.
- ex) `/sys/fs/cgroup/memory.current`
- 일관된 계층 구조와 설정 방식 덕분에 성능 관리가 효율적이며, 자원 사용량이 더 효과적으로 조절됨
- 모든 컨트롤러는 단일 계층 구조를 공유함.
- cgroup v2의 새로운 기능
- 메모리 압력 감지 : 메모리 사용량이 한계에 도달했을 때, 이를 감지하고 조치를 취할 수 있음
- CPU와 I/O를 더 정교하게 조절할 수 있음
# cgroup v2 파일시스템 구경
리눅스 하나를 도커로 띄우자.
docker run -it --rm --privileged docker:27.3.1-dind-alpine3.20 sh
/sys/fs/cgroup 에 가보면 다음과 같은 파일들이 있음.
cd sys/fs/cgroup/
ls
이 경로(`/sys/fs/cgroup/`) 하위에 있는 폴더 하나가 cgroup 하나라고 생각하면 된다. 각 서브시스템 파일들은 하위 폴더들에도 동일하게 있다.
여기에 이미 init이라는 폴더가 하나 있는데, 이는 루트(최상위) cgroup을 나타낸다. <- init 프로세스 (PID 1) 이 속해있음.
cat init/cgroup.procs
이렇게 cgroup.procs란 파일을 확인함으로써 해당 cgroup에 속한 프로세스 id들을 확인할 수 있다.
이제 새로운 cgroup을 하나 만들어 보자. 그냥 폴더 하나를 만들면 된다.
mkdir honglab
새로 생성된 폴더를 확인해 보면, 자동으로 서브시스템 파일들이 동일하게 생성되어 있는것을 확인할 수 있다.
각 파일들의 용도는 권한정보를 통해 어느정도 유추할 수 있다.
> ls -l
total 0
-r--r--r-- 1 root root 0 Nov 3 15:29 cgroup.controllers
-r--r--r-- 1 root root 0 Nov 3 15:29 cgroup.events
-rw-r--r-- 1 root root 0 Nov 3 15:29 cgroup.freeze
--w------- 1 root root 0 Nov 3 15:29 cgroup.kill
-rw-r--r-- 1 root root 0 Nov 3 15:29 cgroup.max.depth
-rw-r--r-- 1 root root 0 Nov 3 15:29 cgroup.max.descendants
- r : 읽기만 가능 - 상태나 통계를 보여줌
- cgroup.procs : 이 cgroup 내의 프로세스 id들 확인 가능
- cgroup.controllers : 이 cgroup에서 사용 가능한 컨트롤러의 목록을 보여줌
- 상위 cgroup의 cgroup.subtree_control 내용과 동일
- w : 쓰기만 가능 - 특정 행위를 함
- cgroup.kill : 입력 시 이 cgroup 내의 모든 프로세스를 종료함 (SIGKILL을 보냄)
- 사용예시 : `echo 1 > /sys/fs/cgroup/honglab/cgroup.kill`
- 아무거나 쓰면 되긴 해서, echo 뒤에 아무거나 와도 됨
- cgroup.kill : 입력 시 이 cgroup 내의 모든 프로세스를 종료함 (SIGKILL을 보냄)
- rw : 읽고 쓰기 가능 - 제한을 설정함
- cgroup.subtree_control : 하위 cgroup들이 사용 가능한 컨트롤러들을 지정할 수 있음
- cpu.weight : CPU의 가중치 설정
# CPU 컨트롤러가 CPU를 제어하는 방법
결론부터 말하자면, cpu는 가중치 기반으로 분배되고 관리된다.
즉, cgroup/A/cpu.weight 이 100이고 cgroup/B/cpu.weight 이 200이면 각각 1 : 2 의 비율로 최대 CPU를 나눠가질 수 있다는 거다.
만약 B그룹이 CPU를 안쓰고 있다면 A그룹이 혼자 CPU를 100% 먹을수도 있다. 마찬가지로 A그룹이 안쓰고 있으면 B그룹이 혼자 먹을수도 있다.
-> 쿠버네티스에서도 마찬가지로 cpu를 나눠가지게 된다. limits.cpu를 지정하지 않는다면 노드 내 모든 파드들이 cpu를 많이 쓰게 될지라도 알아서 cpu를 나눠쓰게 될 것이다. 따라서 limits를 지정하지 않는 것이 권장된다.
cpu 컨트롤러 파일들은 다음과 같다.
- cpu.weight
- 상대적 CPU 가중치 설정
- 형식 : 1 ~ 10000 사이의 정수값 (기본값 : 100)
- cpu.weight.nice
- cpu.weight의 사용자 친화 버전 -> 직관적인 우선순위로 보여주거나 설정
- -20(최고 우선순위) ~ 19(최저 우선순위) (기본값 : 0)
- cpu.weight과 cpu.weight.nice 둘 중 하나가 수정되면 나머지 파일도 알아서 변환됨
- cpu.max
- CPU 사용량 제한
- 형식 : `[quota] [period]`
- period : 마이크로초 단위의 주기 설정 (기본값 : 100000 (0.1초))
- quota : period 주기동안 사용할 수 있는 최대 CPU 시간
- cpu.max.burst
- cpu.max 설정에서 잠깐 동안 추가적인 CPU 사용을 허용함 (일종의 버스트 모드)
- ex) 100000 으로 설정 -> cpu.max에 지정된 사용량 외에 100ms동안 추가적인 CPU 사용을 허용함
- cpu.stat
- CPU 사용 통계 보여줌 (읽기 전용)
- usage_usec , user_usec, system_usec
- cpu.idle
- CPU 자원이 남아돌 때 (유휴 상태일 때) CPU를 사용할 수 있는지 여부 지정
- 형식 : 1 or 0 (기본값 : 0 - 유휴 여부에 상관없이 CPU 사용 가능)
# 압축 가능한 리소스
CPU는 압축 가능한 자원이기 때문에, 쿠버네티스에서 Limits을 설정하지 않는게 더 좋다.
라는 주장은 많이 들었었고, 그에 따라 항상 limits은 없앴지만, 막상 cpu가 왜 압축 가능한 자원인지에 대한 이해는 없었다.
압축 가능한 리소스라는 것은, 자원이 부족해도 프로세스가 죽지 않는 리소스들을 말한다.
즉, 사용할 수 있는 cpu 리소스가 없더라도 프로세스는 기다릴 수 있기 때문에 압축 가능하다고 불린다.
cpu가 부족하면 스로틀링이 걸릴 뿐 프로세스가 죽진 않는다.
# 참조
- https://velog.io/@hsh_124/cgroup-%EC%9D%84-%ED%86%B5%ED%95%B4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%9D%98-%EB%A6%AC%EC%86%8C%EC%8A%A4-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0
- https://blog.outsider.ne.kr/1653
- Chat GPT
끝