Docker 톺아보기 16탄 - Docker 컨테이너 리소스 관리하기 (실습편)
이번 챕터에서는 컨테이너의 리소스를 관리하는 실습을 진행해보도록 하겠다!
이번 챕터의 목차!
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의 깃허브 웹 페이지가 뜬다
스크롤을 아래로 내리다 보면 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 웹 페이지가 뜬다
컨테이너들에 대한 리소스 사용량이나 다양한 정보를 실시간 대시보드 형식으로 확인할 수 있다
이번 챕터는 여기서 끝마치도록 하자!
오늘도 고생 많았어
힘들더라도 화이팅하길 바랄게
안녕
