본문 바로가기
공부/Linux

[Linux] cgroup, cpu

by haejang 2024. 11. 4.
728x90
728x90

 

 

https://medium.com/@7424069/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EA%B0%80-%EC%89%AC%EC%9B%8C%EC%A7%80%EB%8A%94-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%9D%B4%EC%95%BC%EA%B8%B0-cgroup-cpu%ED%8E%B8-c8f1e2208168

 

쿠버네티스가 쉬워지는 컨테이너 이야기 — cgroup, cpu편

들어가며,

medium.com

 

위 글을 읽고, 이해하고 싶어서 추가로 한 공부까지 남긴다.

 

 

# 먼저 개념부터

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

 

PID 1 존재

이렇게 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 뒤에 아무거나 와도 됨
  • 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가 부족하면 스로틀링이 걸릴 뿐 프로세스가 죽진 않는다.

 

 

# 참조

 

 

 

 

728x90
728x90

댓글