Docker를 통한 cgroup분석: CPU 사용률 제한

hyuckhoon.ko·2024년 2월 23일
0

/proc/[PID]/cgroup 통해서 cgroup 정보 확인하기

$ docker run -it -d ubuntu:16.04
$ docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
a091c95446e8   ubuntu:16.04   "/bin/bash"   22 seconds ago   Up 21 seconds             stupefied_chandrasekhar

# 현재 실행중인 컨테이너 PID 추출
reallinux@ubuntu:~$ docker inspect a091c95446e8 | grep Pid
            "Pid": 2510,
            "PidMode": "",
            "PidsLimit": null,

현재 실행중인 컨테이너 cgroup 확인하기

reallinux@ubuntu:~$ cat /proc/2510/cgroup

12:memory:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
11:cpuset:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
10:blkio:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
9:hugetlb:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
8:rdma:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
7:net_cls,net_prio:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
6:pids:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
5:perf_event:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
4:freezer:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
3:cpu,cpuacct:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
2:devices:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
1:name=systemd:/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c
0::/docker/a091c95446e8ff8aeed54a745cd1d04d9291357d5e1e1f95f856b1a80f44589c

그렇다면 PID 1의 프로세스의 cgroup은 어떨까?

PID 1 프로세스 cgroup 확인하기

reallinux@ubuntu:~$ cat /proc/1/cgroup

12:memory:/
11:cpuset:/
10:blkio:/
9:hugetlb:/
8:rdma:/
7:net_cls,net_prio:/
6:pids:/
5:perf_event:/
4:freezer:/
3:cpu,cpuacct:/
2:devices:/
1:name=systemd:/init.scope
0::/init.scope

현재 프로세스 cgroup 확인하기

reallinux@ubuntu:~$ cat /proc/$$/cgroup

12:memory:/user.slice
11:cpuset:/
10:blkio:/user.slice
9:hugetlb:/
8:rdma:/
7:net_cls,net_prio:/
6:pids:/user.slice/user-1000.slice/session-2.scope
5:perf_event:/
4:freezer:/
3:cpu,cpuacct:/user.slice
2:devices:/user.slice
1:name=systemd:/user.slice/user-1000.slice/session-2.scope
0::/user.slice/user-1000.slice/session-2.scope

기본적으로 PID 1번 프로세스의 cgroup을 상속받는다.
그렇기 때문에 1번 프로세스의 cgroup과 현재 프로세스(bash)의 그것이 일치한다.
반면에 격리된 컨테이너의 cgroup은 다름을 확인할 수있다.

프로세스 컨트롤 그룹 즉, cgroup을 제한하여 프로세스들의 하드웨어 자원들을 점유를 제한 해보자.

CPU 사용률 제한

물리적인 서버를 node라고 해보자.
node 안에 두 개의 컨테이너가 있다.

  • 웹 서버 컨테이너
  • 데이터 분석 컨테이너

예를들어, 데이터 분석 컨테이너 때문에 웹 서버 컨테이너의 CPU 사용률이 제한되어 응답속도가 느려지면 안 된다.
따라서, 데이터 분석 컨테이너의 CPU 사용률 제한을 20%로 제한하면, 웹서버는 최대 CPU 사용률 80%를 보장받을 수있다.

1) 컨테이너 실행

이번엔 ubuntu 18.04 버전의 이미지의 컨테이너를 실행시켜보자.

reallinux@ubuntu:~$ sudo docker run -it ubuntu:18.04 /bin/bash

Unable to find image 'ubuntu:18.04' locally
18.04: Pulling from library/ubuntu
7c457f213c76: Pull complete 
Digest: sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Status: Downloaded newer image for ubuntu:18.04
root@04c61489c3e4:/# 

2) 우분투 컨테이너 종료

/bin/bash 프로그램이 실행됐을 것이다.
이제 종료시켜 빠져나와보자.

root@04c61489c3e4:/# exit
exit
reallinux@ubuntu:~$

3) 방금 전 종료된 컨테이너 ID 확인하기

reallinux@ubuntu:~$ sudo docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS                        PORTS     NAMES
04c61489c3e4   ubuntu:18.04   "/bin/bash"              About a minute ago   

4) 종료된 컨테이너 다시 실행시키기

reallinux@ubuntu:~$ sudo docker start 04c61489c3e4
04c61489c3e4

5) 재시작된 우분투 컨테이너에 접속하기

reallinux@ubuntu:~$ docker attach 04c61489c3e4
root@04c61489c3e4:/# ls

6) 기존 컨테이너의 cgroup 변경하기

reallinux@ubuntu:~$ docker ps

CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
04c61489c3e4   ubuntu:18.04   "/bin/bash"   6 minutes ago    Up 2 seconds              confident_bell
a091c95446e8   ubuntu:16.04   "/bin/bash"   20 minutes ago   Up 20 minutes             stupefied_chandrasekhar

reallinux@ubuntu:~$ docker update --cpu-quota=500000 04c61489c3e4
04c61489c3e4


# run 명령어와 함께 cgroup을 변경하여 실행할 수도 있다.
reallinux@ubuntu:~$ docker run --cpu-period=100000 --cpu-quota=50000 -it ubuntu:18.04 /bin/bash
root@aea57f6adafd:/#

CPU 사용률 수치 산정 방법은 아래와 같다.
우선, period 개념이 필요하다.
CPU 스케줄링 단위로, 총 시간을 의미한다. ex) 100ms

100ms 마다 연속된 스케줄링을 한다고 정의 했을 때, cpu-quota를 50ms는 그 절반에 해당하는 시간이고, 전체 CPU 스케줄링 시간의 절반을 CPU 스케줄링을 사용하겠다는 의미다.

Q. 100ms는 0.1s인데, 왜 100000s(100Ms)로 되고야 마는걸까?

우리가 해볼 테스트는 다음과 같다.
컨테이너의 CPU 사용률이 50%가 넘지 않게 제한했다.
벤치마크를 통해 부하를 줬을 때, 정말로 컨테이너의 CPU 사용률이 50%를 넘지 않는지 확인해보는 것이다.

7) sysbench 프로그램 설치하기

root@aea57f6adafd:/# apt update && apt install sysbench

root@aea57f6adafd:/# sysbench --test=cpu run
WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
sysbench 1.0.11 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 1
Initializing random number generator from current time


Prime numbers limit: 10000

Initializing worker threads...

Threads started!

CPU 사용률을 25%로 제한은 어떻게 할까?

docker run --cpu-period=100000 --cpu-quota=25000 -it ubuntu:18.04 /bin/bash

8) cgroup 적용 설정값 확인하기

cd /sys/fs/cgroup/cpu,cpuacct/docker/{컨테이너ID}

에서 cat cpu.cfs_period_us, cat cpu.cfs_quota_us 를 확인할 수 있다.

즉, 도커는 cgroup과 namespace 를 수정해주는 것일 뿐이다.

(참고로, 강의에서는 cpu,cpuacct/docker/ 디렉터리가 나오고 있다. 하지만 나의 경우 아래와 같이 해야만 했다.)

reallinux@ubuntu:~$ docker run --cpu-period=100000 --cpu-quota=50000 -it ubuntu:18.04 /bin/bash

root@d0f8e5226b63:/# ls /sys/fs/cgroup/cpu,cpuacct/
cgroup.clone_children  cpu.shares      cpuacct.stat          cpuacct.usage_percpu_sys   notify_on_release
cgroup.procs           cpu.stat        cpuacct.usage         cpuacct.usage_percpu_user  tasks
cpu.cfs_period_us      cpu.uclamp.max  cpuacct.usage_all     cpuacct.usage_sys
cpu.cfs_quota_us       cpu.uclamp.min  cpuacct.usage_percpu  cpuacct.usage_user
root@d0f8e5226b63:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

root@d0f8e5226b63:/# cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us 
100000
root@d0f8e5226b63:/# cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us 
50000

0개의 댓글