Docker

[Docker] exec, attach, run 비교하기

언킴 2022. 3. 3. 15:57
반응형

도커에서 컨테이너를 실행시킬 경우 run, exec, attach 등을 사용해 컨테이너에 접근해본 적이 있을 것이다. 그렇다면 각각의 명령어가 어떠한 차이점이 존재하는지에 대해서 알아보자. 이번 글에서는 exec를 기준으로 run와 attach에 대해서 각각 비교해볼 것이다. 

 

exec vs attach

exec와 attach는 둘다 컨테이너에 접속하는 명령어다. 둘다 컨테이너가 실행되고 있을 때 사용할 수 있으며, 만약 docker ps 를 입력했을 때 실행 중인 컨테이너가 없다면 실행할 수가 없으므로 새롭게 컨테이너를 실행시키든, 죽은 컨테이너를 살리든 하는 형태로 진행해야만 한다. 

 

exec

exec는 컨테이너 상태를 디버깅하기 위한 용도로 주로 사용된다. exec는 컨테이너 외부에서 접근해 코드를 작동시키지만, 컨테이너 내부에서 커맨드를 실행하는 것과 동일한 형태로 결과를 출력한다. 다만, cd 명령어만 실행하지 못한다. 

 

컨테이너가 실행되는 동안에만 실행되며 컨테이너를 다시 시작해도 다시 시작되지 않는다. 또한 도커 컨테이너를 run 할 경우 /bin/bash의 명령어를 실행하지 않고 run하더라도 /bin/bash에 접속이 가능하다. 

 

$ docker ps
CONTAINER ID   IMAGE               COMMAND     CREATED       STATUS        PORTS     NAMES
144d8d383027   python:3.8.3-slim   "python3"   7 hours ago   Up 1 second             nervous_satoshi


$ docker exec 144d8 ls
bin
boot
dev
etc
home
lib
lib64
media
...



$ docker exec -it 144d8 /bin/bash
root@144d8d383027:/#
$ docker exec <CONTAINER ID> <OPTIONS>

 

컨테이너 ID를 입력해 exec로 접근하여 ls를 출력하면 아래와 같이 컨테이너 내부에서 출력한 것과 동일한 결과를 출력하는 것을 확인할 수 있다. 또한 /bin/bash로 접근해 bash shell을 사용한다고 선언해주고, -it를 통해 접속을 유지한다는 명령어를 입력해주면 root@144d8~~로 localhost가 아닌 컨테이너 내부에 들어와 있는 것을 확인할 수 있다. 

 

 

 

attach

attach는 컨테이너 내부에 다시 접근하게 해주는 명령어이다. Apache나 MySQL과 같은 프로그램을 작동 중인 컨테이너에 attach로 접근하게 될 경우 간혹 컨테이너가 비정상적으로 종료되는 경우가 있기 때문에 주의해야한다.  셸에 접근한 후 빠져나오고 싶을 땐 ctrl + pq를 통해 빠져나올 수 있다.

 

exec와는 달리 attach 는 처음 컨테이너를 run 할 때 /bin/bash를 지정해주지 않으면 bash Shell에 접근이 불가능하다. 

 

$ docker attach <CONTAINER ID>

컨테이너 ID 대신에 이름을 명시해주어도 상관없다. 

 

 

exec vs run

사실상 두 명령어를 비교한다는 것이 조금 이상하긴 하다. 하지만 도커를 처음 시작하는 사람에게는 헷갈릴 수 있는 내용이기 때문에 간단하게 언급한다. 일단 run은 컨테이너를 시작시키고, 명령이 끝나면 빠져나간다. run은 이미지로부터 새로운 컨테이너를 생성할 수 있지만, exec는 위에서 언급했듯 작동 중인 컨테이너에만 존재해야지 접속이 가능하다. 

 

run

$ docker run -it --name <CONTAINER NAME> /bin/bash

위와 같이 /bin/bash를 통해 bash shell을 실행하게 되면 나중에 attach를 통해서도 bash shell을 사용할 수 있을 것이다. 

 

 

run : 새로운 컨테이너를 생성해 실행하는 명령어

exec : 실행 중인 컨테이너에 명령어를 전달(외부 -> 내부)

attach : 실행 중인 컨테이너에 직접 들어가 명령어를 실행 (내부 접근)