컨텐츠 내 위젯


도커 이미지의 이해를 위한 튜토리얼(4 / 6) 프로그래밍 상식

본 글은 https://qiita.com/zembutsu/items/24558f9d0d254e33088f 의 번역본 이며, 글 내용에 대한 권리는 원작자에게 있습니다.

4. hello-world 도커 컨테이너의 실행

다음으로 hello-world 이미지를 사용해, 도커 컨테이너 (이하, 컨테이너로 생략) 을 실행합니다. 실행하기 전에, 컨테이너는 무언가를 단순히 복습합니다. 한마디로 정리하자면, 특별한 상태로 리눅스 프로세스를 기동합니다. 도커는 리눅스 커널이 가진 이름공간 (네임스페이스)의 분리기술혹은 cgroup 에 의한 소스제한, 그 밖에 도커 엔진의 실장(역자 - 장치 등을 구성 개체, 추가 개체)에 따라 도커 이미지안에 있는 파일시스템 안에서 프로그램을 특별한 상태로 하여 기동합니다.


즉, hello-world를 도커 컨테이너로 움직인다는것은,

- hello-wrold 라는 이름의 도커 이미지를 준비한다.
- hello-wold의 이미지 안에 있는 무엇인가의 프로그램을 실행한다.
- 이미지내 정의(CMD 명령)으로 /hello 를 자동적으로 실행한다.
- 그러나 /hello 를 컨테이너로써 (네임스페이스 등의 제약을 받고) 실행.

이상의 동작을 행합니다.

또, 컨에이너는 컨테이너용 읽고쓰기가 가능한 도커 이미지·레이어가 자동적으로 작성됩니다. 이 이미지·레이어는 통상 이미지용과 같이, 친자 상속관계를 가집니다. 그렇기 때문에 같은 호스트 상에서 복수의 컨테이너를 실행하더라도 원래 존재하는 도커 이미지 이상의 용랴을 필요로 하지 않는 이점이 있습니다.


그럼 hello-world 컨테이너를 실행합니다. docker run hello world를 실행 해봅시다.

$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.
...省略...
For more examples and ideas, visit:
https://docs.docker.com/get-started/


이렇듯이 직접 hello의 바이너리를 실행한것과 같은 처리(문자열의 표시)를 했는지 알 수 있습니다.

중요한것은, 이 hello 바이너리는 호스트상의 존재하고 있다는 점 입니다. 좀 전에 본 도커 이미지의 실체로써 hello가 놓여져 있는 패스에 있습니다. 단지, 컨테이너로써 실행하고 있으니깐, hello는 PID(프로세스 식별자) 네임스페이스를 분리하기 위해 hello만 존재하는 프로세스 공간입니다. (역자 주 - hello 바이너리는 호스트 상에 존재하는데 별도의 네임스페이스를 갖도록 분리된 프로세스 공간에 배치하여 사용한다는 의미입니다. ) 더욱이, mount 네임스페이스의 분리에 의해 hello 가 존재하는 디렉토리가 컨테이너를 실행하는 프로세스 공간으로써 '/'로 마운트 됩니다.


즉, '/hello'밖에 없는 파일시스템 상에서 리눅스 유저공간으로 hello의 단일 프로세스만 존재하는 것처럼 특별한 상태를 지니게 합니다. 이것이 도커의 컨테이너 입니다. 그리고, 컨테이너는 이 네임스페이스에서 PID(프로세스 식별자)를 1로해서 hello를 실행합니다. hello가 화면상 문자열로 출력된 다음 exit 상태가 되어, 컨테이너 그자체가 실행 완료(extied)가 됩니다.



이대로,
- docker 이미지를 준비한다
- docker 컨테이너용 네임스페이스공간 (PID, mount, 등등)을 분리 (isolate) 한 환경을 작성
- docker는 docker 이미지의 안에 있는 파일 (바이너리 등의 프로그램)을, 그 네임스페이스 안에서 실행
- 실행한 프로그램을 처리완료하면, 도커 컨테이너도 완료(정지) 한다.

이 컨테이너 기동으로부터 완료까지의 흐름을, 도커의 라이프사이클이라 부르겠습니다.
컨테이너 상태를 조사하려면 docker ps에 -a (전부를 의미) 플래그를 붙여봅시다.

$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e8c0bab26796 hello-world "/hello" 4 minutes ago Exited (0) 4 minutes ago frosty_bhabha


- CONTAINER ID... 컨테이너에 대하여 랜덤 할당되는 64문자의 컨테이너 ID 입니다. 이 컨테이너 ID 또는 컨테이너명으로 컨테이너를 조작합니다.
- IMAGE... 컨테이너 실행의 원본이되는 이미지 명입니다.
- COMMAND... 컨테이너 안에 현재 실행되고 있는 커맨드 입니다.
- CREATE... 컨테이너가 언제 작성되었는가 입니다.
- STATUS... 컨테이너의 상태입니다.
- PORT... 컨테이너가 포트를 공개하고 있는 경우에는, 여기에 표시 됩니다.
- NAMES... 실행시에 지정하지 않으면 자동적으로 랜덤한 문자열 (형용사 + 계산식과학계의 공헌자) 링크 : https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go

이 hello-wrold 컨테이너는 이 컨테이너 전용의 네임스페이스에서 /hello 프로그램을 실행하고, 완료했습니다. docker ps 로 표시된것은 컨테이너라는것 보다도, 컨테이너용 이미지레이어의 일람표시(역자 - 메타정보 같은 것들을 한 눈에 보여주는것)를 하고 있다, 라고 생각하는게 편하게 이해됩니다.

hello-world 컨테이너는 너무 심플하므로, 이거 이상으로 컨테이너 안의 조작은 일으킬 수 없습니다. 리눅스 디스트리뷰전(배포판)에 포함되어 있는 커맨드나 쉘이, 이 이미지에는 담겨있지 않기 때문입니다.
마지막으로, 이 컨테이너를 삭제합니다. docker rm <컨테이너 ID 혹은 컨테이너명> 을 실행합니다.

$ docker rm e8
e8
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

덧붙여, 이렇듯이 컨테이너 ID는 미리 일치시켜 지정할 수 있습니다. 긴 컨테이너 ID는 복사 해두지 않더래도, 통상 2항 혹은 3항으로 지정하더래도 조작이 가능하니까 편리합니다. 그리고, docker ps -a 을 실행하면, 컨테이너(용의 이미지레이어)가 남아 있지 않다는걸 알 수 있습니다.

여기서 docker run 에 새로운 옵션 --rm 을 붙여서 실행해보도록 하죠.
$ docker run --rm hello-world
$ docker ps -a

이 옵션을 붙이면, 컨테이너가 완료되면, 자동적으로 컨테이너 (용 이미지레이어)을 삭제합니다. 기억해 두면, 일시적으로만 컨테이너를 실행할때에 편리한 옵션입니다.



덧글

댓글 입력 영역




(adsbygoogle = window.adsbygoogle || []).push({});