컨테이너 실행하기
컨테이너 실행하기 (Running containers)
Docker는 격리된 컨테이너 안에서 프로세스를 실행해요. 컨테이너는 호스트에서 실행되는 하나의 프로세스예요. 호스트는 로컬이거나 원격일 수 있어요. docker run을 실행하면 실행되는 컨테이너 프로세스는 고유한 파일시스템, 고유한 네트워킹, 그리고 호스트와 분리된 고유한 프로세스 트리를 갖는 격리된 환경이에요.
이 페이지는 docker run 명령으로 컨테이너를 실행하는 방법을 자세히 설명해요.
출처: 문서
본문
일반적인 형식 (General form)
docker run 명령은 다음 형식을 취해요:
$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
docker run 명령은 컨테이너를 만들 이미지 레퍼런스를 지정해야 해요.
이미지 레퍼런스 (Image references)
이미지 레퍼런스는 이미지의 이름과 버전이에요. 이미지 레퍼런스를 사용해 이미지 기반의 컨테이너를 만들거나 실행할 수 있어요.
docker run IMAGE[:TAG][@DIGEST]docker create IMAGE[:TAG][@DIGEST]
이미지 태그는 이미지 버전이며, 생략하면 기본값 latest예요. 태그를 사용해 이미지의 특정 버전으로 컨테이너를 실행해요. 예를 들어 ubuntu 이미지 버전 24.04를 실행하려면 docker run ubuntu:24.04라고 입력해요.
이미지 다이제스트 (Image digests)
v2 이상 이미지 형식을 사용하는 이미지는 다이제스트(digest)라고 하는 콘텐츠 주소 지정 식별자를 가져요. 이미지를 생성하는 데 사용된 입력이 변경되지 않는 한 다이제스트 값은 예측 가능해요.
다음 예시는 sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 다이제스트의 alpine 이미지로 컨테이너를 실행해요:
$ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date
옵션 (Options)
[OPTIONS]는 컨테이너의 옵션을 구성할 수 있게 해줘요. 예를 들어 컨테이너에 이름을 주거나(--name), 백그라운드 프로세스로 실행할 수 있어요(-d). 리소스 제약과 네트워킹 같은 것을 제어하는 옵션도 설정할 수 있어요.
명령과 인자 (Commands and arguments)
[COMMAND]와 [ARG...] 위치 인자를 사용해 컨테이너가 시작될 때 실행할 명령과 인자를 지정할 수 있어요. 예를 들어 -i와 -t 플래그와 함께 [COMMAND]로 sh를 지정하면 컨테이너에서 대화형 셸을 시작할 수 있어요(선택한 이미지에 PATH에 sh 실행 파일이 있는 경우).
$ docker run -it IMAGE sh
Note Docker 시스템 구성에 따라
docker run명령 앞에sudo를 붙여야 할 수도 있어요.docker명령에sudo를 사용하지 않으려면 시스템 관리자가docker라는 Unix 그룹을 만들고 사용자를 그 그룹에 추가할 수 있어요. 이 구성에 대한 자세한 내용은 운영 체제에 맞는 Docker 설치 문서를 참고하세요.
포그라운드와 백그라운드 (Foreground and background)
컨테이너를 시작하면 기본적으로 포그라운드에서 실행돼요. 대신 백그라운드에서 실행하려면 --detach(또는 -d) 플래그를 사용할 수 있어요. 이 플래그는 터미널 창을 점유하지 않고 컨테이너를 시작해요.
$ docker run -d <IMAGE>
컨테이너가 백그라운드에서 실행되는 동안 다른 CLI 명령으로 컨테이너와 상호작용할 수 있어요. 예를 들어 docker logs로 컨테이너 로그를 볼 수 있고, docker attach로 포그라운드로 가져올 수 있어요.
$ docker run -d nginx
0246aa4d1448a401cabd2ce8f242192b6e7af721527e48a810463366c7ff54f1
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0246aa4d1448 nginx "/docker-entrypoint.…" 2 seconds ago Up 1 second 80/tcp pedantic_liskov
$ docker logs -n 5 0246aa4d1448
2023/11/06 15:58:23 [notice] 1#1: start worker process 33
2023/11/06 15:58:23 [notice] 1#1: start worker process 34
2023/11/06 15:58:23 [notice] 1#1: start worker process 35
2023/11/06 15:58:23 [notice] 1#1: start worker process 36
2023/11/06 15:58:23 [notice] 1#1: start worker process 37
$ docker attach 0246aa4d1448
^C
2023/11/06 15:58:40 [notice] 1#1: signal 2 (SIGINT) received, exiting
...
포그라운드·백그라운드 모드와 관련된 docker run 플래그에 대한 자세한 내용은 다음을 참고하세요:
docker run --detach: 컨테이너를 백그라운드로 실행docker run --attach:stdin,stdout,stderr에 연결docker run --tty: pseudo-tty 할당docker run --interactive: 연결되지 않아도stdin을 열어 둠
백그라운드 컨테이너에 다시 연결하는 방법은 docker attach를 참고하세요.
컨테이너 식별 (Container identification)
컨테이너는 세 가지 방법으로 식별할 수 있어요:
| Identifier type | Example value |
|---|---|
| UUID long identifier | f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778 |
| UUID short identifier | f78375b1c487 |
| Name | evil_ptolemy |
UUID 식별자는 데몬이 컨테이너에 할당하는 무작위 ID예요.
데몬은 컨테이너에 자동으로 무작위 문자열 이름을 생성해요. the --name flag를 사용해 사용자 지정 이름을 정의할 수도 있어요. name을 정의하는 것은 컨테이너에 의미를 부여하는 편리한 방법일 수 있어요. name을 지정하면 사용자 정의 네트워크에서 컨테이너를 참조할 때 그것을 사용할 수 있어요. 이는 백그라운드와 포그라운드 Docker 컨테이너 모두에서 동작해요.
컨테이너 식별자는 이미지 레퍼런스와 같은 것이 아니에요. 이미지 레퍼런스는 컨테이너를 실행할 때 사용할 이미지를 지정해요. docker exec nginx:alpine sh를 실행해 nginx:alpine 이미지 기반 컨테이너에서 셸을 열 수는 없어요. docker exec는 이미지가 아닌 컨테이너 식별자(이름 또는 ID)를 기대하기 때문이에요.
컨테이너가 사용하는 이미지는 컨테이너의 식별자가 아니지만, --filter 플래그를 사용해 이미지를 사용하는 컨테이너의 ID를 찾을 수 있어요. 예를 들어 다음 docker ps 명령은 nginx:alpine 이미지 기반의 실행 중인 모든 컨테이너의 ID를 가져와요:
$ docker ps -q --filter ancestor=nginx:alpine
필터 사용에 대한 자세한 내용은 Filtering을 참고하세요.
컨테이너 네트워킹 (Container networking)
컨테이너는 기본적으로 네트워킹이 활성화되어 있고 나가는 연결을 만들 수 있어요. 서로 통신해야 하는 여러 컨테이너를 실행 중이라면 사용자 정의 네트워크를 만들고 컨테이너를 네트워크에 연결할 수 있어요.
여러 컨테이너가 같은 사용자 정의 네트워크에 연결되면 컨테이너 이름을 DNS 호스트 이름으로 사용해 서로 통신할 수 있어요. 다음 예시는 my-net이라는 사용자 정의 네트워크를 만들고 네트워크에 연결되는 두 컨테이너를 실행해요.
$ docker network create my-net
$ docker run -d --name web --network my-net nginx:alpine
$ docker run --rm -it --network my-net busybox
/ # ping web
PING web (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.326 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.257 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.281 ms
^C
--- web ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.257/0.288/0.326 ms
컨테이너 네트워킹에 대한 자세한 내용은 Networking overview를 참고하세요.
파일시스템 마운트 (Filesystem mounts)
기본적으로 컨테이너의 데이터는 임시적이고 쓰기 가능한 컨테이너 레이어에 저장돼요. 컨테이너를 제거하면 그 데이터도 제거돼요. 컨테이너에 영구 데이터를 사용하려면 파일시스템 마운트를 사용해 호스트 시스템에 데이터를 영구 저장할 수 있어요. 파일시스템 마운트는 컨테이너와 호스트 간에 데이터를 공유하게도 해줘요.
Docker는 두 가지 주요 마운트 범주를 지원해요:
- 볼륨 마운트 (Volume mounts)
- 바인드 마운트 (Bind mounts)
볼륨 마운트는 컨테이너 데이터를 영구 저장하고 컨테이너 간에 데이터를 공유하는 데 훌륭해요. 반면 바인드 마운트는 컨테이너와 호스트 간에 데이터를 공유하기 위한 것이에요.
docker run 명령의 --mount 플래그를 사용해 컨테이너에 파일시스템 마운트를 추가할 수 있어요.
다음 섹션에서는 볼륨과 바인드 마운트를 만드는 기본 예시를 보여줘요. 더 심층적인 예시와 설명은 문서의 storage section을 참고하세요.
볼륨 마운트 (Volume mounts)
볼륨 마운트를 만들려면:
$ docker run --mount source=<VOLUME_NAME>,target=[PATH] [IMAGE] [COMMAND...]
이 경우 --mount 플래그는 source와 target 두 매개변수를 가져요. source 매개변수의 값은 볼륨의 이름이에요. target의 값은 컨테이너 안에서 볼륨의 마운트 위치예요. 볼륨을 만들면 컨테이너를 중지하거나 제거해도 볼륨에 쓴 데이터는 유지돼요:
$ docker run --rm --mount source=my_volume,target=/foo busybox \
echo "hello, volume!" > /foo/hello.txt
$ docker run --mount source=my_volume,target=/bar busybox
cat /bar/hello.txt
hello, volume!
target은 항상 /src/docs 같은 절대 경로여야 해요. 절대 경로는 /(슬래시)로 시작해요. 볼륨 이름은 영숫자 문자로 시작하고 뒤에 a-z0-9, _(밑줄), .(마침표) 또는 -(하이픈)가 와야 해요.
바인드 마운트 (Bind mounts)
바인드 마운트를 만들려면:
$ docker run -it --mount type=bind,source=[PATH],target=[PATH] busybox
이 경우 --mount 플래그는 세 매개변수를 가져요. 타입(bind)과 두 경로. source 경로는 컨테이너로 바인드 마운트하려는 호스트의 위치예요. target 경로는 컨테이너 안의 마운트 대상이에요.
기본적으로 바인드 마운트는 source 경로가 데몬 호스트에 존재해야 해요. source 경로가 존재하지 않으면 오류가 반환돼요. 데몬 호스트에 source 경로가 없을 때 만들려면 bind-create-src 옵션을 사용해요:
$ docker run -it --mount type=bind,source=[PATH],target=[PATH],bind-create-src busybox
바인드 마운트는 기본적으로 읽기-쓰기여서 컨테이너에서 마운트된 위치로 파일을 읽고 쓸 수 있어요. 파일 추가나 편집 같은 변경 사항은 호스트 파일시스템에 반영돼요:
$ docker run -it --mount type=bind,source=.,target=/foo busybox
/ # echo "hello from container" > /foo/hello.txt
/ # exit
$ cat hello.txt
hello from container
종료 상태 (Exit status)
docker run의 종료 코드는 컨테이너가 실행에 실패한 이유나 종료된 이유에 대한 정보를 줘요. 다음 섹션에서 다양한 컨테이너 종료 코드 값의 의미를 설명해요.
125
종료 코드 125는 오류가 Docker 데몬 자체에 있음을 나타내요.
$ docker run --foo busybox; echo $?
flag provided but not defined: --foo
See 'docker run --help'.
125
126
종료 코드 126은 지정된 컨테이너 명령을 호출할 수 없음을 나타내요. 다음 예시의 컨테이너 명령은 /etc예요.
$ docker run busybox /etc; echo $?
docker: Error response from daemon: Container command '/etc' could not be invoked.
126
127
종료 코드 127은 컨테이너 명령을 찾을 수 없음을 나타내요.
$ docker run busybox foo; echo $?
docker: Error response from daemon: Container command 'foo' not found or does not exist.
127
기타 종료 코드 (Other exit codes)
125, 126, 127 이외의 종료 코드는 제공된 컨테이너 명령의 종료 코드를 나타내요.
$ docker run busybox /bin/sh -c 'exit 3'
$ echo $?
3
리소스에 대한 런타임 제약 (Runtime constraints on resources)
운영자는 컨테이너의 성능 매개변수도 조정할 수 있어요:
| Option | Description |
|---|---|
-m, --memory="" |
메모리 제한(형식: <number>[<unit>]). number는 양의 정수. unit은 b, k, m, g 중 하나. 최소는 6M. |
--memory-swap="" |
총 메모리 제한(memory + swap, 형식: <number>[<unit>]). number는 양의 정수. unit은 b, k, m, g 중 하나. |
--memory-reservation="" |
메모리 소프트 제한(형식: <number>[<unit>]). number는 양의 정수. unit은 b, k, m, g 중 하나. |
-c, --cpu-shares=0 |
CPU 공유(상대 가중치) |
--cpus=0.000 |
CPU 수. 소수. 0.000은 제한 없음. |
--cpu-period=0 |
CPU CFS(Completely Fair Scheduler) 주기 제한 |
--cpuset-cpus="" |
실행을 허용할 CPU(0-3, 0,1) |
--cpuset-mems="" |
실행을 허용할 메모리 노드(MEMs)(0-3, 0,1). NUMA 시스템에서만 유효. |
--cpu-quota=0 |
CPU CFS(Completely Fair Scheduler) 할당량 제한 |
--cpu-rt-period=0 |
CPU 실시간 주기 제한. 마이크로초 단위. 부모 cgroups가 설정되어야 하고 부모보다 높을 수 없음. rtprio ulimits도 확인. |
--cpu-rt-runtime=0 |
CPU 실시간 런타임 제한. 마이크로초 단위. 부모 cgroups가 설정되어야 하고 부모보다 높을 수 없음. rtprio ulimits도 확인. |
--blkio-weight=0 |
블록 IO 가중치(상대 가중치) 10에서 1000 사이의 가중치 값 허용. |
--blkio-weight-device="" |
블록 IO 가중치(상대 디바이스 가중치, 형식: DEVICE_NAME:WEIGHT) |
--device-read-bps="" |
디바이스에서 읽기 속도 제한(형식: <device-path>:<number>[<unit>]). number는 양의 정수. unit은 kb, mb, gb 중 하나. |
--device-write-bps="" |
디바이스로 쓰기 속도 제한(형식: <device-path>:<number>[<unit>]). number는 양의 정수. unit은 kb, mb, gb 중 하나. |
--device-read-iops="" |
디바이스에서 읽기 속도(초당 IO) 제한(형식: <device-path>:<number>). number는 양의 정수. |
--device-write-iops="" |
디바이스로 쓰기 속도(초당 IO) 제한(형식: <device-path>:<number>). number는 양의 정수. |
--oom-kill-disable=false |
컨테이너용 OOM Killer를 비활성화할지 여부. |
--oom-score-adj=0 |
컨테이너의 OOM 선호도 조정(-1000 ~ 1000) |
--memory-swappiness="" |
컨테이너의 메모리 swappiness 동작 조정. 0에서 100 사이의 정수 허용. |
--shm-size="" |
/dev/shm 크기. 형식은 <number><unit>. number는 0보다 커야 함. unit은 선택 사항이고 b(바이트), k(킬로바이트), m(메가바이트), g(기가바이트)일 수 있음. unit을 생략하면 시스템은 바이트를 사용. 크기를 완전히 생략하면 시스템은 64m을 사용. |
사용자 메모리 제약 (User memory constraints)
사용자 메모리 사용량을 설정하는 네 가지 방법이 있어요:
| Option | Result |
|---|---|
| memory=inf, memory-swap=inf (default) | 컨테이너에 메모리 제한이 없어요. 컨테이너는 필요한 만큼 메모리를 사용할 수 있어요. |
| memory=L <inf, memory-swap=inf | (memory를 지정하고 memory-swap을 -1로 설정) 컨테이너는 L 바이트를 초과하는 메모리를 사용할 수 없지만, 필요한 만큼 swap을 사용할 수 있어요(호스트가 swap 메모리를 지원하는 경우). |
| memory=L <inf, memory-swap=2*L | (memory-swap 없이 memory만 지정) 컨테이너는 L 바이트를 초과하는 메모리를 사용할 수 없고, swap 더하기 메모리 사용량은 그 두 배예요. |
| memory=L <inf, memory-swap=S<inf, L<=S | (memory와 memory-swap 둘 다 지정) 컨테이너는 L 바이트를 초과하는 메모리를 사용할 수 없고, swap 더하기 메모리 사용량은 S로 제한돼요. |
예시:
$ docker run -it ubuntu:24.04 /bin/bash
메모리에 대해 아무것도 설정하지 않았으므로 컨테이너의 프로세스는 필요한 만큼 메모리와 swap 메모리를 사용할 수 있어요.
$ docker run -it -m 300M --memory-swap -1 ubuntu:24.04 /bin/bash
메모리 제한을 설정하고 swap 메모리 제한을 비활성화했으므로 컨테이너의 프로세스는 300M 메모리와 필요한 만큼의 swap 메모리를 사용할 수 있어요(호스트가 swap 메모리를 지원하는 경우).
$ docker run -it -m 300M ubuntu:24.04 /bin/bash
메모리 제한만 설정했으므로 컨테이너의 프로세스는 300M 메모리와 300M swap 메모리를 사용할 수 있어요. 기본적으로 총 가상 메모리 크기(--memory-swap)는 메모리의 두 배로 설정되므로, 이 경우 memory + swap은 2*300M이고 프로세스는 300M swap 메모리도 사용할 수 있어요.
$ docker run -it -m 300M --memory-swap 1G ubuntu:24.04 /bin/bash
메모리와 swap 메모리를 둘 다 설정했으므로 컨테이너의 프로세스는 300M 메모리와 700M swap 메모리를 사용할 수 있어요.
메모리 예약(memory reservation)은 메모리의 더 큰 공유를 허용하는 일종의 소프트 메모리 제한이에요. 정상적인 상황에서 컨테이너는 필요한 만큼 메모리를 사용할 수 있고 -m/--memory 옵션으로 설정된 하드 제한에 의해서만 제약돼요. 메모리 예약이 설정되면 Docker는 메모리 경합이나 낮은 메모리를 감지하고 컨테이너가 예약 제한으로 소비를 제한하도록 강제해요.
항상 memory reservation 값을 하드 제한보다 낮게 설정하세요. 그렇지 않으면 하드 제한이 우선해요. 예약 0은 예약을 설정하지 않는 것과 같아요. 기본적으로(예약 미설정) 메모리 예약은 하드 메모리 제한과 같아요.
메모리 예약은 소프트 제한 기능이라 제한이 초과되지 않을 것을 보장하지 않아요. 대신 이 기능은 메모리가 심하게 경합될 때 예약 힌트/설정에 따라 메모리가 할당되도록 시도해요.
다음 예시는 메모리(-m)를 500M로 제한하고 memory reservation을 200M로 설정해요.
$ docker run -it -m 500M --memory-reservation 200M ubuntu:24.04 /bin/bash
이 구성에서 컨테이너가 200M 초과 500M 미만을 소비하면, 다음 시스템 메모리 회수은 컨테이너 메모리를 200M 미만으로 줄이려고 시도해요.
다음 예시는 하드 메모리 제한 없이 memory reservation을 1G로 설정해요.
$ docker run -it --memory-reservation 1G ubuntu:24.04 /bin/bash
컨테이너는 필요한 만큼 메모리를 사용할 수 있어요. memory reservation 설정은 모든 메모리 회수에서 컨테이너의 소비를 예약 수준으로 줄이므로 컨테이너가 오랫동안 너무 많은 메모리를 소비하지 않도록 보장해요.
기본적으로 OOM(메모리 부족) 오류가 발생하면 커널이 컨테이너의 프로세스를 죽여요. 이 동작을 바꾸려면 --oom-kill-disable 옵션을 사용해요. -m/--memory 옵션도 설정한 컨테이너에서만 OOM killer를 비활성화하세요. -m 플래그가 설정되지 않으면 호스트에서 메모리가 부족해져 메모리를 확보하기 위해 호스트의 시스템 프로세스를 죽여야 할 수 있어요.
다음 예시는 메모리를 100M로 제한하고 이 컨테이너의 OOM killer를 비활성화해요:
$ docker run -it -m 100M --oom-kill-disable ubuntu:24.04 /bin/bash
다음 예시는 이 플래그의 위험한 사용법을 보여줘요:
$ docker run -it --oom-kill-disable ubuntu:24.04 /bin/bash
컨테이너가 무제한 메모리를 가지므로 호스트가 메모리 부족이 되고 메모리를 확보하기 위해 시스템 프로세스를 죽여야 할 수 있어요. --oom-score-adj 매개변수는 시스템이 메모리 부족일 때 어떤 컨테이너가 죽임을 당할지 우선순위를 선택하도록 바꿀 수 있는데, 음수 점수는 죽임을 당할 가능성을 낮추고 양수 점수는 높여요.
Swappiness 제약 (Swappiness constraint)
기본적으로 컨테이너의 커널은 익명 페이지의 일정 비율을 스왑아웃할 수 있어요. 컨테이너에 이 비율을 설정하려면 0과 100 사이의 --memory-swappiness 값을 지정해요. 값 0은 익명 페이지 스와핑을 끄요. 값 100은 모든 익명 페이지를 swap 가능하게 설정해요. 기본적으로 --memory-swappiness를 사용하지 않으면 memory swappiness 값은 부모에게서 상속돼요.
예를 들어 다음과 같이 설정할 수 있어요:
$ docker run -it --memory-swappiness=0 ubuntu:24.04 /bin/bash
--memory-swappiness 옵션을 설정하는 것은 컨테이너의 워킹 셋을 유지하고 스와핑 성능 저하를 피하고 싶을 때 유용해요.
CPU 공유 제약 (CPU share constraint)
기본적으로 모든 컨테이너는 동일한 비율의 CPU 사이클을 받아요. 이 비율은 다른 모든 실행 중인 컨테이너의 가중치를 기준으로 컨테이너의 CPU 공유 가중치를 변경해 수정할 수 있어요.
기본값 1024에서 비율을 수정하려면 -c 또는 --cpu-shares 플래그를 사용해 가중치를 2 이상으로 설정해요. 0이 설정되면 시스템은 값을 무시하고 기본값 1024를 사용해요.
이 비율은 CPU 집약적 프로세스가 실행 중일 때만 적용돼요. 한 컨테이너의 작업이 유휴 상태일 때 다른 컨테이너가 남은 CPU 시간을 사용할 수 있어요. 실제 CPU 시간은 시스템에서 실행 중인 컨테이너 수에 따라 달라져요.
예를 들어 세 컨테이너를 생각해 보세요. 하나는 cpu-share가 1024이고 나머지 둘은 cpu-share 설정이 512예요. 세 컨테이너의 프로세스가 모두 CPU를 100% 사용하려 하면 첫 번째 컨테이너는 총 CPU 시간의 50%를 받아요. cpu-share 1024의 네 번째 컨테이너를 추가하면 첫 번째 컨테이너는 CPU의 33%만 받아요. 나머지 컨테이너는 각각 16.5%, 16.5%, 33%를 받아요.
멀티 코어 시스템에서 CPU 시간의 공유는 모든 CPU 코어에 분산돼요. 컨테이너가 CPU 시간의 100% 미만으로 제한되어도 각 개별 CPU 코어의 100%를 사용할 수 있어요.
예를 들어 세 개 이상의 코어가 있는 시스템을 생각해 보세요. 하나의 프로세스를 실행하는 -c=512의 컨테이너 {C0}와 두 프로세스를 실행하는 -c=1024의 컨테이너 {C1}을 시작하면 다음과 같은 CPU 공유 분할이 나올 수 있어요:
PID container CPU CPU share
100 {C0} 0 100% of CPU0
101 {C1} 1 100% of CPU1
102 {C1} 2 100% of CPU2
CPU 주기 제약 (CPU period constraint)
기본 CPU CFS(Completely Fair Scheduler) 주기는 100ms예요. --cpu-period를 사용해 CPU 주기를 설정해 컨테이너의 CPU 사용량을 제한할 수 있어요. 그리고 보통 --cpu-period는 --cpu-quota와 함께 동작해요.
예시:
$ docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu:24.04 /bin/bash
CPU가 1개라면 이 컨테이너가 50ms마다 50% CPU에 해당하는 런타임을 얻을 수 있다는 뜻이에요.
CPU 주기 제약을 설정하는 데 --cpu-period와 --cpu-quota를 사용하는 것 외에도, 소수 --cpus를 지정해 같은 목적을 달성할 수 있어요. 예를 들어 CPU가 1개라면 --cpus=0.5는 --cpu-period=50000과 --cpu-quota=25000(50% CPU)을 설정하는 것과 같은 결과를 얻어요.
--cpus의 기본값은 0.000이며 제한이 없음을 뜻해요.
자세한 내용은 bandwidth limiting에 대한 CFS 문서를 참고하세요.
Cpuset 제약 (Cpuset constraint)
컨테이너가 실행을 허용할 CPU를 설정할 수 있어요.
예시:
$ docker run -it --cpuset-cpus="1,3" ubuntu:24.04 /bin/bash
이는 컨테이너의 프로세스가 cpu 1과 cpu 3에서 실행될 수 있다는 뜻이에요.
$ docker run -it --cpuset-cpus="0-2" ubuntu:24.04 /bin/bash
이는 컨테이너의 프로세스가 cpu 0, 1, 2에서 실행될 수 있다는 뜻이에요.
컨테이너가 실행을 허용할 mems도 설정할 수 있어요. NUMA 시스템에서만 유효해요.
예시:
$ docker run -it --cpuset-mems="1,3" ubuntu:24.04 /bin/bash
이 예시는 컨테이너의 프로세스가 메모리 노드 1과 3에서만 메모리를 사용하도록 제한해요.
$ docker run -it --cpuset-mems="0-2" ubuntu:24.04 /bin/bash
이 예시는 컨테이너의 프로세스가 메모리 노드 0, 1, 2에서만 메모리를 사용하도록 제한해요.
CPU 할당량 제약 (CPU quota constraint)
--cpu-quota 플래그는 컨테이너의 CPU 사용량을 제한해요. 기본값 0은 컨테이너가 CPU 리소스(1 CPU)의 100%를 가져갈 수 있게 해요. CFS(Completely Fair Scheduler)는 실행 중인 프로세스의 리소스 할당을 처리하며 커널이 사용하는 기본 Linux 스케줄러예요. 이 값을 50000으로 설정하면 컨테이너를 CPU 리소스의 50%로 제한해요. 여러 CPU의 경우 필요에 따라 --cpu-quota를 조정해요. 자세한 내용은 bandwidth limiting에 대한 CFS 문서를 참고하세요.
블록 IO 대역폭(Blkio) 제약 (Block IO bandwidth constraint)
기본적으로 모든 컨테이너는 동일한 비율의 블록 IO 대역폭(blkio)을 받아요. 이 비율은 500이에요. 이 비율을 수정하려면 --blkio-weight 플래그를 사용해 다른 모든 실행 중인 컨테이너의 가중치를 기준으로 컨테이너의 blkio 가중치를 변경해요.
Note blkio weight 설정은 직접 IO(direct IO)에서만 사용할 수 있어요. 버퍼 IO(buffered IO)는 현재 지원되지 않아요.
--blkio-weight 플래그는 10에서 1000 사이의 값으로 가중치를 설정할 수 있어요. 예를 들어 다음 명령은 서로 다른 blkio weight의 두 컨테이너를 만들어요:
$ docker run -it --name c1 --blkio-weight 300 ubuntu:24.04 /bin/bash
$ docker run -it --name c2 --blkio-weight 600 ubuntu:24.04 /bin/bash
두 컨테이너에서 동시에 블록 IO를 수행하면, 예를 들어:
$ time dd if=/mnt/zerofile of=test.out bs=1M count=1024 oflag=direct
시간 비율이 두 컨테이너의 blkio weight 비율과 같다는 것을 발견할 수 있어요.
--blkio-weight-device="DEVICE_NAME:WEIGHT" 플래그는 특정 디바이스 가중치를 설정해요. DEVICE_NAME:WEIGHT는 콜론으로 구분된 디바이스 이름과 가중치를 담은 문자열이에요. 예를 들어 /dev/sda 디바이스 가중치를 200으로 설정하려면:
$ docker run -it \
--blkio-weight-device "/dev/sda:200" \
ubuntu
--blkio-weight와 --blkio-weight-device를 둘 다 지정하면 Docker는 --blkio-weight를 기본 가중치로 사용하고 --blkio-weight-device로 특정 디바이스에서 이 기본값을 새 값으로 재정의해요. 다음 예시는 기본 가중치 300을 사용하고 /dev/sda에서 이 기본값을 200으로 재정의해요:
$ docker run -it \
--blkio-weight 300 \
--blkio-weight-device "/dev/sda:200" \
ubuntu
--device-read-bps 플래그는 디바이스에서 읽기 속도(초당 바이트)를 제한해요. 예를 들어 이 명령은 컨테이너를 만들고 /dev/sda에서 읽기 속도를 초당 1mb로 제한해요:
$ docker run -it --device-read-bps /dev/sda:1mb ubuntu
--device-write-bps 플래그는 디바이스로 쓰기 속도(초당 바이트)를 제한해요. 예를 들어 이 명령은 컨테이너를 만들고 /dev/sda의 쓰기 속도를 초당 1mb로 제한해요:
$ docker run -it --device-write-bps /dev/sda:1mb ubuntu
두 플래그 모두 <device-path>:<limit>[unit] 형식의 제한을 가져요. 읽기·쓰기 속도 모두 양의 정수여야 해요. kb(킬로바이트), mb(메가바이트), gb(기가바이트) 단위로 지정할 수 있어요.
--device-read-iops 플래그는 디바이스에서 읽기 속도(초당 IO)를 제한해요. 예를 들어 이 명령은 컨테이너를 만들고 /dev/sda에서 읽기 속도를 초당 1000 IO로 제한해요:
$ docker run -it --device-read-iops /dev/sda:1000 ubuntu
--device-write-iops 플래그는 디바이스로 쓰기 속도(초당 IO)를 제한해요. 예를 들어 이 명령은 컨테이너를 만들고 /dev/sda로 쓰기 속도를 초당 1000 IO로 제한해요:
$ docker run -it --device-write-iops /dev/sda:1000 ubuntu
두 플래그 모두 <device-path>:<limit> 형식의 제한을 가져요. 읽기·쓰기 속도 모두 양의 정수여야 해요.
추가 그룹 (Additional groups)
--group-add: Add additional groups to run as
기본적으로 docker 컨테이너 프로세스는 지정된 사용자에 대해 조회된 보조 그룹으로 실행돼요. 그 그룹 목록에 더 추가하려면 이 플래그를 사용할 수 있어요:
$ docker run --rm --group-add audio --group-add nogroup --group-add 777 busybox id
uid=0(root) gid=0(root) groups=10(wheel),29(audio),99(nogroup),777
런타임 권한과 Linux capabilities
| Option | Description |
|---|---|
--cap-add |
Linux capabilities 추가 |
--cap-drop |
Linux capabilities 제거 |
--privileged |
이 컨테이너에 확장된 권한 부여 |
--device=[] |
--privileged 플래그 없이 컨테이너 안에서 디바이스를 실행하게 해줌. |
기본적으로 Docker 컨테이너는 "비특권(unprivileged)"이며, 예를 들어 Docker 컨테이너 안에서 Docker 데몬을 실행할 수 없어요. 이는 기본적으로 컨테이너가 어떤 디바이스에도 접근할 수 없지만, "특권(privileged)" 컨테이너는 모든 디바이스에 접근할 수 있기 때문이에요(cgroups devices 문서 참고).
--privileged 플래그는 컨테이너에 모든 capabilities를 부여해요. 운영자가 docker run --privileged를 실행하면 Docker는 호스트의 모든 디바이스에 대한 접근을 활성화하고, AppArmor나 SELinux를 재구성해 컨테이너가 호스트에서 컨테이너 밖에서 실행되는 프로세스와 거의 동일하게 호스트에 접근할 수 있게 해요. 이 플래그는 주의해서 사용하세요. --privileged 플래그에 대한 자세한 내용은 docker run 레퍼런스를 참고하세요.
특정 디바이스에 대한 접근을 제한하려면 --device 플래그를 사용할 수 있어요. 이 플래그는 컨테이너 안에서 접근할 수 있는 하나 이상의 디바이스를 지정할 수 있게 해줘요.
$ docker run --device=/dev/snd:/dev/snd ...
기본적으로 컨테이너는 이 디바이스들을 read, write, mknod할 수 있어요. 이는 각 --device 플래그에 세 번째 :rwm 옵션 세트를 사용해 재정의할 수 있어요:
$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk /dev/xvdc
Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk /dev/xvdc
You will not be able to write the partition table.
Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk /dev/xvdc
crash....
$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted
--privileged 외에도 운영자는 --cap-add와 --cap-drop를 사용해 capabilities를 세밀하게 제어할 수 있어요. 기본적으로 Docker는 유지되는 기본 capabilities 목록을 가져요. 다음 표는 기본적으로 허용되고 제거할 수 있는 Linux capability 옵션을 나열해요.
| Capability Key | Capability Description |
|---|---|
| AUDIT_WRITE | 커널 감사 로그에 기록 쓰기. |
| CHOWN | 파일 UID와 GID에 임의 변경( chown(2) 참고). |
| DAC_OVERRIDE | 파일 읽기, 쓰기, 실행 권한 검사 우회. |
| FOWNER | 일반적으로 파일시스템 UID가 파일 UID와 일치해야 하는 작업의 권한 검사 우회. |
| FSETID | 파일이 수정될 때 set-user-ID와 set-group-ID 권한 비트를 지우지 않음. |
| KILL | 신호 전송의 권한 검사 우회. |
| MKNOD | mknod(2)를 사용해 특수 파일 생성. |
| NET_BIND_SERVICE | 소켓을 인터넷 도메인 특권 포트(1024 미만 포트 번호)에 바인드. |
| NET_RAW | RAW 및 PACKET 소켓 사용. |
| SETFCAP | 파일 capabilities 설정. |
| SETGID | 프로세스 GID와 보조 GID 목록의 임의 조작. |
| SETPCAP | 프로세스 capabilities 수정. |
| SETUID | 프로세스 UID의 임의 조작. |
| SYS_CHROOT | chroot(2) 사용, 루트 디렉토리 변경. |
다음 표는 기본적으로 부여되지 않고 추가할 수 있는 capabilities를 보여줘요.
| Capability Key | Capability Description |
|---|---|
| AUDIT_CONTROL | 커널 감사 활성화·비활성화; 감사 필터 규칙 변경; 감사 상태와 필터링 규칙 검색. |
| AUDIT_READ | 멀티캐스트 netlink 소켓으로 감사 로그 읽기 허용. |
| BLOCK_SUSPEND | 시스템 일시정지 방지 허용. |
| BPF | BPF 맵 생성, BPF Type Format(BTF) 데이터 로드, BPF 프로그램의 JITed 코드 검색 등 허용. |
| CHECKPOINT_RESTORE | checkpoint/restore 관련 작업 허용. 커널 5.9에서 도입. |
| DAC_READ_SEARCH | 파일 읽기 권한 검사와 디렉토리 읽기·실행 권한 검사 우회. |
| IPC_LOCK | 메모리 잠금(mlock(2), mlockall(2), mmap(2), shmctl(2)). |
| IPC_OWNER | System V IPC 객체에 대한 작업의 권한 검사 우회. |
| LEASE | 임의 파일에 대한 임대 설정( fcntl(2) 참고). |
| LINUX_IMMUTABLE | FS_APPEND_FL 및 FS_IMMUTABLE_FL i-node 플래그 설정. |
| MAC_ADMIN | MAC 구성 또는 상태 변경 허용. Smack LSM에 구현됨. |
| MAC_OVERRIDE | Mandatory Access Control(MAC) 재정의. Smack Linux Security Module(LSM)에 구현됨. |
| NET_ADMIN | 다양한 네트워크 관련 작업 수행. |
| NET_BROADCAST | 소켓 브로드캐스트, 멀티캐스트 수신. |
| PERFMON | perf_events, i915_perf 및 기타 커널 하위 시스템을 사용해 시스템 성능 및 관측성 특권 작업 허용. |
| SYS_ADMIN | 다양한 시스템 관리 작업 수행. |
| SYS_BOOT | reboot(2)와 kexec_load(2) 사용, 재부팅하고 나중에 실행할 새 커널 로드. |
| SYS_MODULE | 커널 모듈 로드·언로드. |
| SYS_NICE | 프로세스 nice 값(nice(2), setpriority(2)) 높이기 및 임의 프로세스의 nice 값 변경. |
| SYS_PACCT | acct(2) 사용, 프로세스 어카운팅 켜기/끄기. |
| SYS_PTRACE | ptrace(2)로 임의 프로세스 추적. |
| SYS_RAWIO | I/O 포트 작업(iopl(2) 및 ioperm(2)) 수행. |
| SYS_RESOURCE | 리소스 제한 재정의. |
| SYS_TIME | 시스템 시계 설정(settimeofday(2), stime(2), adjtimex(2)); 실시간(하드웨어) 시계 설정. |
| SYS_TTY_CONFIG | vhangup(2) 사용; 가상 터미널에서 다양한 특권 ioctl(2) 작업 수행. |
| SYSLOG | 특권 syslog(2) 작업 수행. |
| WAKE_ALARM | 시스템을 깨울 무언가 트리거. |
더 자세한 참고 정보는 capabilities(7) - Linux man page와 Linux 커널 소스 코드에서 확인할 수 있어요.
두 플래그 모두 ALL 값을 지원하므로 MKNOD를 제외한 모든 capabilities를 사용하도록 허용하려면:
$ docker run --cap-add=ALL --cap-drop=MKNOD ...
--cap-add와 --cap-drop 플래그는 CAP_ 접두사와 함께 지정된 capabilities를 받아들여요. 따라서 다음 예시들은 동등해요:
$ docker run --cap-add=SYS_ADMIN ...
$ docker run --cap-add=CAP_SYS_ADMIN ...
네트워크 스택과 상호작용하려면 --privileged 대신 --cap-add=NET_ADMIN을 사용해 네트워크 인터페이스를 수정해야 해요.
$ docker run -it --rm ubuntu:24.04 ip link add dummy0 type dummy
RTNETLINK answers: Operation not permitted
$ docker run -it --rm --cap-add=NET_ADMIN ubuntu:24.04 ip link add dummy0 type dummy
FUSE 기반 파일시스템을 마운트하려면 --cap-add와 --device를 모두 조합해야 해요:
$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs [email protected]:/home/sven /mnt
fuse: failed to open /dev/fuse: Operation not permitted
$ docker run --rm -it --device /dev/fuse sshfs sshfs [email protected]:/home/sven /mnt
fusermount: mount failed: Operation not permitted
$ docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
# sshfs [email protected]:/home/sven /mnt
The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established.
ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.
Are you sure you want to continue connecting (yes/no)? yes
[email protected]'s password:
root@30aa0cfaf1b5:/# ls -la /mnt/src/docker
total 1516
drwxrwxr-x 1 1000 1000 4096 Dec 4 06:08 .
drwxrwxr-x 1 1000 1000 4096 Dec 4 11:46 ..
-rw-rw-r-- 1 1000 1000 16 Oct 8 00:09 .dockerignore
-rwxrwxr-x 1 1000 1000 464 Oct 8 00:09 .drone.yml
drwxrwxr-x 1 1000 1000 4096 Dec 4 06:11 .git
-rw-rw-r-- 1 1000 1000 461 Dec 4 06:08 .gitignore
....
기본 seccomp 프로필은 선택된 capabilities에 맞게 조정되어 capabilities가 허용하는 기능을 사용할 수 있게 하므로 이것을 조정할 필요는 없어야 해요.
이미지 기본값 재정의 (Overriding image defaults)
Dockerfile에서 이미지를 빌드하거나 커밋할 때, 이미지가 컨테이너로 시작될 때 적용되는 여러 기본 매개변수를 설정할 수 있어요. 이미지를 실행할 때 docker run 명령의 플래그를 사용해 그 기본값들을 재정의할 수 있어요.
- 기본 엔트리포인트 (Default entrypoint)
- 기본 명령과 옵션 (Default command and options)
- 포트 노출 (Expose ports)
- 환경 변수 (Environment variables)
- 헬스체크 (Healthcheck)
- 사용자 (User)
- 작업 디렉토리 (Working directory)
기본 명령과 옵션 (Default command and options)
docker run의 명령 구문은 컨테이너의 엔트리포인트에 명령과 인자를 선택적으로 지정하는 것을 지원하며, 다음 시놉시스 예시에서 [COMMAND]와 [ARG...]로 표현돼요:
$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
이 명령은 선택 사항인데, IMAGE를 만든 사람이 Dockerfile CMD 명령으로 기본 COMMAND를 이미 제공했을 수 있기 때문이에요. 컨테이너를 실행할 때 새 COMMAND를 지정하기만 해도 그 CMD 명령을 재정의할 수 있어요.
이미지가 ENTRYPOINT도 지정하면 CMD 또는 COMMAND가 ENTRYPOINT의 인자로 추가돼요.
기본 엔트리포인트 (Default entrypoint)
--entrypoint="": Overwrite the default entrypoint set by the image
엔트리포인트는 컨테이너를 실행할 때 호출되는 기본 실행 파일을 말해요. 컨테이너의 엔트리포인트는 Dockerfile ENTRYPOINT 명령으로 정의돼요. 이는 기본 명령을 지정하는 것과 비슷하지만, 차이점은 엔트리포인트를 재정의하려면 명시적 플래그를 전달해야 하는 반면 기본 명령은 위치 인자로 재정의할 수 있다는 것이에요. 이것은 컨테이너의 기본 동작을 정의하며, 엔트리포인트를 설정하면 컨테이너를 기본 옵션과 함께 그 바이너리인 것처럼 실행할 수 있고, 명령으로 더 많은 옵션을 전달할 수 있다는 생각이에요. 하지만 컨테이너 안에서 다른 것을 실행하고 싶을 때가 있어요. 이때 docker run 명령의 --entrypoint 플래그를 사용해 런타임에서 기본 엔트리포인트를 재정의하는 게 유용해요.
--entrypoint 플래그는 컨테이너가 시작될 때 호출하려는 바이너리의 이름 또는 경로를 나타내는 문자열 값을 기대해요. 다음 예시는 다른 바이너리(예: /usr/bin/redis-server)를 자동으로 실행하도록 설정된 컨테이너에서 Bash 셸을 실행하는 방법을 보여줘요:
$ docker run -it --entrypoint /bin/bash example/redis
다음 예시는 위치 명령 인자를 사용해 사용자 지정 엔트리포인트에 추가 매개변수를 전달하는 방법을 보여줘요:
$ docker run -it --entrypoint /bin/bash example/redis -c ls -l
$ docker run -it --entrypoint /usr/bin/redis-cli example/redis --help
빈 문자열을 전달해 컨테이너의 엔트리포인트를 리셋할 수 있어요. 예를 들어:
$ docker run -it --entrypoint="" mysql bash
Note
--entrypoint를 전달하면 이미지에 설정된 모든 기본 명령이 지워져요. 즉, 빌드에 사용된 Dockerfile의 어떤CMD명령도 지워져요.
노출된 포트 (Exposed ports)
기본적으로 컨테이너를 실행하면 컨테이너의 어떤 포트도 호스트에 노출되지 않아요. 이는 컨테이너가 수신 대기하고 있을 수 있는 포트에 접근할 수 없다는 뜻이에요. 호스트에서 컨테이너의 포트에 접근할 수 있게 하려면 포트를 게시(publish)해야 해요.
-P 또는 -p 플래그로 컨테이너를 시작해 포트를 노출할 수 있어요:
-P(또는--publish-all) 플래그는 모든 노출된 포트를 호스트에 게시해요. Docker는 각 노출된 포트를 호스트의 무작위 포트에 바인드해요.-P플래그는 DockerfileEXPOSE명령이나docker run명령의--expose플래그로 명시적으로 노출된 것으로 표시된 포트 번호만 게시해요.-p(또는--publish) 플래그는 컨테이너의 단일 포트 또는 포트 범위를 호스트에 명시적으로 매핑할 수 있게 해줘요.
컨테이너 안의 포트 번호(서비스가 수신하는 곳)는 컨테이너 밖에 게시된 포트 번호(클라이언트가 연결하는 곳)와 일치할 필요가 없어요. 예를 들어 컨테이너 안에서 HTTP 서비스가 포트 80에서 수신 대기할 수 있어요. 런타임에는 그 포트가 호스트의 42800에 바인드될 수 있어요. 호스트 포트와 노출된 포트 사이의 매핑을 찾으려면 docker port 명령을 사용해요.
환경 변수 (Environment variables)
Docker는 Linux 컨테이너를 만들 때 일부 환경 변수를 자동으로 설정해요. Docker는 Windows 컨테이너를 만들 때는 어떤 환경 변수도 설정하지 않아요.
Linux 컨테이너에 설정되는 환경 변수는 다음과 같아요:
| Variable | Value |
|---|---|
HOME |
USER 값에 기반해 설정 |
HOSTNAME |
컨테이너와 연결된 호스트 이름 |
PATH |
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 같은 널리 쓰이는 디렉토리 포함 |
TERM |
컨테이너에 pseudo-TTY가 할당되면 xterm |
추가로 하나 이상의 -e 플래그를 사용해 컨테이너에 어떤 환경 변수든 설정할 수 있어요. 위에서 언급한 변수나, 이미지를 빌드할 때 Dockerfile ENV 명령으로 정의한 변수도 재정의할 수 있어요.
값을 지정하지 않고 환경 변수 이름을 지정하면 호스트에서 그 이름의 현재 값이 컨테이너의 환경으로 전파돼요:
$ export today=Wednesday
$ docker run -e "deep=purple" -e today --rm alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=d2219b854598
deep=purple
today=Wednesday
HOME=/root
PS C:\> docker run --rm -e "foo=bar" microsoft/nanoserver cmd /s /c set
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\ContainerAdministrator\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=C2FAEFCC8253
ComSpec=C:\Windows\system32\cmd.exe
foo=bar
LOCALAPPDATA=C:\Users\ContainerAdministrator\AppData\Local
NUMBER_OF_PROCESSORS=8
OS=Windows_NT
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps
PATHEXT=.COM;.EXE;.BAT;.CMD
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 62 Stepping 4, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3e04
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PUBLIC=C:\Users\Public
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
TMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
USERDOMAIN=User Manager
USERNAME=ContainerAdministrator
USERPROFILE=C:\Users\ContainerAdministrator
windir=C:\Windows
헬스체크 (Healthchecks)
docker run 명령의 다음 플래그로 컨테이너 헬스체크 매개변수를 제어할 수 있어요:
| Option | Description |
|---|---|
--health-cmd |
건강을 확인하기 위해 실행할 명령 |
--health-interval |
검사 실행 사이의 시간 |
--health-retries |
비정상(unhealthy)으로 보고하는 데 필요한 연속 실패 횟수 |
--health-timeout |
한 검사가 실행될 수 있는 최대 시간 |
--health-start-period |
health-retries 카운트다운 시작 전에 컨테이너가 초기화되는 시작 기간 |
--health-start-interval |
시작 기간 동안 검사 실행 사이의 시간 |
--no-healthcheck |
컨테이너 지정 HEALTHCHECK 비활성화 |
예시:
$ docker run --name=test -d \
--health-cmd='stat /etc/passwd || exit 1' \
--health-interval=2s \
busybox sleep 1d
$ sleep 2; docker inspect --format='{{.State.Health.Status}}' test
healthy
$ docker exec test rm /etc/passwd
$ sleep 2; docker inspect --format='{{json .State.Health}}' test
{
"Status": "unhealthy",
"FailingStreak": 3,
"Log": [
{
"Start": "2016-05-25T17:22:04.635478668Z",
"End": "2016-05-25T17:22:04.7272552Z",
"ExitCode": 0,
"Output": " File: /etc/passwd\n Size: 334 \tBlocks: 8 IO Block: 4096 regular file\nDevice: 32h/50d\tInode: 12 Links: 1\nAccess: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
},
{
"Start": "2016-05-25T17:22:06.732900633Z",
"End": "2016-05-25T17:22:06.822168935Z",
"ExitCode": 0,
"Output": " File: /etc/passwd\n Size: 334 \tBlocks: 8 IO Block: 4096 regular file\nDevice: 32h/50d\tInode: 12 Links: 1\nAccess: (0664/-rw-rw-r--) Uid: ( 0/ root) Gid: ( 0/ root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
},
{
"Start": "2016-05-25T17:22:08.823956535Z",
"End": "2016-05-25T17:22:08.897359124Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
},
{
"Start": "2016-05-25T17:22:10.898802931Z",
"End": "2016-05-25T17:22:10.969631866Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
},
{
"Start": "2016-05-25T17:22:12.971033523Z",
"End": "2016-05-25T17:22:13.082015516Z",
"ExitCode": 1,
"Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
}
]
}
건강 상태는 docker ps 출력에도 표시돼요.
사용자 (User)
컨테이너 안의 기본 사용자는 root(uid = 0)예요. Dockerfile USER 명령으로 첫 프로세스를 실행할 기본 사용자를 설정할 수 있어요. 컨테이너를 시작할 때 -u 옵션을 전달해 USER 명령을 재정의할 수 있어요.
-u="", --user="": Sets the username or UID used and optionally the groupname or GID for the specified command.
다음 예시는 모두 유효해요:
--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]
Note 숫자 사용자 ID를 전달하면 0-2147483647 범위여야 해요. 사용자 이름을 전달하면 그 사용자가 컨테이너에 존재해야 해요.
작업 디렉토리 (Working directory)
컨테이너 안에서 바이너리를 실행하기 위한 기본 작업 디렉토리는 루트 디렉토리(/)예요. 이미지의 기본 작업 디렉토리는 Dockerfile WORKDIR 명령으로 설정돼요. docker run 명령의 -w(또는 --workdir) 플래그로 이미지의 기본 작업 디렉토리를 재정의할 수 있어요:
$ docker run --rm -w /my/workdir alpine pwd
/my/workdir
디렉토리가 컨테이너에 이미 존재하지 않으면 생성돼요.