Framework and Tool/Docker

Docker resource constraints

ocwokocw 2023. 6. 18. 14:04

- 출처: 시작하세요! 도커/쿠버네티스 - 컨테이너 자원 할당 제한

- 출처: https://docs.docker.com/config/containers/resource_constraints/

 

- 개요

기본적으로 container는 자원 사용량에 제한이 없다. Docker는 docker run 명령어 option을 통해 memory, CPU를 얼마나 사용할지 설정하는 기능을 제공한다.

이런 기능들을 사용하기 위해서는 kernel이 Linux capabilities(프로세스의 권한을 제어하는 기능)을 제공해야 한다. docker info 명령어를 실행했을 때 kernel이 기능을 제공하지 않는다면 WARNING: No swap limit support와 같은 메시지를 보게될 수 있다.


- Memory

실행중인 container가 host machine의 memory를 너무 많이 소비하지 않도록 제어하는것은 중요하다. Linux 에서 kernel이 중요한 system function을 수행하는데 메모리가 충분하지 않으면 OOME가 발생하면서 memory 확보를 위해 process들을 죽이기 시작한다. Docker도 예외 대상은 아니며 이렇게 되면 system이 down되는 사태가 발생한다.

 

Docker는 Docker deamon의 OOM 우선순위를 조정해서 다른 process들 보다 종료 우선순위가 낮도록 하여 이런 위험을 회피하려고 시도한다. OOM 우선순위는 container에는 적용되지 않는다. 때문에 container는 Docker daemon이나 다른 process보다 종료될 가능성이 높아진다. 여기까지 숙지하고 나서 container를 살려보겠다고 daemon이나 container에 --oom-score-adj 를 음수값으로 서정하거나, container에 --oom-kill-disable을 설정해서는 안된다.

OOME 때문에 발생하는 시스템 불안정성을 완화하려면

  • memory 요구랑을 파악하기 위한 test 수행
  • application이 요구하는 자원을 만족하는 host 에서만 실행되는지 확인
  • container가 사용할 수 있는 자원 사용량 제한
  • swap은 memory보다 느리지만 system memory 부족에 대한 buffer를 제공할 수 있는점을 숙지

Docker는 주어진 user나 system memory 이상을 사용할 수 없도록 hard limit을 설정하거나, 특정 조건을 만족하지 않는다면 필요한 만큼 memory를 사용하도록 허락하는 soft limit을 설정할 수 있다.

 

- memory swap details

--memory-swap: --memory가 설정되어 있을 때만 의미가 있다. 요구량을 초과한 memory를 disk에 쓰도록 swap을 사용한다. 물론 memory대신 disk를 사용할 때 성능 penalty가 존재한다.

  • 만약 --memory-swap="1g"이고 --memory="300m" 으로 설정했다면 container는 300m memory와 700m(1g - 300m) swap을 사용한다.
  • --memory-swap과 --memory가 같으면 swap을 사용하지 않는다.
  • --memory="300m"이고 --memory-swap이 설정되어 있지 않으면 --memory 만큼 swap을 사용한다. 따라서 container는 총 600m의 memory와 swap을 사용한다.

- kernel memory details

kernel memory 제한은 container에 할당된 전체 memory로 표현된다.

  • unlimited memory, unlimited kernel memory: default 설정
  • unlimited memory, limited kernel memory: 모든 cgroup 에서 필요한 memory가 host machine에 실제로 존재하는 memory 보다 클때 적합한 설정이다. kernel memory가 host machine에서 사용가능한 memory를 초과하지 않도록 설정하면 더 많은 memory가 필요한 container는 대기해야 한다.
  • limited memory, unlimited kernel memory: 전체 memory는 제한되지만 kernel memory는 제한이 없다.
  • limited memory, limited kernel memory: user와 kernel memory를 둘다 제한하는 설정은 memory 사용량 문제를 파악할 때 유용하다. 만약 container가 예상치 못한 유형의 memory를 사용하거나 그 이상의 memory를 사용하면 다른 container나 host machine에 영향을 주지 않고 memory를 소모하게 된다. 이런 상황에서 만약 kernel memory limit이 user memory limit 보다 작으면 kernel memory가 부족하게 되어 container에서 OOM이 발생한다. 그 반대라면 container에서 OOM이 발생하지 않는다.

- CPU

기본적으로 각 container가 host machine CPU 사용할때에는 제한이 없다. 대부분의 user는 기본 CFS scheduler를 사용하지만 realtime scheduler도 사용가능하다.

 

- default CFS scheduler

CFS는 일반적인 Linux process들을 위한 Linux kernel CPU scheduler이다. 1개의 CPU를 갖고 있다고 가정했을 때 아래 명령어들은 매초마다 container가 최대 50% CPU를 사용할 수 있도록 보장해준다.

docker run -it --cpus=".5" ubuntu /bin/bash

docker run -it --cpu-period=100000 --cpu-quota=50000 ubuntu /bin/bash

 

- realtime scheduler

Container가 CFS scheduler를 사용할 수 없는 작업의 경우 realtime scheduler를 사용하도록 설정할 수 있다. Docker daemon이나 container를 설정하기 전에 host machine의 kernel이 올바르게 구성되어 있는지 확인해야 한다.

 

CPU scheduling 및 우선순위 설정은 고급 kernel 수준의 기능이기 때문에 일반적인 사용자가 설정할일은 잘 없다. 이런 설정은 잘못하면 host system을 불안정하게 하거나 심지어 사용할 수 없게 만들 수 있다.

 

만약 관심이 있다면 https://docs.docker.com/config/containers/resource_constraints/ 문서를 참조하자.