개발자가 처음 Docker 접할때 오는 멘붕 몇가지

송예인·2021년 1월 20일
0

일단 도커는 virtual machine이 아니다!

여기서 우분투 image를 실행했는데 왜 아무것도 실행되지 않고 바로 Exit되었을까??
docker컨테이너는 virtual machine과 같이 하나의 온전한 서버를 제공하는 것이 아니라, 명령을 실행하는 환경만 제공하고 그 명령을 실행할 뿐이다.

/bin/bash 19 seconds ago

  • 여기서 알수 있는건 우분투 컨테이너를 실행하면 우분투 서버가 실행되는 것이 아니라 "/bin/bash"가 실행되는 것 뿐이다.
  • docker image에서 설정된 default 실행 명령인 "/bin/bash"를 실행하고 그 결과를 출력하고 종료된 것. "/bin/bash"명령은 표준 출력(STDOUT)또는 표준 입력(STDERR)로 아무것도 출력을 하지 않기 때문에 사용자가 보기에는 실행이 안된 것과 같은 느낌으로 다가 온다.

마지막에 주는 인자 값은 컨테이너가 실행할 명령을 전달하는 인자이다.
아무런 값을 입력하지 않으면 /bin/bash가 실행되고, 인자를 전달하면 그 값이 실행된다.
"env"명령은 환경 정보를 출력하는 명령이다.

우분투의 bash shell에서 명령을 실행하려면

  • i: interactive 모드로 표준입력과 표준풀력을 키보드와 화면을 통해 가능하도록 하는옵션
  • t: 텍스트 기반의 터미널(TTY)를 애뮬레이션 해주는 옵션

여기서!!
해당 shell이 나오고 내가 필요한 명령이 사용가능하게 되면 마치 우분투 서버가 실행되었다는 착각을 하게 됨 그리고 해당 shell에 tomcat 이나 railes같은 애플리케이션 서버를 설치하고, 실행해본다. 잘 돌아간다. 문제는, 이렇게 한 다음 shell에서 exit를 입력하여 shell을 나오는 순간 컨테이너는 중지된다.

현재, -it옵션을 써서 입출력을 interactive하게 하노 TTY터미널을 애뮬레이션 해주는 것은 백그라운드로 실행시켰고 + attach명령은 virtual machine의 리모트쉘 접속과 같은 개념이 아니라 컨테이너의 현재 Host OS shell의 stdout, stderr을 docker 컨테이너에 붙이는 명령인 것 뿐이다.-> 사실 이부분이 이해가 잘 안간다..

Docker에 애플리케이션 서버 실행하기

위 실행옵션은 /bin/bash를 돌면서 -c 옵션에 있는 명령을 실행하는 것이다.
-c에 있는 옵션은 무한루프를 돌면서 100초마다 한번씩 "still live"를 출력하는 기능을 수행하는 shell script이다.이렇게 무한루프를 도는 명령을 -d 옵션을 이용하여 백그라운드로 실행하기 때문에 컨테이너 실행 후 바로 Host OS의 Prompt로 돌아오지만 컨테이너는 여전히 살아있는것을 확인할 수 있다.

결론, Docker의 컨테이너 내에 애플리케이션 서버를 실행하려면 애플리케이션 서버가 무한루프로 동작하게 해야 한다. 하지만 이미 애플리케이션 서버들은 무한루프로 동작하는 프로그램이다. 따라서 "Docker 컨테이너에서 실행되는 애플리케이션 서버는 back ground모드가 아닌 fore ground모드로 실행해야 한다."

예를 들어 shell에서 그냥 tomcat명령을 실행하면 foreground로 실행이 되는데 여기서 shell을 닫아버리면 해당 shell에서 실행된 tomcat명령은 종료가 된다.
백그라운드로 실행하면 tomcat은 shell이 종료되어도 여전히 존재한다. 하지만 tomcat내에서 무슨 문제가 발생하여 tomcat이 죽어버리게 되면 이 프로세스는 없어지게 된다.
docker run -d 옵션과 container 내에서의 foreground,background의 차이는 이런 의미!
결론적으로, host에서 실행되는 프로세스(=docker container) 자체에 대한 백그라운드 실행을 담당하고 container내부에서는 foreground로 줘야만 container내부에서의 명령 실행 종료로 인한 host에서의 docker container프로세스가 완료되는것 방지할 수 있다.

프로그램에서 출력하는 로그는 어떻게 해야하나?

docker 컨테이너에 애플리케이션 서버를 실행하는 경우 로그는 어떻게 해야할까
1. 이전과 동일하게 파일로 저장
컨테이너의 특정 디렉토리에 저장한다는 의미인데, 이렇게 할 경우 해당 컨테이너가 삭제되 면, 로그도 함께 삭제되기 때매 권장X
2. 모든 로그를 표준 출력(STDOUT)또는 표준 에러(STDERR)로 출력한다.
docker는 컨테이너에서 모든 로그를 표준 출력으로 보내 Host OS의 특정 디렉토리에 저장 하고 쉽게 조회할 수 있게 한다.(docker logs명령)
이방식의 경우 로그 파일을 하나의 파일로 관리하게 되어 파일이 너무 커지게 되어 스토리지 를 모두 차지하게 되는 문제가 있음
3. 1번처럼 파일에 로그를 저장하지만 로그 디렉토리를 Host Os의 볼륨을 이용한다
컨테이너 생성시 볼륨을 붙여준다.

0개의 댓글