컨테이너 CPU 제한
docker run -i -t --name cpu_share \
--cpu-shares 1024 \
ubuntu:14.04
--cpu-shares: 컨테이너에 가중치를 설정해 해당 컨테이너가 CPU를 상대적으로 얼마나 사용할 수 있는지를 나타냄.
즉, 컨테이너에 CPU를 한 개씩 할당하는 방식이 아닌, 시스템에 존재하는 CP를 어느 비중만큼 나눠 쓸지 명시하는 옵션.
아무것도 설정하지 않으면 1024, CPU 할당에서는 1의 비중을 가짐.
docker run -i -t --name cpu_1024 \
--cpu-shares 1024 \
alice/stress \
stress --cpu 1
1개의 프로세스로 CPU에 부하를 주는 명령어를 설정했습니다.
이렇게 설정하면 --cpu-shares 값이 1024로 설정됐지만,
호스트에 다른 컨테이너가 존재하지 않기 때문에 CPU를 100% 사용하게 됩니다.
그렇다면 --cpu-shares의 값이 512로 설정된 컨테이너가 같이 실행된다면 어떻게 될까요?
두 컨테이너가 각각 69%, 33%의 CPU를 사용하고 있으며,
즉 1024 : 512, 약 2:1의 비율로 시스템의 CPU를 사용하는 것을 알 수 있습니다.
이처럼 --cpu-shares에 설정된 값의 비율에 따라 컨테이너가 CPU를 사용할 수 있는 비율이 정해집니다.
--cpuset-cpu: CPU가 여러 개 있을 때, 특정 CPU만 사용하도록 설정
docker run -d --name cpuset_2 \
--cpuset-cpus=2 \
alice/stress \
stress --cpu 1
컨테이너가 3번째 CPU만 사용하도록 설정했습니다.
htop을 사용하면 CPU별로 사용량을 확인할 수 있습니다.
우분투: apt-get install htop
CentOS: yum -y install epel-release && yum -y install htop
컨테이너의 CFS(Completely Fair Scheduler) 주기는 기본적으로 100ms로 설정되지만 run 명령어의 옵션 중 --cpu-period와 --cpu-quota로 이 주기를 변경할 수 있습니다.
docker run -d --name quota_1_1 \
--cpu-period=100000 \
--cpu-quota=100000 \
alice \
stress \
--cpu 1
--cpu-period: 기본적으로 100000(= 100ms)
--cpu-quota: --cpu-period에 설정된 시간 중 CPU 스케줄링에 얼마나 할당할 것인지를 설정
위의 예시는 100000 중 25000만큼 할당해 CPU 주기가 1/4로 줄었으므로,
일반적인 컨테이너 CPU 성능보다 1/4 감소합니다.
즉, 컨테이너는 [--cpu-quota 값] / [--cpu-period 값]만큼 CPU 시간을 할당받습니다.
--cpus: CPU의 개수를 직접 지정하는 옵션
ex) --cpus=0.5 = --cpu-period=100000 = --cpu-quota=50000
즉, CPU의 약 50%를 점유하게 됩니다.
Block I/O 제한
컨테이너 생성시 설정을 하지 않으면 내부에서 파일을 읽고 쓰는 대역폭에 제한이 설정되지 않습니다.
하나의 컨테이너가 블록 입출력을 과도하게 사용하지 않게 run 명령어에서 옵션을 설정할 수 있습니다.
- --device-write-bps
- --device-read-bps
- --device-write-iops
- --device-read-iops
이 옵션들을 통해 블록입출력을 제한할 수 있습니다.
하지만 Direct I/O의 경우에만 블록 입출력이 제한되며, Buffered I/O는 제한되지 않습니다.
--device-write-bps, --device-read-bps는 쓰고 읽는 작업을 초당 제한으로 설정하며, kb, mb, gb 단위로 설정할 수 있습니다.
docker run -it \
--device-write-bps /dev/xvda:1mb \
ubuntu:14.04
초당 쓰기 작업의 최대치가 1MB로 제한된 컨테이너를 만들었습니다.
그리고 이 컨테이너에서 10MB의 파일을 Direct I/O를 통해 쓰기 작업을 수행했습니다.
CPU 자원 할당에서 --cpu-share에 상대적인 값을 입력했던 것처럼
--device-write-iops, --device-read-iops에도 상대적인 값을 입력합니다.
docker run -it \
--device-write-iops /dev/xvda:5 \
ubuntu:14.04
docker run -it \
--device-write-iops /dev/xvda:10 \
ubuntu:14.04
이처럼 2배 차이 나는 컨테이너를 쓰기 작업을 수행하면 수행 시간 또한 약 5MB/s에서 10MB/s로 2배가량 차이 나는 것을 알 수 있습니다.
스토리지 드라이버와 컨테이너 저장 공간 제한
도커 엔진은 컨테이너 내부의 저장공간을 제한하는 기능을 제공하지 않지만,
스토리지 드라이버나 파일 시스템 등 특정 조건을 만족하면 이 기능을 사용할 수 있습니다.
하지만 모든 스토리지 드라이버에서 컨테이너의 저장공간을 제한할 수 있는 것은 아닙니다.
컨테이너 애플리케이션이 해당스토리지 드라이버에 적합하지 않다면 이 기능을 사용하지 않는 것이 좋습니다.
또한 컨테이너 내부에서 개발중이거나 특별한 상황이 아니라면 stateful한 것은 그다지 바람직하지 않습니다.
따라서 컨테이너의 저장 공간을 제한하지 않는다는 선택지도 고려할 수 있습니다.
도커 이미지
모든 컨테이너는 이미지를 기반으로 생성되므로 이미지를 다루는 방법은 도커 관리에서 중요합니다.
이미지의 이름을 구성하는 저장소, 이미지 이름, 태그 뿐만 아니라 이미지의 생성, 삭제, 구조는 어떻게 돼 있는지 아는 것 또한 중요합니다.
그러기 위해 이미지를 관리하는 기본적인 방법을 살펴보겠습니다.
데비안 OS의 apt-get install, 레드헷 OS의 yum install을 통해 패키지를 내려받듯,
도커는 기본적으로 도커 허브(Docker Hub)라는 중앙 이미지 저장소에서 이미지를 내려받습니다.
도커 허브: 도커가 공식적으로 제공하고 있는 이미지 저장소.
도커 계정을 가지고 있다면 누구든지 이미지를 올리고, 내려받을 수 있기 때문에 다른 사람들에게 이미지를 쉽게 공유할 수 있습니다.
docker create, run, pull의 명령어로 이미지를 내려받을 때, 도카는 도커 허브에서 해당 이미지를 검색한 뒤 내려받습니다.
대부분의 이미지는 도커 허브에서 공식적으로 제공하거나(ubuntu, centos 등),
다른 사람들이 더커 허브에 이미 올려놓은 경우(Apache Tomcat, Hadoop 등)가 대부분이라서 애플리케이션 이미지를 직접 만들지 않아도 쉽게 사용할 수 있다는 장점이 있습니다.
하지만 도커 허브는 누구나 이미지를 올릴 수 있기 때문에 공식 라벨이 없는 이미지는 사용법을 찾을 수 없거나 제대로 동작하지 않을 수 있습니다. 또한 이미지 저장소를 다른 사람들에게 공개하지 않기 위해 private 저장소를 사용하려면 요금을 지불해야 합니다.
도커 허브에 어떤 이미지가 있는지 확인하기 위해 도커 허브 사이트를 직접 접속해서 찾아볼 수도 있지만 도커 엔진에서 docker search 명령어를 사용할 수도 있습니다.
이처럼 ubuntu 이미지도 여러 종류가 있음을 알 수 있습니다.
STARS는 해당 이미지가 도커 사용자로부터 얼마나 즐겨찾기 됐는지 알 수 있습니다.
도커 이미지 생성
docker search를 통해 검색한 이미지를 pull 명령어를 사용해 내려받을 수도 있지만,
도커로 개발하는 많은 경우에는 컨테이너에 애플리케이션을 위한 특정 개발 환경을 직접 구축한 뒤, 사용자만의 이미지를 생성합니다.
그럼 컨테이너 안에서 작업한 내용을 이미지로 만들어 보겠습니다.
docker run -it --name commit_test ubuntu:14.04
echo test_first! >> first
docker commit \
-a "alice" -m "my first commit" \
commit_test \
commit_test:first
commit_test라는 이름에 컨테이너를 만들고 first라는 파일을 만들었습니다.
그리고 commit 명령어를 사용해 commit_test 컨테이너를 이미지로 만들었습니다.
저장소 이름은 입력하지 않아도 상관없지만, 태그를 입력하지 않으면 자동으로 latest로 설정됩니다.
위와 같이 설정할 경우 이미지의 이름은 commit_test, 태그는 first로 설정됩니다.
-a: author를 뜻하며, 이미지의 작성자를 나타내는 메타데이터를 이미지에 포함시킵니다.
-m: 커밋 메시지를 뜻하며, 이미지에 포함될 부가 설명을 입력합니다.
commit_test 라는 이름에 first라는 태그로 이미지가 생성됐습니다.
이번에는 만든 이미지로 새로운 컨테이너를 생성해 보겠습니다.
docker run -it --name commit_test2 commit_test:first
echo test_second! >> second
docker commit \
-a "alice" -m "my second commit" \
commit_test2 \
commit_test2:second
commit_test를 사용해 새로운 컨테이너를 생성했습니다.
그리고 이를 통해 또 새로운 이미지를 생성했습니다.
docker images 명령어를 통해 이미지가 잘 만들어진 걸 확인할 수 있습니다.
'Docker&Kubernetes' 카테고리의 다른 글
[Docker] 도커 엔진 (컨테이너 로깅, logs, syslog, memory) (0) | 2024.03.01 |
---|---|
[Docker] 도커 엔진 (Volume, network, bridge, MacVLAN) (0) | 2024.02.21 |
[Docker] 도커 엔진 (feat. docker 명령어) (1) | 2024.02.04 |
[Docker] 도커란? (1) | 2024.01.19 |