Docker

Docker 톺아보기 16탄 - Docker 컨테이너 리소스 관리하기 (실습편)

AAROH 2022. 12. 27. 14:24


이번 챕터에서는 컨테이너의 리소스를 관리하는 실습을 진행해보도록 하겠다!

 

이번 챕터의 목차!

1. 컨테이너 리소스 제한

2. 컨테이너 모니터링하기

3. cAdvisor 설치해서 사용하기

 

시작하기에 앞서 리눅스에는 stress라는 부하테스트 도구가 있다

$ stress --cpu 2
$ stress -c 2

이렇게 실행하면 CPU 작업 부하가 일어난다

위 명령어는 2개의 CPU 코어에 대해 작업 부하를 일으키는 것이다

 

메모리에도 작업부하를 줄 수 있다

$ stress --vm 2 --vm-bytes <사용할 크기>

명시한 크기만큼 메모리에 작업부하를 주는 명령어이다

 

실습 전에 먼저 작업 디렉토리를 생성하고 그 안에 도커파일을 만들자

그리고 도커파일이 제대로 작성됐는지 확인하고, 빌드해서 컨테이너 이미지를 만들자

확인해보자

 

 

 

 

그럼 메모리 리소스 제한을 실습해보자

$ docker run -m 100m --memory-swap 100m stress:latest stress --vm 1 --vm-bytes 90m -t 5s

위 명령은 stress라는 이름의 컨테이너 이미지를

실제 메모리 + 스왑 메모리 = 100mb로 설정하고, 전체 메모리는 100mb를 사용하여 실행하겠다는 뜻이다

(따라서 실제 메모리는 100mb, 스왑메모리는 0mb가 된다)

그리고 stress 테스트 툴을 사용해서 90mb의 메모리 부하를 주는 테스트를 진행한다

그럼 아래처럼 부하테스트를 진행하는데

5초가 지난 후에 성공적으로 부하테스트가 완료되었다는 것을 알 수 있다

 

 만약 아래 명령을 실행하면 어떻게 될까?

$ docker run -m 100m --memory-swap 100m stress:latest stress --vm 1 --vm-bytes 150m -t 5s

할당된 100mb의 메모리 보다 많은 150mb의 부하를 주게 되어 fail이 나게 된다

 

그렇다면 아래 명령처럼 스왑메모리 지정을 안해주면 어떻게 될까?

$ docker run -m 100m stress:latest stress --vm 1 --vm-bytes 150m -t 5s

스왑 메모리를 지정해주지 않으면 자동으로 실제 메모리의 두 배의 크기로 전체 메모리를 잡아준다

따라서 위 명령은 아래의 명령과 같은 셈이다

$ docker run -m 100m --memory-swap 200m stress:latest stress --vm 1 --vm-bytes 150m -t 5s

위 명령으로 잡힌 메모리는

전체 메모리 = 200m

실제 메모리 = 100m

스왑 메모리 = 100m

이기 떄문에

150m의 메모리 부하를 주면 100m는 실제 메모리에서 사용되고 나머지 50m는 스왑 메모리에서 사용된다

이처럼 테스트가 잘 진행되는 것을 볼 수 있다

 

우리는 앞 챕터에서 oom killer에 대해서 알아봤었다

oom killer는 out of memory killer 의 줄임말로써,

리눅스 시스템은 물리적 메모리가 부족해지면 강제로 프로세스를 죽이는 oom killer를 실행한다

그렇게 해서라도 메모리 영역을 보호하는 것이다

하지만 우리는 이 oom killer가 어떤 프로세스를 죽일지 모른다!

그렇기 때문에 반드시 필요한 컨테이너의 경우, oom killer로부터 죽는 것을 막아야 한다

$ docker run -d -m  100m --name m4 --oom-kill-disable=true nginx:1.14

위 명령은 nginx 1.14버전의 컨테이너 이미지를 100m의 메모리를 사용하여 m4라는 이름의 컨테이너를 생성하게 한다

다만 --oom-kill-disable 옵션을 true로 줘서 oom killer가 이 컨테이너를 강제로 죽이지 못하도록 한다

이 oom killer의 활성화 여부는 두 가지 방법으로 확인할 수 있다

첫번째, docker inspect

$ docker inspect m4

m4 컨테이너의 상세 정보를 볼 수 있는데

이 중에서 OomKillDisable 키를 찾으면 된다

이처럼 실제 메모리 용량과 전체 메모리 용량(실제 메모리+스왑 메모리)과 더불어

oom killer 의 활성화 여부도 확인할 수 있다

 

두번째, 파일로 확인하기

/sys/fs/cgroup/memory/docker/<컨테이너ID>/memory.oom_control

경로를 cat 명령으로 부르면 oom killer의 활성화 여부가 0과 1로 표현된다

1은 true이고, 0은 false 이다

 

 

이렇게 간단하게 stress라는 커맨드를 이용해서 부하를 일으켜 메모리 제한에 대한 실습을 해보았다

 

이번에는 CPU 리소스 제한 실습을 해보자!

먼저 cpu에 대한 정보를 확인해보자

$ lscpu

CPU가 2코어인 것을 알 수 있다

CPU가 2코어이면 cpu set는 0번과 1번으로 구성된다

 

이제 cpu를 할당해서 컨테이너를 생성해보자

$ docker run --cpuset-cpus 1 --name c1 -d stress:latest stress --cpu 1

stress:latest 컨테이너 이미지를 데몬으로 실행하되, 1번째 cpu만을 사용하는 c1이라는 이름으로 컨테이너가 생성되었다

이 컨테이너를 생성하고 stress --cpu 1 이라는 명령으로 cpu 1코어 만큼의 부하를 주는 명령을 실행하는 것이다

그럼 확인 해보자

$ htop

설치가 안되어 있다면

$ sudo apt-get install htop

으로 설치하자

이렇게 1번째(2라고 표시된) CPU가 100퍼센트 사용 중인 것을 확인할 수 있다

F10을 눌러서 빠져나오자

 

그리고 터미널에서 아래 명령으로 alias 설정을 하나 해주도록 하자

$ alias crm='docker rm -f $(docker ps -aq)'

위 명령은 모든 컨테이너를 삭제하는 명령이다

그리고 crm 명령으로 컨테이너를 삭제하자

 

 

이번에는 0번째 CPU에 부하를 줘보자

$ docker run --cpuset-cpus 0 --name c1 -d stress:latest stress --cpu 1

htop 명령으로 cpu 사용률을 확인해보자

$ htop

이번엔 0번째(1이라고 표시된) CPU의 사용률이 100퍼센트인 것을 볼 수 있다

다시 빠져나와서 crm 명령으로 컨테이너를 삭제하자

이렇게 원하는 CPU에 컨테이너를 할당할 수 있다

 

이번에는 --cpu-shares 옵션을 사용해보자

아래 명령들을 입력하자

$ docker run -c 2048 --name cload1 -d stress:latest
$ docker run --name cload2 -d stress:latest # 기본값은 1024
$ docker run -c 512 --name cload3 -d stress:latest
$ docker run -c 512 --name cload4 -d stress:latest

그리고 이번엔 htop 명령이 아닌 docker stats 명령으로 리소스 사용량을 확인해보자

$ docker stats [컨테이너 이름] # 컨테이름을 명시하지 않으면 모든 컨테이너의 리소스 사용량을 보여줌

그런데 뭔가 이상하다....

강사님은 cload1이 100%, cload2가 50%, cload3과 cload4가 각각 25%로 나오는데

나는 0%에서 2000%까지 들쑥날쑥하다....

왜 이러는 걸까

아무리 찾아봐도 모르겠다...

이 부분은 좀 더 찾아보고 해결해야겠다ㅠㅠ

 

 

이번엔 Block I/O 제한 실습을 해보자

일단 시작하기에 앞서 lsblk 명령으로 디스크 이름을 찾아보자

$ lsblk

나는 sda로 되어 있지만, 강사님은 xvda로 되어 있으시다

확인을 잘 해봐야할 것 같다

먼저 아래 명령을 진행해보자

$ docker run -it --rm --device-write-iops /dev/sda:10 ubuntu:18.04 /bin/bash

그러면 컨테이너 생성 및 실행됨과 동시에 컨테이너 내부로 진입하게 된다

그 안에서 아래 명령으로 파일 I/O 시간을 테스트 해보자

dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct

그러면 초당 5.8mb의 속도가 나오는 것을 알 수 있다

이번에는 디스크 속도를 10에서 100으로 바꿔줘보자

먼저 컨테이너를 빠져 나오고

exit
docker run -it --rm --device-write-iops /dev/sda:100 ubuntu:18.04 /bin/bash
dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct

초당 약 90mb의 속도가 나오는 것을 알 수 있다

 

 

 

== cAdvisor ==

cAdvisor

위 링크로 들어가면 cAdvisor의 깃허브 웹 페이지가 뜬다

스크롤을 아래로 내리다 보면 Quick Start Running cAdvisor in a Docker Container 라는 제목이 있을거다

여기서 코드부분을 복사해서 그대로 리눅스 터미널에 복사해주면 된다

VERSION=v0.36.0 # use the latest release version from https://github.com/google/cadvisor/releases
sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  --device=/dev/kmsg \
  gcr.io/cadvisor/cadvisor:$VERSION

이제 cAdvisor의 대시보드를 확인해볼 건데 웹 페이지로 접속을 해야 한다

localhost:8080 으로 접속하면 된다

 

만약 접속이 안된다면 아래 절차를 따라해보자

먼저 Virtual Box의 파일 - 환경 설정 - 네트워크 로 들어가자

그리고 설정되어 있는 NAT 네트워크를 더블클릭 하고 포트포워딩 버튼을 누르자

그리고 한 줄을 추가 해서

호스트IP = 127.0.0.1

호스트포트 = 8080

게스트IP = 10.100.0.105

게스트포트 = 8080

으로 설정하고 확인, 확인, 확인 하면 설정이 반영될 것이다

 

localhost:8080으로 접속하면 cAdvisor 웹 페이지가 뜬다

 

컨테이너들에 대한 리소스 사용량이나 다양한 정보를 실시간 대시보드 형식으로 확인할 수 있다

 

이번 챕터는 여기서 끝마치도록 하자!

오늘도 고생 많았어

힘들더라도 화이팅하길 바랄게

안녕