[Docker] 효율적인 도커 자원 할당: CPU와 메모리 제어하기

728x90
반응형

1. 자원 사용에 대한 제약

1) 볼륨에 대한 자원 사용 확인

  • 리눅스에서 자원 사용량을 확인: `df -h`
  • 컨테이너 내부에서도 동일한 명령을 수행: `docker exec -it apache2 /bin/bash`

현재 컨테이너의 자원 사용 가능 사이즈와 호스트 컴퓨터의 자원 사용 가능 사이즈가 동일하다.


2) 리눅스 자원 모니터링

  • top: 리눅스 전체의 자원 소비량과 개별 액티브 프로세스의 자원 사용량을 보여준다.

  • htop: top보다 향상된 UI와 기능을 제공하는 자원 사용량 모니터링 도구

  • sar(system active report): 다양한 옵션을 이용하여 시스템 전반의 사용량을 세부적으로 모니터링할 수 있으며, 쉘 스크립트에 포함하여 사용할 수 있다. `sysstat` 패키지를 별도로 설치해야 한다.
sar 2 10  # 2초마다 10번 데이터 수집

  • iostat, df: 디스크 성능 지표를 수집
    • `iostat`는 `sar` 사용법이 동일
  • vmstat, free: 메모리 성능 측정
    • vmstat는 `sar` 사용법이 동일하고 `free -mt` 명령으로 마지막 사용량을 MB 단위로 표시
  • dstat: 시스템 전반의 자원 사용량에 대한 모니터링 제공, `dstat`를 별도 설치
    • `dstat` 명령으로 수행
  • iptraf-ng: 유입되는 네트워크 인터페이스별 패킷 양, 프로토콜 등을 통해서 네트워크 트래픽 모니터링
    • `iptraf-ng`를 별도로 설치 후, `iptraf-ng` 명령으로 수행

위의 도구들을 이용해서 서버 자원을 모니터링 하면 예방적 차원의 관리 작업과 효율성을 확인할 수 있다.


3) 자원 할당 제어

`docker run` 또는 `docker create` 명령어를 사용할 때 자원 할당 제어를 사용하지 않으면 생성된 컨테이너는 호스트 운영체제의 모든 자원을 자유롭게 사용하게 되며, 과도한 자원 사용이 발생할 수 있다.

클라우드 네이티브 환경에서는 컨테이너가 소규모 애플리케이션 서비스로 사용되는데, 잘못된 설정으로 인해 시스템에 부하를 유발하면 다른 컨테이너의 동작과 호스트 운영체제에 영향을 줄 수 있다.

도커는 여러 런타임 제약 옵션을 제공하며, 컨테이너 생성 후에도 `docker update` 명령어로 변경할 수 있다.

리소스 런타임 제약은 리눅스 커널의 `cgroup` 기능을 통해 설정할 수 있다.


4) cgroup 확인

`cgroup` 설정을 확인하려면 다음 명령어를 사용한다:

grep cgroup /proc/mounts
docker info | grep Cgroup

5) 메모리 제약 설정

nginx 이미지에 메모리 100MB를 할당한 컨테이너를 생성하려면 다음과 같은 명령어를 사용한다:

  • 할당
docker run -d --memory=100m --name=nginx_100m nginx
  • 확인
docker inspect nginx_100m | grep "Memory"

 

만약 우분투에서 문제가 발생하면 아래 명령어를 순서대로 수행하여 설정을 변경한다:

GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
sudo update-grub  # 변경 내용 적용
sudo reboot  # 재부팅

그 후 `sudo vi /etc/default/grub` 를 수행해서 파일을 열어 아래 값을 수정한다.


6) CPU 제약 설정

  • `--cpus`: 1개의 cpu 인 경우는 비율이 되고 여러 개의 cpu 인 경우는 개수
    • `--cpus=0.2`: 1개인 경우는 20%를 사용
    • `--cpus=1.5`: 여러 개 인 경우 1.5개를 사용
  • `--cpu-period`: 기간 제한 옵션으로 컨테이너의 CFS는 밀리세컨드 단위로 지정
    • `--cpu-period=100000` 의 형태로 지정
  • `--cpu-quota`: 시간 할당량
    • `--cpu-quota=50000`의 형태로 지정하는데 `--cpu-period` 와 같이 사용
  • `--cpuset-cpus`: 여러 개의 cpu 인 경우 특정 cpu의 코어 번호를 이용해서 할당
    • `--cpuset-cpus=”0,3”`: 0번 과 3번 코어 이용
    • `--cpuset-cpus=”0-2”`: 0, 1, 2번 코어 사용
  • `--cpu-shares`: 공평한 스케쥴링을 원칙으로 하여 가중치를 부여할 수 있다.

cpu 제약 실습

아래 명령어로 CPU 제약을 설정한 컨테이너를 실행해보자:

docker run -d --name cpu_1024 --cpu-shares 1024 leecloudo/stress:1.0 stress --cpu 4
docker run -d --name cpu_512 --cpu-shares 512 leecloudo/stress:1.0 stress --cpu 4

테스트 시에는 무한 루프를 동작하는 애플리케이션을 만들어 확인할 수 있다.
2개 이상의 컨테이너를 실행하면 일련번호 형태의 프로세스 ID가 생성된다.

ps -aux | grep stress | grep -v grep


7) 메모리 사용량 제한

메모리

  • 메모리는 물리적인 메모리와 스왑 메모리(가상 메모리)로 나뉜다.
  • 물리적인 메모리는 실제 메모리 크기를 의미하고, 스왑 메모리는 메모리가 부족할 때 하드디스크의 일정 부분을 빌려와서 사용하는 메모리
  • 일반적으로 스왑 메모리는 물리적 메모리의 두 배로 설정하지만, 이를 사용하면 속도가 느려진다. 

옵션

  • `memory` 또는 `-m`: 물리적인 메모리의 최댓값을 설정하며, 최솟값은 4MB
  • `memory-swap`: 스왑할 수 있는 메모리 양을 지정. 0은 컨테이너 스왑 사용을 해제, -1이면 무제한
  • `kernel-memory`: 커널 메모리 설정. 모든 cgroup이 필요한 메모리 크기가 장비의 메모리보다 클 때 사용

예를 들어, ubuntu:14.04 이미지를 이용하여 메모리 크기를 1GB로 제한한 컨테이너를 생성하려면:

docker run -it -d --name=ubuntu_1g --memory=1g ubuntu:14.04
docker inspect ubuntu_1g | grep -i memory

메모리 설정이 애플리케이션이 사용하는 양보다 적게 설정되면 오류가 발생할 수 있으며, Kafka를 사용할 때 이러한 오류가 빈번하게 발생한다. Kafka는 기본적으로 1GB 이상의 메모리를 요구하므로, EC2에서 사용할 경우 더 큰 메모리 인스턴스를 선택하거나 Kafka의 메모리 용량을 조절해야 한다.

이와 같이 자원 사용에 대한 제약을 설정하고 모니터링하면, 효율적인 자원 관리와 안정적인 서비스 운영이 가능하다.

 

728x90
반응형