본문 바로가기
도커/개발자를 위한 쉬운 도커

2.4 도커(Docker) 이미지와 컨테이너: 컨테이너의 라이프사이클(Lifecycle)

by limdae94 2024. 6. 19.
 

개발자를 위한 쉬운 도커 | 데브위키 - 인프런

데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근

www.inflearn.com

 

1. docker create

docker create

 

컨테이너는 이미지에서부터 시작한다. 이미지는 애플리케이션을 실행할 수 있는 모든 환경이 준비되어 있는 압축 파일이다. 첫 번째로 컨테이너가 가질 수 있는 상태는 Created이다. Created는 생성 단계로, docker create 명령을 사용하면 이미지를 컨테이너로 만들 수 있다. 이미지 생성 단계에서는 컨테이너를 실행하기 위한 격리된 공간이 만들어지는 상태이다. 그래서 네트워크나 스토리지, 환경 변수 같은 모든 리소스가 격리된 공간인 컨테이너로 분리된 상태인 것이다.

2. docker start

docker start

 

하지만 생성 단계에서는 내부에서 프로세스를 실제로 실행하지 않기 때문에 호스트 OS의 CPU 와 Memory를 사용하지 않는다. 이 생성 단계에서 docker start 명령을 사용하면 컨테이너의 메타데이터인 Cmd 값을 사용해서 컨테이너를 실행(Runnig) 상태로 만들 수 있다. 이 실행 상태가 되었다는 것은 컨테이너 내에서 정상적으로 프로세스가 실행 중이라는 것을 의미한다. 그리고 이 프로세스가 실제로 CPU 와 Memory를 사용한다.

 

지금까지 실습에 사용했던 docker run 명령은 docker createdocker start가 하나로 합쳐진 명령이다. 그래서 docker run 명령을 사용하면 컨테이너를 만드는 것과 동시에 바로 실행할 수 있다. 그리고 이 실행 상태에서 docker restart 명령을 하면 프로세스를 재시작시킬 수 있다.

 

3. docker restart

docker restart

 

실행 중인 프로세스에 종료나 재시작 신호를 보내면 10초 뒤에 이 신호가 동작한다. 그래서 docker restart 명령을 보내면 10초 뒤에 프로세스가 재시작하게 된다. 그리고 이 컨테이너에서 실행 중인 프로세스를 일시 정지하거나 종료할 수도 있다. pause 상태에서는 컨테이너에서 실행 중인 모든 프로세스가 일시 중지된 상태이며, 일시 중지한다는 것은 현재의 상태를 모두 메모리에 저장해 두는 것을 의미한다.

 

4. docker pause

docker pause

 

그래서 일시 정지(pause) 상태에서는 CPU는 사용하지 않고 메모리만 사용하게 된다. 그리고 이 상태에서 unpause 명령을 사용하면 프로세스를 일시 정지했던 시점부터 재시작할 수 있다. stopped 상태는 컨테이너에서 실행 중인 프로세스를 완전히 중단시켰다는 것을 의미한다. stopped 상태에서는 메모리와 CPU 사용이 모두 중단된다. 종료된 컨테이너를 다시 시작하면 컨테이너의 프로세스가 처음부터 다시 실행된다. 그리고 이 컨테이너는 모든 상태에서 rm 명령을 사용해서 삭제할 수 있다. 다만 실행 중인 컨테이너를 삭제하려면 이전에 실습했던 것처럼 -f 옵션을 사용해야 한다.

 

정리하자면 컨테이너의 라이프사이클은 크게 생성(create), 실행(start), 정지(pause), 종료(stopped,) 삭제(delete)로 구분된다. 대부분은 컨테이너에서 실행되는 프로세스의 상태와 일치한다. 컨테이너를 학습할 때 프로그램과 프로세스의 차이를 학습한 이유가 컨테이너가 프로세스와 많은 연관성을 가지고 있기 때문이다. 프로세스가 실행되면 컨테이너도 실행되고, 프로세스가 멈추거나 종료되면 컨테이너도 마찬가지로 정지되거나 종료된다. 결국 프로세스를 잘 설계하고 다루는 것이 컨테이너를 잘 사용하는 것과 방향성이 일치한다고 볼 수 있다.

 

5. 컨테이너 라이프 사이클 실습

tencounter, hundredcounter 수행
tencounter, hundredcounter 결과

 

실습을 통해서 컨테이너의 상태를 docker logs 명령을 학습한다. 실습에 사용될 이미지는 10 카운터와 100 카운터이다. 두 컨테이너 모두 실행 후 종료되는 일회성 컨테이너이다. 10 카운터는 1부터 10까지 1초 간격으로 출력하고 종료되고, 헌드레드 카운터는 1부터 100까지 1초 간격으로 출력되고 종료된다. 이제 이번 실습에서 추가로 배울 명령어는 docker logs 명령어이다.

 

6. docker logs

docker logs (컨테이너명)
docker create --name tencounter devwikirepo/tencounter

 

docker ps -a

docker logs 뒤에 컨테이너명을 입력하면 실행 중인 컨테이너의 로그를 확인할 수 있다. 먼저 docker create 명령을 사용해서 컨테이너를 생성 상태로 만들어 보자. docker create --nametencounter라고 입력하고, 이미지는 devwikirepotencounter를 지정한다. 이미지를 다운받는 것을 확인하고 완료되면 docker ps -a를 통해서 컨테이너를 확인해 보면 이렇게 tencountercreate 상태라는 것을 확인할 수 있다.

 

 

docker start encounter
docker ps -a

 

지금 create 상태에서는 CPU나 메모리를 사용하지 않고 오로지 격리된 공간만 만들어진 상태이다. 이제 이 상태에서 docker start 명령을 사용해서 tencounter를 실행한다. 그리고 docker ps -a로 확인해 보면 이렇게 실행 중인 상태인 up 인 것을 확인할 수 있다. 그런데 이 tencounter는 10초 뒤에 종료되기 때문에 조금 기다렸다가 다시 docker ps -a 명령으로 확인해 보면 tencounter 컨테이너가 Exited, 종료된 상태인 것을 확인할 수 있다.

 

docker ps -a

따라서 tencounter 컨테이너 내부에서 실행 중인 프로세스가 10초 뒤에 종료된 상태인 것이다.

 

7. docker start -i tencounter

docker start -i tencounter
docker ps -a
docoer rm tencounter

 

다시 docker Start 명령을 입력하자. -i 옵션을 추가하면 컨테이너를 실행함과 동시에 컨테이너의 출력을 바로 터미널로 연결할 수 있다. 그러면 tencounter를 입력해서 docker start -i tencounter으로 엔터를 누르면 이렇게 컨테이너가 실행되면서 로그가 출력되는 것을 확인할 수 있다. 정확히 10까지만 출력되고 프로세스가 종료되는 걸 확인할 수 있다. 그리고 다시 docker ps -a 으로 컨테이너를 확인해 보면 역시 컨테이너가 종료된 상태인 것을 확인할 수 있다. 그러면 이제 docker rm 명령으로 tencounter 컨테이너는 삭제한다.

 

8. docker pause hundredcounter

docker pause hundredcounter

 

다음으로 hundredcounter를 실습하자. hundredcounter 는 파워 쉘을 하나 더 띄우고 두 개의 쉘로 테스트를 한다. 이렇게 양쪽에 커맨드 창을 띄우고, 먼저 왼쪽 커맨드 창에서 hundredcounter 를 실행한다. docker run --name 으로 hundredcounter라고 입력한다. devwikirepohundredcounter를 입력하고 엔터를 눌러서 수행한다. 역시 이미지가 다운로드 되는 것을 확인할 수 있다. 이번에는 -d 옵션을 주지 않았기 때문에 이렇게 1부터 100까지 출력되는 것을 확인할 수 있다.

 

그러면 이 상태에서 docker pause 명령을 사용해서 실행 중인 컨테이너를 정지한다. 이렇게 24까지 출력된 상태에서 1이 정지된 것을 확인할 수 있다. 이 상태에서는 CPU는 사용하지 않지만 상태가 메모리에 그대로 저장되어 있기 때문에 메모리는 사용하는 상태이다. 여기서 다시 docker unpause 명령으로 100 카운터를 입력해 주시면 다시 정지된 상태에서 그대로 시작되는 것을 확인할 수 있다. 이제 docker stop을 활용해 보자.

 

docker start -i hundredcounter

 

docker stophundredcounter를 입력하면, 프로세스의 종료 명령을 전달한다. 이 종료 명령이 실행 중인 프로세스면 정확히 10초 뒤에 종료한다. 이렇게 stop 명령을 실행하고 10초가 지난 뒤에 프로세스가 종료되는 것을 확인할 수 있다. 여기서 docker ps -a 명령으로 컨테이너의 목록을 출력하면 이렇게 hundredcounter가 종료된 것을 확인할 수 있다. 다시 왼쪽 셸로 이동해서 이번에는 컨테이너를 `docker start -i hundredcounter` 으로 재실행한다.

 

docker start-i, hundredcounter를 입력한다. 이 i 옵션을 주면은 실행되면서 터미널로 바로 연결이 되기 때문에 1부터 출력이 될 것이다. stop된 상태에서 스타트를 다시 했기 때문에 완전히 처음부터 실행되는 것을 확인할 수 있다. 이번에는 다시 2번 셀로 와서 이 컨테이너를 restart한다. docker restart, hundredcounter를 입력하고 엔터를 눌러주면 이 명령도 마찬가지로 재시작 명령이기 때문에 10초 뒤에 컨테이너가 재시작되는 것을 확인할 수 있다.

 

docker logs hundredcounter
docker ps -a

다시 왼쪽 셀로 와서, 재시작이 되었기 때문에 기존에 연결되어 있던 셀은 종료가 된 상태를 확인한다. 빠져나온 상태에서 docker ps 명령을 사용해 보면 이번에는 이 hundredcounterrunning, up 상태인 것을 확인할 수 있다. 이제 실행 중인 컨테이너의 로그를 확인해 보자.

 

docker logs -f hundredcounter
docker logs -f hundredcounter

 

docker logshundredcounter를 입력하면 로그를 이렇게 출력할 수가 있다. 아까 25 상태에서 리스타트가 되었기 때문에 로그가 25 까지 남아있는 것을 확인할 수 있다. 그리고 리스타트를 했기 때문에 다시 1부터 출력이 된 것이다. 그런데 이 로그 명령은 일회성 출력이기 때문에 한 번만 출력되고 종료되는데, 이 로그를 지속적으로 터미널에 띄우려면 docker logs-f 옵션을 추가해서 로그를 계속적으로 출력할 수 있다. 이렇게 docker logs-f hundredcounter 를 입력하고 엔터를 누르면 이렇게 로그가 지속적으로 출력되는 상태를 유지할 수 있다.

 

이 상태에서 빠져나오시려면 저희가 컨테이너에서 빠져나온 것과 동일하게 Ctrl + C를 눌러주면 된다. 이제 docker ps 명령을 사용하면 실행 중인 컨테이너의 로그 출력만 종료한 상태이기 때문에 컨테이너가 여전히 실행 중인 것을 확인할 수 있다. 그러면 이제 컨테이너를 docker rm -f 명령을 사용해서 삭제한다.

 

 

docker rm -f hundredcounter

 

hundredcounter 를 입력해서 엔터를 눌러서 컨테이너를 삭제하고, 컨테이너 라이프사이클 실습을 마친다. 이번 파트에서는 이미지에 대해서 알아보고, 이 이미지를 통해서 컨테이너를 실행하는 과정을 관찰해 보면서 이미지와 컨테이너의 관계를 분석해 보았다. 그리고 이미지가 이미지의 압축 파일과 메타데이터로 구성되어 있다는 것을 학습하고, 메타데이터의 CMD 와 ENV 를 덮어씌우면서 테스트해 보았다. 그리고 컨테이너가 가질 수 있는 다양한 상태들을 확인해 보면서 컨테이너의 라이프사이클을 정리했다. 이제 다음 파트에서는 이미지를 다운받고 공유할 수 있는 공간인 이미지 레지스트리에 대해서 학습한다. 이것으로 두 번째 파트를 마친다.