DevOps/Docker

[Docker] Docker LifeCycle과 자주 사용하는 옵션

TTOII 2022. 5. 7. 01:34
728x90

✔️ Docker의 LifeCycle

create → start → (pause) → (unpause) → (kill) → stop → rm → run ---------->

Docker run은 Docker create + Docker start 를 합친 것이다.
Docker create - 컨테이너를 생성하며
Docker start - 컨테이너를 실행한다.

실행의 원칙은 app이 종료가 되면 컨테이너도 종료 되는 것이다.
여기서의 종료는 stop을 의미한다.

 

pause, unpause 명령을 통해 컨테이너를 일시 중지, 중지 해제 할 수도 있다.

puase를 시키면 사용하던 리소스들을 그대로 가지고 있다.

kill은 프로세스를 종료시키는 것이며, 컨테이너를 강제종료시키는 것이다.

 

 

 vagrant@docker  ~  docker run -d httpd
a668098f67397a547a7984e772ef44170a0e0dcae91be669ef013cdd29db0a0e # 생성된 컨테이너의 아이디

 vagrant@docker  ~  docker ps -a       
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   9 seconds ago   Up 6 seconds   80/tcp    clever_nobel

-d 옵션을 붙이면 백그라운드에서 계속적으로 실행할 수 있다.
사용할 이미지에 따라 -d 옵션을 붙여야 하는 경우가 있고 안붙여도 되는 경우가 있다.

 

 

 vagrant@docker  ~  docker pause clever_nobel 
clever_nobel

 vagrant@docker  ~  docker ps                
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS                  PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   3 minutes ago   Up 3 minutes (Paused)   80/tcp    clever_nobel

 vagrant@docker  ~  docker unpause clever_nobel 
clever_nobel

 vagrant@docker  ~  docker ps                  
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   3 minutes ago   Up 3 minutes   80/tcp    clever_nobel
 vagrant@docker  ~  docker kill clever_nobel             
clever_nobel

 vagrant@docker  ~  docker ps -a 
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS                       PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   4 minutes ago   Exited (137) 8 seconds ago             clever_nobel

STATUS의 Exited(137) 코드는 137에서 128을 빼주면 된다. '9' 즉 kill을 의미한다.
이렇게 다른 코드를 사용하는 이유은 컨테이너 내의 시그널과 호스트 운영체제의 시그널울 분리하기 위해서다.

 

 

 vagrant@docker  ~  docker start clever_nobel 
clever_nobel
 vagrant@docker  ~  docker ps -a             
dCONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   6 minutes ago   Up 5 seconds   80/tcp    clever_nobel
 vagrant@docker  ~  docker stop clever_nobel 
clever_nobel
 vagrant@docker  ~  docker ps -a            
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS                     PORTS     NAMES
a668098f6739   httpd     "httpd-foreground"   6 minutes ago   Exited (0) 3 seconds ago             clever_nobel
 vagrant@docker  ~  docker rm clever_nobel 
clever_nobel
 vagrant@docker  ~  docker ps -a             
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

 vagrant@docker  ~  docker create  httpd  
69f28f6d2a5c1c873001e04d0f5fe033f50848a195d073f2e6131a9aafc89404
 vagrant@docker  ~  docker ps -a        
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS    PORTS     NAMES
69f28f6d2a5c   httpd     "httpd-foreground"   5 seconds ago   Created             trusting_franklin
 vagrant@docker  ~  docker start trusting_franklin 
trusting_franklin

 vagrant@docker  ~  docker ps -a  
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS         PORTS     NAMES
69f28f6d2a5c   httpd     "httpd-foreground"   About a minute ago   Up 5 seconds   80/tcp    trusting_franklin

 vagrant@docker  ~  docker kill trusting_franklin  
trusting_franklin

 vagrant@docker  ~  docker ps -a                 
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS                       PORTS     NAMES
69f28f6d2a5c   httpd     "httpd-foreground"   About a minute ago   Exited (137) 4 seconds ago             trusting_franklin

우리가 알고 있는 process와 도커의 LifeCycle은 크게 다르지 않다.

 

 

 vagrant@docker  ~  docker run --help

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
 vagrant@docker  ~  docker run ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
125a6e411906: Pull complete 
Digest: sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d
Status: Downloaded newer image for ubuntu:latest
 vagrant@docker  ~  docker ps -a               
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS                          PORTS     NAMES
3062acbb0c7d   ubuntu    "bash"               About a minute ago   Exited (0) About a minute ago             vigorous_agnesi

docker run ubuntu 명령을 실행했을 때 컨테이너 내부에서 실행하는 어플리케이션이 bash라는 것이다.

docker run --help에서 보면 실제 뒤에 실행할 커맨드를 지정하는 부분이 있는데, 이를 따로 지정하지 않았을 때 ubuntu 이미지에서 기본적으로 실행하는 게 bash이다.

따라서 bash의 명시 여부는 상관 없다.

기본적으로 bash를 실행하는 이미지에서는 이 세가지 옵션이 아주 중요하다.

  • -i (interactive) : STDIN 유지
  • -t () : Terminal 할당
  • -d : Detach

-it 옵션은 Shell을 실행하는 이미지에서 사용 : centos, ubuntu 등
-d 옵션은 application이 계속적으로 실행되어야 할 때 : httpd 등

bash라고 하는 셸은 입력이 들어가고 출력이 나온다.
키보드로 ls를 입력해야 그에 대한 결과가 나오는 것과 같다.

즉, 입력이 들어가야 출력 또는 오류가 발생하는 것이다.

 

기본적으로 도커 클라이언트는 표준 입력을 전송시키지 않는다.

-i 옵션을 사용하면 standard input을 open 시키고 유지한다.
이를 통해 도커 클라이언트가 도커 데몬에게 표준 입력을 전송할 수 있도록 한다.

 

 

 vagrant@docker  ~  docker run -i ubuntu
ls
bin
boot
dev
etc
home
lib
lib32
lib64
libx32
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
hostname
d87968e1eb87

도커 클라이언트의 키보드 입력을 전송시킨다.

 

 

 vagrant@docker  ~  docker ps -a        
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS                        PORTS     NAMES
d87968e1eb87   ubuntu    "bash"               About a minute ago   Exited (0) 6 seconds ago                exciting_knuth
3062acbb0c7d   ubuntu    "bash"               7 minutes ago        Exited (0) 7 minutes ago                vigorous_agnesi
69f28f6d2a5c   httpd     "httpd-foreground"   14 minutes ago       Exited (137) 13 minutes ago             trusting_franklin

bash 라는 것은 입력이 있어야지만 출력을 할 수 있는 app이다.
docker run ubuntu (-i 옵션이 없는 명령) 는 바로 종료되어 버린다.

표준 입력이 없기 때문에, 더 이상 실행될 수가 없다.

 

 

docker run -i ubuntu 

아무것도 진행되지 않는 것 처럼 보이지만 bash는 우리의 입력을 기다리고 있다.
docker ps로 확인하면 현재 실행 중에 있다.

ls는 컨테이너 내에서 bash에게 ls를 표준 입력으로 넣은 것이며 디렉토리 경로가 표준 출력으로 넘어온 것이다.

 

우리가 bash를 실행할 때는 보통 -it 옵션을 주는데

-t : terminal 사용을 의미한다.
-i 옵션만 사용하면 뭔가 진행이 되는지를 잘 모른다.
-t를 부여하면 우리가 흔히 알고 있는 형태로 셸이 터미널에 의해 실행된다.
그리고 우리가 요청하는 표준 입력을 받을 수 있다.

 

 

 vagrant@docker  ~  docker run -it ubuntu
root@63aef66acd0f:/# hostname
63aef66acd0f # 기본적으로 컨테이너의 ID이다.

태그를 직접 지정해 실행해보자

 vagrant@docker  ~  docker run centos:7   
Unable to find image 'centos:7' locally
7: Pulling from library/centos
2d473b07cdd5: Pull complete 
Digest: sha256:c73f515d06b0fa07bb18d8202035e739a494ce760aa73129f60f4bf2bd22b407
Status: Downloaded newer image for centos:7
 vagrant@docker  ~  docker ps -a       
CONTAINER ID   IMAGE      COMMAND              CREATED          STATUS                          PORTS     NAMES
d5091ce5f789   centos:7   "/bin/bash"          2 minutes ago    Exited (0) About a minute ago             peaceful_bose
63aef66acd0f   ubuntu     "bash"               4 minutes ago    Exited (0) 2 minutes ago                  nice_panini
d87968e1eb87   ubuntu     "bash"               9 minutes ago    Exited (0) 8 minutes ago                  exciting_knuth
3062acbb0c7d   ubuntu     "bash"               15 minutes ago   Exited (0) 15 minutes ago                 vigorous_agnesi
69f28f6d2a5c   httpd      "httpd-foreground"   23 minutes ago   Exited (137) 21 minutes ago               trusting_franklin

얘도 /bin/bash 를 실행하고 있다. 이 이미지도 기본적으로 bash를 실행한다.

bash를 실행하는 이미지들은 모두 다 -it 옵션으로 실행할 수 있다.

 

 

 vagrant@docker  ~  docker run -it centos:7
[root@511cf08f6577 /]# hostname
511cf08f6577
[root@511cf08f6577 /]# yum install tree
Loaded plugins: fastestmirror, ovl

Installed:
  tree.x86_64 0:1.6.0-10.el7                                                                                                          

Complete!

[root@511cf08f6577 /]# yum install httpd
Loaded plugins: fastestmirror, ovl

Installed:
  httpd.x86_64 0:2.4.6-97.el7.centos.5                                                                                                

Dependency Installed:
  apr.x86_64 0:1.4.8-7.el7                         apr-util.x86_64 0:1.5.2-6.el7       centos-logos.noarch 0:70.0.6-3.el7.centos      
  httpd-tools.x86_64 0:2.4.6-97.el7.centos.5       mailcap.noarch 0:2.1.41-2.el7      

Complete!

하지만

[root@511cf08f6577 /]# systemctl start httpd
Failed to get D-Bus connection: Operation not permitted

컨테이너는 systemd가 없기 때문에 실행할 수 없다.
start 하고 싶어도 할 수 없다. 컨테이너는 이러한 사용 목적을 가지고 만들어진 것이 아니기 때문이다.

 

 

[root@511cf08f6577 /]# exit     
exit
 vagrant@docker  ~  docker ps              
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

 vagrant@docker  ~  docker ps -a
CONTAINER ID   IMAGE      COMMAND              CREATED              STATUS                        PORTS     NAMES
511cf08f6577   centos:7   "/bin/bash"          About a minute ago   Exited (127) 5 seconds ago              dreamy_sutherland
d5091ce5f789   centos:7   "/bin/bash"          4 minutes ago        Exited (0) 4 minutes ago                peaceful_bose
63aef66acd0f   ubuntu     "bash"               7 minutes ago        Exited (0) 5 minutes ago                nice_panini
d87968e1eb87   ubuntu     "bash"               12 minutes ago       Exited (0) 11 minutes ago               exciting_knuth
3062acbb0c7d   ubuntu     "bash"               18 minutes ago       Exited (0) 18 minutes ago               vigorous_agnesi
69f28f6d2a5c   httpd      "httpd-foreground"   25 minutes ago       Exited (137) 24 minutes ago             trusting_franklin

여기서 조금 이상한 점이 있다.
컨테이너 이미지에는 운영체제가 없다고 해왔다. 실제로 컨테이너는 VM과 다르게 운영체제가 없다.

하지만 Dockerhub에서 다양한 운영체제 이미지를 볼 수 있다.

 

그럼 이런 이미지들의 목적은 무엇일까 ?

 vagrant@docker  ~  docker pull amazonlinux
Using default tag: latest
latest: Pulling from library/amazonlinux
ac1397dc8419: Pull complete 
Digest: sha256:54f592d954725ce989af5ed5fb49e35ab2b1f1d830ee3f1f79b58ed75a631f64
Status: Downloaded newer image for amazonlinux:latest
docker.io/library/amazonlinux:latest
 vagrant@docker  ~  docker run -it amazonlinux
bash-4.2# exit
exit
 vagrant@docker  ~  docker ps -a              
CONTAINER ID   IMAGE         COMMAND              CREATED          STATUS                        PORTS     NAMES
45131b2e90b1   amazonlinux   "/bin/bash"          9 seconds ago    Exited (0) 3 seconds ago                jovial_carver
511cf08f6577   centos:7      "/bin/bash"          10 minutes ago   Exited (127) 8 minutes ago              dreamy_sutherland
d5091ce5f789   centos:7      "/bin/bash"          13 minutes ago   Exited (0) 13 minutes ago               peaceful_bose
63aef66acd0f   ubuntu        "bash"               15 minutes ago   Exited (0) 13 minutes ago               nice_panini
d87968e1eb87   ubuntu        "bash"               20 minutes ago   Exited (0) 19 minutes ago               exciting_knuth
3062acbb0c7d   ubuntu        "bash"               26 minutes ago   Exited (0) 26 minutes ago               vigorous_agnesi
69f28f6d2a5c   httpd         "httpd-foreground"   34 minutes ago   Exited (137) 32 minutes ago             trusting_franklin

이 이미지도 shell을 실행한다. 다른 운영체제 이미지들도 모두 shell을 실행한다.
그렇다면 bash shell 실행시켜서 뭘 할 것인가 ?
결론부터 말하자면 해당 운영체제 이미지들은 다른 이미지들을 만들기 위해 사용한다.

 

리눅스 배포판 이름으로 된 이미지들

  • ubuntu
  • centos
  • rocky
  • alpine
  • busybox
  • amazonlinux
  • oraclelinux
  • ....

→ Base Image : 다른 이미지를 만들 때 사용한다.

 

Packer를 통해 source를 build 할 때 기본 이미지를 가지고 거기에 덧붙여서 새로운 이미지를 만든다.
즉, 커스텀 이미지를 만들 때 쓰라고 만들어놓은 이미지들이다.

이미지를 띄워서 뭔가를 구성을 하고 다시 그것을 이미지로 만들 때 사용한다.

 

컨테이너에는 운영체제가 없다. 이것은 자명하다.
기본적으로 해당되는 배포판에서 사용하는 binary/library가 있다.

정확하게 Bins/Lib만을 제공해주며 그 위에 우리가 실행시킬 어플리케이션을 추가해서 이미지를 만들라고 만들어놓은 것이 Base Image이다.

 

detach 모드라는 것으로 실행해보자

 vagrant@docker  ~  docker run -d ubuntu      
c4c731e23286e5c89a881a0d7e1589e5d4ae308ad46d986dfb907848cce904fd
 vagrant@docker  ~  docker ps           
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

하지만 ubuntu는 -d 옵션으로 실행되지 않는다.

 

 

 vagrant@docker  ~  docker run -it hello-world bash
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "bash": executable file not found in $PATH: unknown.
ERRO[0001] error waiting for container: context canceled 

어떤 이미지는 어떻게 실행해서 어떻게 사용해야하는지를 알아야 한다.
이것을 아는 것이 Docker에서 중요한 부분이다.

728x90