cgroup 을 통해 컨테이너의 리소스 확인하기

황서희·2024년 9월 25일
0

kubectl top 명령어를 통해 pod의 메모리와 CPU를 확인할 수 있으면 좋겠지만, 모종의 이유로 kubectl top 을 설치하지 못해 kubectl top 명령어 없이도 memory와 CPU 등 리소스를 확인할 수 있는 방법을 알아보게 되었다. 다행히 cgroup 디렉터리를 이용하여 확인할 수 있는 방법이 있었다. 루트 권한으로의 접근이 가능하다면, 해당 방법으로 확인하는 것이 좋겠다.

확인할 수 있는 이유

컨테이너는 linux의 cgroup 과 namespace 기능을 통해 격리된 환경이기 때문이다. cgroup은 프로세스 그룹별로 시스템 리소스를 제한하고 모니터링할 수 있게 한다.
cgroup은 컨테이너별로 그룹의 리소스 사용량과 제한 정보를 파일 시스템 형태로 노출한다. 일반적으로 sys/fs/cgroup 디렉토리에서 확인할 수 있다 (컨테이너 안에서도).

cgroup 은 cgroup v1 과 cgroup v2 가 사용되고 있다. 이에 따라 경로와 파일 명칭이 다를 수 있다.

  • cgroup v1 : /sys/fs/cgroup/memory/memory.usage_in_bytes
  • cgroup v2 : /sys/fs/cgroup/memory.current

cgroup v1과 cgroup v2란?
cgroup 은 버전에 따라 시스템 자원을 관리하는 방식과 구조에 차이가 있다.
cgroup v1 은 각 자원 컨트롤러 (메모리, CPU) 등이 별도의 계층 구조를 가져 독립적으로 운영된다. 유연성을 제공하지만, 여러 자원을 동시에 관리할 때는 복잡성이 증가할 수 있다.
cgroup v2는 모든 자원 컨트롤러가 하나의 계층 구조를 공유한다. 컨트롤러 간의 일관성이 보장되고 관리가 용이하지만, 호환성의 이슈가 있을 수 있다.
어떤 버전의 cgroup 을 사용하는지는, mount | grep cgroup2 을 통해 확인할 수 있다. 출력에 cgroup2가 있으면 cgroup v2를 사용하는 것이다.

컨테이너 런타임은 이 cgroup을 활용하여 컨테이너의 리소스 사용을 관리하므로, 해당 방법을 통해 컨테이너의 리소스를 정확하게 추적할 수 있다.

확인 방법

1. 컨테이너 안에서 확인
컨테이너에 안에 접속하여 /sys/fs/cgroup/memory 폴더의 memory.usage_in_bytes 파일을 확인한다.

# cgroup v1
cat /sys/fs/cgroup/memory/memory.usage_in_bytes

# cgroup v2
cat /sys/fs/cgroup/memory.current

2. 접속한 node에서 확인

  1. kubernetes pod 혹은 container 가 위치한 node에 접속한다.
  2. 컨테이너의 PID (Process ID) 를 확인한다. (docker 의 경우 docker inspect --format '{{.State.Pid}}' <컨테이너 ID> , containerd를 사용하는 경우 crictl inspect --output go-template --template '{{.info.pid}}' <컨테이너 ID>)
    • kubernetes의 경우 kubectl describe <pod> -n <namespace> 명령어를 사용하여 사용하는 컨테이너의 ID를 확인할 수 있다.
  3. 컨테이너의 PID가 확인되었으면 해당 process 의 경로에서 PID의 cgroup을 찾는다. cat /proc/<PID>/cgroup
    • cgroup v1 : 각 컨트롤러 별로 경로가 표시된다.
    • cgroup v2 : 단일 계층 구조이므로 0::/ 형태로 경로가 표시된다.
cat /proc/<PID>/cgroup # cgroup v1의 경우
11:memory:/user.slice
10:cpu,cpuacct:/user.slice
9:cpuset:/
8:blkio:/user.slice
7:net_cls,net_prio:/
6:freezer:/
5:devices:/user.slice
4:hugetlb:/
3:perf_event:/
2:pids:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope

cat /proc/87357/cgroup # cgroup v2의 경우
0::/user.slice/user-1000.slice/session-2.scope
  1. /sys/fs/cgroup 에서 위에서 확인한 경로로 이동한다. 경로를 그대로 /sys/fs/cgroup 아래에 결합하여 사용한다. ( e.g. /sys/fs/cgroup/user.slice/user-1000.slice/session-2.scope
  2. memory.usage 등의 파일을 사용하여 사용중인 메모리를 확인한다.
    • cgroup v1 의 경우 : /sys/fs/cgroup/memory/<cgroup 경로>/memory.usage_in_bytes
    • cgroup v2 의 경우 : /sys/fs/cgroup/<cgroup 경로>/memory.current

메모리 뿐만 아니라 CPU 사용량 (cpuacct.usage 혹은 cpu.stat) 역시 확인할 수 있다. 각 메모리 사용량 파일의 값은 바이트(Byte) 단위이다.

cgroup v1에서는 cpuacct.usage 파일에서 나노초 단위로 확인한다. cgroup v2 에서는 cpu.stat 파일에서 usage_usec 값을 통해 마이크로초 단위로 확인한다.

profile
다 아는 건 아니어도 바라는 대로

0개의 댓글