도커 기본 사용법
Docker
도커는 “컨테이너”이다.
컨테이너는 애플리케이션을 실행하기 위한 독립적이고 가벼운 환경을 제공하는 기술이다. 여기에는 여러 가지 구성 요소와 자원이 포함되어 있어, 애플리케이션이 이동성 있게 실행되고 개발 및 배포가 편리하게 이루어진다. 컨테이너는 가상화 기술의 한 형태로, 여러 애플리케이션을 동일한 호스트 시스템에서 격리된 환경에서 실행할 수 있도록 해준다.
컨테이너의 주요 개념과 특징
- 이식성(Portability): 컨테이너는 애플리케이션 및 모든 종속성을 포함하므로 어디서든 동일한 환경에서 실행될 수 있습니다. 이식성은 개발에서 운영 환경으로, 또는 클라우드 간에 애플리케이션을 쉽게 이동시킬 수 있음을 의미한다.
- 격리(Isolation): 컨테이너는 호스트 시스템에서 격리된 고립된 환경을 제공한다. 각 컨테이너는 자체 파일 시스템, 네트워크, 프로세스 공간을 가지며 다른 컨테이너와 독립적으로 실행된다.
- 가볍고 빠른 시작: 가상 머신과 비교해 컨테이너는 더 가볍고 빠르게 시작된다. 이는 호스트 운영 체제의 커널을 공유하고 자원을 가상화하지 않기 때문이다.
- 환경의 일치: 개발 환경과 운영 환경이 동일하게 유지된다. 개발 시 사용한 환경을 컨테이너로 패키징하면 운영 환경에서도 동일한 조건에서 애플리케이션을 실행할 수 있다.
- 자동화 및 스케일링: 컨테이너는 자동화된 배포 및 스케일링이 용이하며, 필요에 따라 빠르게 복제하거나 축소할 수 있다.
도커 이미지? 도커 컨테이너?
도커 이미지(Docker Image)
도커 이미지는 컨테이너를 만드는 데 사용되는 읽기 전용(Read-only) 템플릿이다.
컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있는 도커파일을 만든 후Dockerfile을 빌드하여 이미지를 만든다.
도커 컨테이너(Docker Container)
도커이미지를 실행한 상태다.
이미지로 컨테이너를 생성하면 이미지의 목적에 맞는 파일이 들어있는 파일 시스템과
격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간이 생성된다.
이것을 도커 컨테이너라고 한다.
도커 컨테이너는 읽기 전용인 이미지에 변경된 사항을 저장하는 컨테이너 계층(Layer)에 저장한다.
도커 이미지를 도넛 레시피에 비유한다면, 도커 컨테이너는 해당 레시피를 이용해 만든 도넛으로 비유할 수 있다.
하나의 도넛 레시피에서 여러 가지 맛의 도넛을 만들 수 있는 것과 같이, 하나의 도커 이미지로 여러 개의 도커 컨테이너 를 만들 수 있다.
또한, 기존의 도넛 레시피를 수정하게 되어도, 이미 기존 레시피로 만들어진 도넛에는 영향이 없듯이, 이처럼 도커 이미지를 변경해도 이미 실행 중인 도커 컨테이너에는 영향을 주지 않는다.
- API 테스트 및 개발에 사용되는 도구
- 다양한 HTTP 요청 및 응답 테스트
- 테스트 스크립팅 및 자동화 가능
기본적인 도커 명령어
도커 명령어의 구조는 아래와 같다.
-
docker [대상] [액션]
→ [대상] :
container
(생략 가능),image
,volume
,network
등→ [액션] :
ls
,inspect
,start
,run
등
도커 컨테이너
docker (container) create
→ 컨테이너를 생성하고 자동으로 시작하지는 않음
root@minseoky:~# docker create --name testos centos
Unable to find image 'centos:latest' locally
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
875366cc4662d6ccdc21dfbaa654ed3eee74bb54d6a2ce34333a62924f7e0272
centos 이미지를 사용해서 컨테이너를 생성해 주는 명령어다.
-name
옵션을 추가하여 컨테이너명은 testos로 설정했다.
→ name 옵션을 쓰지 않으면 임의의 name이 부여된다.
이미 생성된 컨테이너의 컨테이너 명을 바꾸고 싶으면docker rename [현재 이름] [바꿀 이름]
명령어를 사용한다.
💡 컨테이너 명을 변경하여도 컨테이너 ID는 변경되지 않는다.
로컬 리포지토리에 이미지가 없으면 기본으로 docker hub에서 이미지를 pull 한다.
한번 pull 한 이미지는 재사용이 가능하다.
컨테이너를 생성할 때 옵션을 써줄 수도 있다.
docker create -it --name testos2 centos
해당 옵션들의 설명은 아래와 같다.
옵션 | 설명 |
---|---|
-i (—interactive) | 표준 입력(STDIN)을 활성화 함.컨테이너와 attach되어있지 않아도 표준 입력 유지 |
-t (—tty) | 컨테이너에 pseudo-terminal을 할당 |
docker ps
→ 실행(Up) 중인 컨테이너들의 목록을 확인
→docker container ls
와 같음
root@minseoky:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
adb6732a399d centos "/bin/bash" 51 seconds ago Up 50 seconds testos2
출력된 결과의 각 항목은 다음과 같이 설명할 수 있다.
[CONTAINER ID] :
- 컨테이너에 할당되는 고유한 컨테이너 ID
- 전체 ID에서 12자리만 출력
[IMAGE] :
- 컨테이너를 생성할 때 사용된 이미지
[COMMAND] :
- 컨테이너가 시작될 때 실행될 명령어
docker run
이나docker create
명령어의 맨 끝에 새로운 명령어를 입력해서 컨테이너를 생성할 때 대체 가능[CREATED] :
- 컨테이너 생성 후 경과 시간
[STATUS] :
- 컨테이너의 상태
- 실행 중(Up), 종료(Exited), 일시 중지(Pause)
[PORTS] :
- 컨테이너가 개방한 포트와 호스트에 연결된 포트
[NAMES] :
- 컨테이너 이름
a
(all) 옵션을 함께 써주면 실행 중이지 않은 컨테이너를 포함하여 전체 컨테이너 목록을 출력한다.
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
adb6732a399d centos "/bin/bash" 55 seconds ago Up 54 seconds testos2
875366cc4662 centos "/bin/bash" 5 hours ago Created testos`
-no-trunc
옵션을 함께 써주면 컨테이너 ID 전체를 보여준다.
root@minseoky:~# docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
adb6732a399de1d9d4d2d8e2b74d6a4c6829652c8e950c77daebe32afdc25430 centos "/bin/bash" 5 minutes ago Up 5 minutes testos2`
docker start
→ 컨테이너를 시작(실행)
→생성해둔 컨테이너를 시작할 수 있음
root@minseoky:~# docker start -ai testos
[root@151f3b70b5a4 /]#
컨테이너(testos)를 시작하면서-ai
옵션을 사용해 해당 컨테이너 내부로 접근하여 표준 입력을 받을 수 있도록 했다.
옵션 | 설명 |
---|---|
-a (—attach) | 해당 컨테이너 내부로 접근 |
해당 컨테이너에 접근한 상태로 exit 명령을 사용하면, /bin/bash
가 종료되면서 컨테이너도 함께 종료된다.
때문에 순차적으로 Ctrl + P
, Ctrl + Q
를 눌러 컨테이너 실행 상태를 유지한 채로 빠져나온 후, 컨테이너가 실행 중(Up)인지 확인할 수 있다.
root@minseoky:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
151f3b70b5a4 centos "/bin/bash" 44 seconds ago Up 16 seconds testos
docker stop
→ 실행 중인 컨테이너를 종료
root@minseoky:~# docker stop testos
testos
컨테이너가 종료(Exited)된 것을 확인할 수 있다.
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
151f3b70b5a4 centos "/bin/bash" 8 minutes ago Exited (0) 19 seconds ago testos`
docker run
→ 컨테이너를 시작하고 COMMAND를 실행
→ 로컬에 이미지가 있다면 해당 이미지로 실행하고, 없으면 도커허브에서 다운로드 후 실행
→create + start
root@minseoky:~# docker run -dit --name test centos
5d56fc765e3780fb06f5f3d5a66935e1a087087d7b9ab69e979e830773603a81
root@minseoky:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d56fc765e37 centos "/bin/bash" 1 second ago Up 1 second test
d
옵션을 사용해 사용자가 직접 컨테이너 안으로 접근하지 않고, 컨테이너의 COMMAND를 백그라운드로 실행할 수 있다.
컨테이너를 시작할 때, 명령어의 맨 뒤에 임의로 COMMAND를 정의할 수 있다.
root@minseoky:~# docker run -it --name date centos /bin/date
Tue Jun 28 08:56:41 UTC 2022
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24a654120847 centos "/bin/date" About a minute ago Exited (0) About a minute ago date`
COMMAND(/bin/date
)가 종료되면서 컨테이너도 함께 종료된 것을 확인할 수 있다.
shell의 환경 정보를 옵션으로 정의하는 것도 가능하다.
root@minseoky:~# docker run -it --name test -w "/tmpdir" -e "MYNAME=MINSEOKY" centos
[root@8e01dc01c6f7 tmpdir]# pwd
/tmpdir
[root@8e01dc01c6f7 tmpdir]# echo $MYNAME
MINSEOKY
옵션 | 설명 |
---|---|
-w (—workdir) | 컨테이너의 작업 디렉토리를 설정 |
-e (—env) | 환경 변수 설정 |
—env-file=[파일명] | 정의해야 하는 환경 변수가 많은 경우 특정 파일을 호출해서 설정 가능 |
restart
옵션을 통해 정해진 규칙에 따라 자동으로 재시작이 가능하다.
root@minseoky:~# docker run -it --name test --restart always centos
[root@8dfcdfd3c5c6 /]# exit
exit
root@minseoky:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8dfcdfd3c5c6 centos "/bin/bash" 16 seconds ago Up 3 seconds test`
동작 중인 컨테이너에서 exit
을 하면 종료가 되어야 하는데 restart
옵션을 always
로 설정했기 때문에 종료되어도 다시 시작(Up) 된 것을 확인할 수 있다.
아래의 표와 같은 restart
옵션을 사용할 수 있다.
옵션 | 키워드 | 설명 |
---|---|---|
—restart | no | 재시작하지 않음 |
on-failure | 종료 상태(Exited code)가 0이 아닌 경우 재시작 | |
on-failure:횟수(n) | 종료 상태(Exited code)가 0이 아닌 경우 n회만 재시작 | |
always | 항상 재시작 |
컨테이너를 시작할 때 CPU와 메모리 등 리소스 사용량을 제한할 수 있다.
옵션 | 설명 |
---|---|
—cpus | 컨테이너에서 최대 사용 가능한 cpu의 수를 지정(CPU 사용 비율 지정) |
ex) –cpus=0.2 는 CPU를 0.2개(20%)만큼 사용한다는 의미 | |
-c (—cpu-share) | default 값은 1024 |
512라고 정의하면 프로세스들 간의 CPU 자원의 경합이 발생했을 때 다른 프로세스들(1024)의 50%만 자원 할당 가능 | |
-m (—memory) | 메모리 사용량을 제한(b, k, m, g 단위 정의 |
이 외에도 리소스를 제한하는 더 많은 옵션들이 있다.
docker attach
→ 컨테이너 내부에 접근하여 STDIN/STDOUT/STDERR를 사용
→ 컨테이너 PID=1 표준 입출력을 이용
root@minseoky:~# docker run -it --name test centos
[root@c8137246c2de /]# [Ctrl + p, Ctrl + q]
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8137246c2de centos "/bin/bash" 29 seconds ago Up 29 seconds test
root@minseoky:~# docker attach test
[root@c8137246c2de /]# ps -e
PID TTY TIME CMD
1 pts/0 00:00:00 bash
15 pts/0 00:00:00 ps
docker exec
→ 동작 중인 컨테이너에서 새로운 프로세스를 실행
→ COMMAND 말고 별도의 명령어를 실행
root@minseoky:~# docker run -d --name web httpd
4e02c31135d3eb2dda8dcdb8fd83b97d3aa0805ddb50235b5efbc71dfa19b604
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4e02c31135d3 httpd "httpd-foreground" 2 seconds ago Up 1 second 80/tcp web
root@minseoky:~# docker exec -it web /bin/bash
root@4e02c31135d3:/usr/local/apache2#
웹서버 같은 경우는 COMMAND(PID=1)가 httpd로 정의되고, 쉘이 실행되지 않기 때문에 docker attach
로 명령 입력이 불가능하다.
때문에 쉘에 접근하기 위해서는 개별적으로 실행을 해줘야 한다.
docker logs
→ 컨테이너의 PID=1 프로세스의 STDIN/STDOUT/STDERR를 출력 가능
root@minseoky:~# docker run -dit --name pingtest centos /bin/ping localhost
85421d90d372895c5cc9f0219ffd6235c3536e31c9dde1eacdd641803999d59c
root@minseoky:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
85421d90d372 centos "/bin/ping localhost" 3 seconds ago Up 2 seconds pingtest
root@minseoky:~# docker logs -f pingtest
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.019 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.069 ms
root@minseoky:~# docker logs -ft pingtest
2022-06-29T02:40:10.275963929Z PING localhost (127.0.0.1) 56(84) bytes of data.
2022-06-29T02:40:10.276917834Z 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.019 ms
2022-06-29T02:40:11.277869637Z 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.036 ms
몇 가지 옵션을 주어 로그를 다양한 방식으로 출력할 수 있다.
옵션 | 설명 |
---|---|
-f (—follow) | 실시간으로 로그를 추적, 출력 |
-t (—timestamp) | 타임스탬프 출력 |
docker stats
→ 동작 중인 컨테이너의 상태와 사용 중인 리소스의 양을 확인할 때 사용
→ 상태 확인이 끝나면 Ctrl + C
를 눌러 명령을 종료
root@minseoky:~# docker run -dit --name test --cpus=0.3 stress
e1f401b606f3c1cbee21f2bbe83a656cf22c1382495055076451ceef90aee7d4
root@minseoky:~# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
e1f401b606f3 test 29.31% 752KiB / 12.36GiB 0.01% 906B / 0B 0B / 0B 4
부하 테스트를 할 수 있는 임의의 컨테이너(test)를 실행시킨 후, docker stats
으로 확인해 보았다.
각 항목에 대한 설명이다.
[CONTAINER ID] :
- 컨테이너 ID
[NAME] :
- 컨테이너 이름
[CPU %] :
- CPU 사용률
[MEM USAGE / LIMIT] :
- 메모리 사용량 / 컨테이너에서 사용할 수 있는 메모리 제한
[MEM %] :
- 메모리 사용률
[NET I/O] :
- 네트워크 I/O
[BLOCK I/O] :
- 블록 I/O
[PIDS] :
- 사용 중인 PID의 수(프로세스의 수)
docker top
→ 동작 중인 컨테이너에서 실행되고 있는 프로세스를 확인할 때 사용
root@minseoky:~# docker run -dit --name test centos
e900da8137a077c9a82f3936899e9ac0d3f167a6a6e759cfacdcce17ef940979
root@DH:~# docker top test
UID PID PPID C STIME TTY TIME CMD
root 3947 3927 0 05:45 ? 00:00:00 /bin/bash
컨테이너 내부 격리 환경에서 각 프로세스는 PID 1번이지만, 전체 운영체제에서의 PID가 출력된다.
docker pause/unpause
→ 컨테이너를 일시 중지하거나 일시 중지된 컨테이너를 재시작
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e900da8137a0 centos "/bin/bash" 6 minutes ago Up 5 minutes test
root@minseoky:~# docker pause test
test
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e900da8137a0 centos "/bin/bash" 6 minutes ago Up 6 minutes (Paused) test
root@minseoky:~# docker attach test
You cannot attach to a paused container, unpause it first
root@minseoky:~# docker unpause test
test
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e900da8137a0 centos "/bin/bash" 6 minutes ago Up 6 minutes test
동작 중인 컨테이너를 pause
명령어를 사용하여 일시 중지한 뒤에 attach
명령어로 접근을 시도하면 당연히 접근이 되지 않는다.
unpause
명령어로 일시 중지된 컨테이너를 재시작 해주어야 접근이 가능하다.
docker ps -a
로 STATUS에 Paused
가 출력되는 것을 확인할 수 있다.
docker rm
→ 컨테이너를 삭제
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cbeab5acfb0 centos "/bin/bash" 9 seconds ago Exited (0) 8 seconds ago test2
e900da8137a0 centos "/bin/bash" 12 minutes ago Up 12 minutes test
root@minseoky:~# docker rm test
Error response from daemon: You cannot remove a running container e900da8137a077c9a82f3936899e9ac0d3f167a6a6e759cfacdcce17ef940979. Stop the container before attempting removal or force remove
root@minseoky:~# docker rm test2
test2
root@minseoky:~# docker rm -f test
test
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
rm
명령어를 사용해 종료된 컨테이너를 삭제할 수 있다.
동작 중인(Up) 컨테이너를 삭제하려면 stop
명령어를 사용해 종료(Exited) 후 삭제하거나, rm
명령어에 -f
옵션을 사용해 삭제할 수 있다.
docker rmi [이미지명] → 이미지를 삭제
docker (container) prune
→ 종료(Exited) 된 컨테이너를 일괄적으로 삭제
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6044f6e3d7e centos "/bin/bash" 44 seconds ago Exited (0) 43 seconds ago test4
7486f75a31e5 centos "/bin/bash" 51 seconds ago Exited (0) 51 seconds ago test3
b22e767a3965 centos "/bin/bash" 59 seconds ago Up 58 seconds test2
54ca84644b86 centos "/bin/bash" About a minute ago Up About a minute test
root@minseoky:~# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
c6044f6e3d7eeda4d692ecb848ec52d01d22681238d5c4d2b2f430df9ae6b06f
7486f75a31e5fb22120de3ed0bd45fa65cfcd5c940981d4625dbc241ea87150f
Total reclaimed space: 0B
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b22e767a3965 centos "/bin/bash" About a minute ago Up About a minute test2
54ca84644b86 centos "/bin/bash" About a minute ago Up About a minute test
prune
명령어를 사용하려면 앞에 [대상]을 명시해주어야 한다.
ex) container, image, network, volume, system
동작 중인 컨테이너는 삭제되지 않고 종료된 컨테이너만 삭제합니다.
docker cp
→ 컨테이너와 호스트 간의 파일 복사
root@minseoky:~# touch example.txt
root@minseoky:~# ls
example.txt
root@minseoky:~# docker run -dit --name test centos
5e43e97c988e78202f4d6dcb2b68b153c0a3c91e80ac2bdb5b8b7ae2a39f0592
root@minseoky:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e43e97c988e centos "/bin/bash" 6 seconds ago Up 5 seconds test
root@minseoky:~# docker cp ~/example.txt test:/
root@minseoky:~# docker exec test /bin/ls example.txt
example.txt
root@minseoky:~# docker cp test:/example.txt ~/example2.txt
root@minseoky:~# ls
example.txt example2.txt
docker cp 명령어를 사용하여 컨테이너와 로컬 호스트 간의 파일을 복사할 수 있습니다. docker cp [복사할 대상] [복사시킬 대상] 구조로 사용할 수 있습니다. 컨테이너 안의 디렉터리를 지정하려면 [컨테이너명:경로]의 구조로 사용해야 합니다.
docker diff
→ 컨테이너가 생성된 시점부터 변경된 이력을 확인
→ writable layer의 변경 여부를 확인
root@minseoky:~# docker run -it --name test centos
[root@ba258fff1ae8 /]# useradd containeruser
[root@ba258fff1ae8 /]# [Ctrl + p, Ctrl + q]
root@minseoky:~# docker diff test
C /home
A /home/containeruser
A /home/containeruser/.bash_logout
A /home/containeruser/.bash_profile
A /home/containeruser/.bashrc
C /etc
A /etc/subuid-
C /etc/subgid
C /etc/passwd-
C /etc/shadow
C /etc/group
A /etc/subgid-
C /etc/subuid
C /etc/gshadow
C /etc/shadow-
C /etc/gshadow-
C /etc/passwd
C /etc/group-
C /var
C /var/log
C /var/log/lastlog
C /var/spool
C /var/spool/mail
A /var/spool/mail/containeruser
diff
명령어를 사용하여 컨테이너의 변경된 이력을 확인할 수 있다.
A(Add)는 추가된 이력, C(Change)는 변경된 이력, D(Delete)는 삭제된 이력을 의미한다.