Docker - Resource 제어

Docker

컨테이너 리소스 제한

기본적으로 컨테이너는 HOST 하드웨어 리소스의 제한을 받지 않는다. 즉 컨테이너의 용량 제한을 걸어두지 않으면 HOST 하드웨어 리소스를 모두 사용할 수 있다. 따라서 필요한 만큼의 리소스만 할당해주어야 한다.

Docker command를 통해 제한할 수 있는 리소스

리소스는 docker run의 옵션을 통해 설정할 수 있다.

CPU

--cpus : 컨테이너에 할당할 CPU core 수를 설정한다.

  • docker run -d --cpus=".5" ubuntu:1.14
  • ubuntu 컨테이너가 0.5개의 코어만 사용할 수 있도록 설정한다.

--cpuset-cpus : 컨테이너가 사용할 수 있는 CPU나 코어를 할당해준다.

  • index는 0부터 시작한다.
  • docker run -d --cpuset-cpus 0-3 ubuntu:1.14

--cpu-shares : CPU 비중을 상대적으로 설정한다.

  • 모든 application은 share 값을 1024로 할당한다.
  • 2048로 설정할 시 기본값보다 2배 많은 자원을 할당받는 것이다.
  • docker run -d --cpu-shares 2048 ubuntu:1.14

CPU-예제

아래와 같이 CPU share 값을 각기 다르게 설정하고 컨테이너를 실행시켜보았다. docker ps를 통해 실행 중인 컨테이너 목록을 확인하면 정상적으로 4개의 컨테이너가 실행 중인 것을 볼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
$ docker run -c 2048 --name cload1 -d stress:latest
$ docker run -c 1024 --name cload2 -d stress:latest
$ docker run -c 512 --name cload3 -d stress:latest
$ docker run -c 512 --name cload4 -d stress:latest

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf49f08f0e83 stress:latest "/bin/sh -c 'stress …" 8 seconds ago Up 7 seconds cload4
28d9ff3b113d stress:latest "/bin/sh -c 'stress …" 13 seconds ago Up 11 seconds cload3
a73132273677 stress:latest "/bin/sh -c 'stress …" 22 seconds ago Up 21 seconds cload2
7ce85fb5b7f4 stress:latest "/bin/sh -c 'stress …" 42 seconds ago Up 41 seconds cload1

docker stats 명령어를 통해 실시간으로 각 컨테이너들이 CPU를 얼만큼 점유하고 있는지 확인해보았다.

docker stats

상대적 비율이므로 2048로 설정한 cload1부터 해당 비율만큼 차이를 보이며 cpu를 점유하고 있는 것을 볼 수 있다.


Memory

제한 단위는 b, k, m, g로 할당할 수 있다.

--memory [용량], -m [용량] : 컨테이너가 사용할 최대 메모리 양을 지정해준다.

  • docker run -d -m 512m nginx:1.14
  • nginx:1.14 컨테이너는 최대 512MB를 사용할 수 있다.

--memory-reservaion [용량] : 설정한 값보다 적은 값으로 구성하는 soft 제한 값을 설정한다.

  • docker run -d -m 1g --memory-reservation 500m nginx:1.14
  • 최대 1GB를 사용할 수 있고, 최소 500MB를 보장받을 수 있다.

--memory-swap [용량] : 컨테이너가 사용할 스왑 메모리 영역에 대한 설정

  • default 값은 설정한 메모리의 2배가 설정된다.
  • docker run -d -m 200m --memory-swap 300m nginx:1.14
  • 최대 메모리양은 200MB이며, 300MB는 최대 메모리 + 스왑 메모리 이다.
  • 위에서 스왑 메모리는 100MB이다.

--oom-kill-disable : OOM Killer가 프로세스를 kill하지 못하도록 보호한다.

  • OOM : Out Of Memory
  • Linux 커널은 물리 메모리가 부족하면 OOM Killer를 동작시켜 프로세스를 종료하는 기능을 가지고 있다. 커널이 임의로 프로세스를 종료하지 못하도록 설정하는 것이다.

DISK I/O (Block I/O)

--blkio-weight, --blkio-weight-device : Block IO의 Quota를 설정할 수 있다.

  • 모든 컨테이너는 동작할 때 I/O 스케줄링을 받는다.
  • default 값은 500이며, 100부터 1000까지 설정할 수 있다.
  • device는 device에 대해서만 적용할 때 사용한다.
  • docker run -it --rm --blkio-weight 100 ubuntu:latest /bin/bash

--device-read-bps, --device-write-bps : 특정 device에 대한 읽기 쓰기 작업에 제한값을 설정한다.

  • kb, mb, gb 단위로 설정한다.
  • throughput과 연관이 있다.
  • docker run -it --rm --device-write-bps /dev/vda:10mb ubuntu:latest /bin/bash
  • /dev/vda에 있는 데이터를 읽고 쓸 때는 10mb로 속도를 제한하겠다.

--device-read-iops, --device-write-iops : 초당 속도에 대한 quota를 제한한다.

  • IOPS는 0 이상의 정수로 표기하여야한다.
  • 초당 데이터 전송량 = IOPS * 블럭크기 (단위 데이터 용량) 으로 나타낸다.

Block I/O -예제

컨테이너에서 --device-write-iops를 적용해서 write 속도를 다르게 제한한 후 write를 발생시켰을 때 속도를 비교해보자.

lslbk 명령어를 통해 disk 이름을 확인한 후 실행한다.

  • 예시에서 disk 이름은 xvda이다.

아래 예제 코드는 iops를 설정하고, ubuntu 컨테이너를 실행 후 /bin/bash 를 실행하는 코드입니다.

iops를 10으로 설정했을 때 : 1.01219초 가량이 소요되었으며, 초당 10.3MB를 실행하였다.

1
2
3
4
$ docker run -it --rm --device-write-iops /dev/xvda:10 ubuntu:latest /bin/bash
# 접속 후
# 1M를 10개 만들 때 걸리는 시간이 출력된다
dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct

iops를 100으로 설정했을 때 : 0.0412287초가 소요되었으며, 초당 254MB를 실행하였다.

1
2
3
4
$ docker run -it --rm --device-write-iops /dev/xvda:10 ubuntu:latest /bin/bash
# 접속 후
# 1M를 10개 만들 때 걸리는 시간이 출력된다
dd if=/dev/zero of=file1 bs=1M count=10 oflag=direct

리소스 모니터링

Command

docker stat

docker stats [option] [container...] : 실행 중인 컨테이너의 런타임 통계를 확인한다.

docker events : 도커 호스트의 실시간 event 정보를 수집해서 출력해준다.

  • container, image, volume, network 등 컨테이너와 관련된 event를 출력한다.
  • docker events -f container=<MAME>

Application

cAdvisor

google에서 만든 docker 모니터링 도구이다.

Author

Inwoo Jeong

Posted on

2022-01-13

Updated on

2022-01-14

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

댓글