도커 이미지(Docker image)
-가상머신의 이미지
가상 머신의 특정 상태를 그대로 저장해두고, 이를 나중에 다시 복원하는 것이 가능합니다.
일반적으로 매우 큰 편이며, 파일 시스템을 비롯해 이미지를 만드는 시점의 메모리 내용과 그 외에 시스템을 구성하기 위한 다양한 정보들을 포함하고 있습니다.
-도커 이미지
도커 이미지는 그냥 순수한 파일들의 집합입니다. 메모리 정보나 그 이외의 독자적인 형식으로 저장해둔 시스템의 정보 같은 것은 없습니다.
파일이 아닌 메타 데이터 정도가 존재합니다.
컨테이너에서 가장 핵심적인 역할을 하는 기능이 바로 chroot와 같이 프로세스가 바라보는 루트 디렉터리를 바꾸는 기능입니다.
일반적으로 리눅스 시스템에서 모든 프로세스는 같은 루트를 공유합니다. 그런데 chroot를 사용하면 실제 루트가 아닌 다른 디렉터리를 루트로 바라보는 프로세스를 실행하는 것이 가능합니다. 즉, 이미지는 컨테이너가 바라보는 새로운 루트 디렉터리라고 할 수 있습니다.
쉽게말해, 이미지를 통해 생성한 컨테이너는 루트 디렉터리에서 파생된 자식이라고 볼 수 있는 것입니다.
컨테이너의 특별한 점은 호스트의 루트가 아닌 별도로 준비된 배포판의 파일들을 담은 이미지를 루트 디렉터리로 사용한다는 점입니다.
하지만 실행중에 호스트 시스템의 리눅스 커널은 그대로 공유합니다.
도커에서 제공하는 베이스 이미지
리눅스의 배포판이란 ?
리눅스 커널을 사용하는 다양한 리눅스 배포판들이 있습니다. 예를들어, 우분투, 데비안, 레드햇, 오픈수세, 젠투, 아치, 아마존 리눅스 등이 잇으며 도커에서 경량 환경으로 애용되는 알파인도 있습니다. 사용자들은 일반적으로는 이러한 리눅스 배포판 이미지를 베이스 이미지로 삼아 커스텀 이미지를 만듭니다.
이미지의 풀 네임은 이미지 이름과 태그 이름으로 조합됩니다. ubuntu:18.04를 지정하면 18.04버전을 사용할 수 있고, ubuntu:21.04를 지정하면 21.04버전을 사용할 수 있습니다.
이제 커스텀 이미지를 생성하는 것을 실습을 통해 알아보겠습니다.
git이 설치된 ubuntu:18.04 이미지를 생성해보겠습니다.
➜ ~ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
Digest: sha256:ca70a834041dd1bf16cc38dfcd24f0888ec4fa431e09f3344f354cf8d1724499
Status: Image is up to date for ubuntu:18.04
docker.io/library/ubuntu:18.04
➜ ~ docker images | grep 18.04
ubuntu 18.04 2d07c6c16e27 3 days ago 56.7MB
➜ ~ docker run -it ubuntu:18.04 git --version
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "git": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
➜ ~ docker run -it ubuntu:18.04 bash
root@e9e61d06923a:/# apt update
root@e9e61d06923a:/# apt install -y git
root@e9e61d06923a:/# git --version
git version 2.17.1
git이 잘 설치되었습니다. 이제 bash쉘을 종료하고 새 컨테이너에서 git --version을 실행해보면, git은 존재하지 않습니다.
➜ ~ docker run -it ubuntu:18.04 bash
root@f873a1efe3b6:/# git --version
bash: git: command not found
docker commit 명령어로 이미지 만들기
➜ ~ docker diff f873a1efe3b6
아무것도 출력되지 않는다면, 정상입니다.
root@f873a1efe3b6:/# touch hello world
root@f873a1efe3b6:/# ls
bin dev hello lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr world
이제 다시 docker diff 명령어를 실행해 보겠습니다.
➜ ~ docker diff f873a1efe3b6
A /hello
A /world
이전과는 출력이 달라졌습니다. A는 파일이 추가되었다는 것을 의미합니다. 즉 /hello와 /world 파일이 추가된 것입니다.
이제 이 컨테이너의 파일 공간을 이미지로 저장해보겠습니다.
➜ ~ docker commit f873a1efe3b6 ubuntu:hello-world
sha256:b836b1b5a8d6956c0740f2021eaa60977eeeae0ad6e022089ac2c1cbda340851
➜ ~ docker images | grep hello-world
ubuntu hello-world b836b1b5a8d6 17 seconds ago 56.7MB
hello-world라는 이름의 이미지가 생성된 것을 확인할 수 있습니다.
➜ ~ docker run -it ubuntu:hello-world
root@0857aeb0dfa3:/# ls
bin dev hello lib mnt proc run srv tmp var
boot etc home media opt root sbin sys usr world
hello-world이미지로 컨테이너를 생성하니, hello와 world라는 파일이 생성되어 있는 것을 확인할 수 있습니다.
➜ ~ docker diff 0857aeb0dfa3
아무것도 출력되지 않습니다. 컨테이너의 기반이 된 이미지와 현재 컨테이너의 파일 공간에 다른것이 없기 때문입니다.
컨테이너를 종료시키지 않고 빠져나오려면 Ctrl을 누른상태에서 P와 Q를 한번씩 눌러주면 된다.
출처: https://mosei.tistory.com/entry/Docker-Container-접속과-종료-시-주의할-점 [씹어먹는 블로그:티스토리]
다음의 내용을 참고했습니다.