[Docker] 이미지

buckshot·2024년 8월 9일

Docker

목록 보기
2/3

Docker Image

모든 도커의 컨티너는 이미지를 기반으로 생성됙 때문에 이미지에 관련하여 알고 있는 것이 바람직하다.

데미안 운영체제에서 apt-get insatll을 실행하면 apt 리포지터리에서 패키지를 다운받고 레드헷 운영체제에서 yum insatll을 실행하면 yum 리포지터리에서 패키지를 내려받는 것과 유사하게
도커는 기본적으로 Docker Hub라는 중앙 이미지 저장소에서 이미지를 받는다. 이 도커 허브는 도커가 공식적으로 제공하고 있다.

docker create, docker run, docker pull의 명령어로 이미지를 내려 받을 때 도커는 도커 허브에서 해당 이미지를 찾아서 내려 받는다.
대부분의 이미지는 도커 허브에서 공식적으로 제공하거나 (예를 들어서 ubunt, centos 등) 아니면 다른 사람이 허브에 올려둔 (예를 들어 Tomcat, Hadoop 등)것을 받기 때문에 직접적으로 이미지를 만들지 않아도 된다는 장점이 존재한다.

도커 허브에는 어떠한 이미지가 있는지 확인하기 위해서 직접 허브 사이트에 접속하여 찾을 수 있지만, 도커 엔진에서 docker search명령어를 사용하여 검색할 수 있다.

이미지 생성하기

search를 이요하여 검색한 이미지를 pull로 다운을 받을 수 있지만, 컨테이너에 어플리케이션을 위한 특정한 개발 환경을 직접 구축을 하여 사용자만의 이미지를 생성을 해야한다.

이제 이미지 생성하는 방법에 대하여 간단하게 설명을 하겠다.

일단 run 명령어를 이용하여 컨테이너 하나를 생성해준다, 그리고 해당 컨테이너 내부에 변경점을 만들어 준다.

$ docker run -i -t --name my_first_image ubuntu:14.04

~~:# echo test_first >> first

변경점이 생성되었다면 commit명령어를 이용하여 이미지를 생성한다.

$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

형식으로 명령어를 작성하면 된다.


여기서 -a 옵션은 author을 뜻한다. 이는 이미지의 작성자를 나타내는 메타데이터를 이미지에 포함시킨다.
다음으로 -m 옵션은 커밋 메세지 옵션이다.


이미지들을 확인을 하면 방금 생성한 이미지가 잘 나타난다.

이미지 구조

위 처럼 이미지 생성은 commit 명령어를 통하여 쉽게 생성할 수 있다. 그러나 이미지를 보다 효율적으로 사용하기 위해서는 컨테이너가 어떻게 이미지로 만들어지며, 어떠한 구조를 갖고있는지 알아야 한다.

일단 앞에서 생성한 이미지를 이용하여 변경점을 하나 생성한 뒤 이미지를 추가로 하나 더 만들겠다.

이제 ubuntu14.04와 첫 번째 이미지, 두 번째 이미지를 비교를 해보자

$ docker inspect ubuntu:14.04
$ docker inspect my_first_image:first
$ docker inspect my_second_image:second
  • ubuntu:14.04
    ubuntu:14.04
  • my_first_image
    my_first_image
  • my_second_image
    my_second_image

각 이미지에 대한 Layers를 살펴보면 ubuntu:14.04를 기준으로 차례대로 하나씩 추가되었다는 것을 확인할 수 있다. 그리고 각각의 이미지의 크기를 확인하면 188MB라고 나타난다.

그러면 188MB가 3개나 존재하기 때문에 총 564MB의 크기를 차지할까? 이러한 질문에 대한 대답은 "아니다."

이유는 이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함을 하여 새로운 이미지를 생성하기 때문에 전체 이미지의 실제 크기는 188MB + my_first_image의 변경점 + my_second_image의 변경점 총 합이 실제 크기가 된다.

그러면 이제 이미지를 삭제를 해보자

$ docker rmi my_first_image:first

여기서 이미지를 사용하고 있는 컨테이너가 존재하는 상황에서 이미지를 삭제를 할 수 없다. 이 상황에서 -f 옵션을 추가하여 삭제를 하여도 해당 이미지 레어이 퍼일은 실제로 삭제하지 않고 이미지 이름만 삭제하기 때문에 -f 옵션을 추가하여도 큰 의미는 없다.

다음으로 두 번쨰 이미지를 삭제해보겠다.

$ docker rmi my_second_image:second


Deleted 문구가 뜨는 것을 보니 이미지 레이어가 삭제가 되었다.

second 이미지가 삭제가 되었다고 ubuntu 까지 삭제되는 것은 아니다. 앞에서 이미지를 생성할 때 부모 이미지로 부터 변경된 부분만 삭제가 된다.

이미지 추출

도커 이미지를 개별로 저장하거나 옮기는 등 이미지를 단일 바이너리 파일로 저장을 해야 할 순간이 있다. 이런 상황에서는 docker save 명령어를 사용하여 컨테이너의 커멘드, 이미지 이름 및 태그 등 메타데이터를 포함하여 하나의 파일로 추출할 수 있다.

$ docker save -o ubuntu_14_04.tar ubuntu:14.04

이렇게 추출된 이미지는 다시 load명령어를 통하여 도커에 다시 로드될 수 있다.

$ docker load -i ubuntu_14_04.tar

앞에서 save는 커멘드, 메타 데이터가 포함된다고 했었다. 그렇기 때문에 load를 하면 이전의 이미지와 완전히 동일한 이미지가 도커 엔진에 나타나게 된다.

save, load 명령어와 유사한 기능을 하는 명령어가 존재한다. 바로 export와 import 명령어다.
docker commit 명령어로 컨테이너를 이미지로 만들면 컨테이너에서 변경된 부분 뿐만 아니라 컨테이너가 생성될 때 설정한 detached모드, 컨테이너 커멘드와 같은 컨테이너의 설정 등 또한 이미지에 함께 저장된다. 그러나 export 명령어는 컨테이너의 파일 시스템을 .tar파일로 추출하며 컨테이너 및 이미지에 대한 설정 정보를 저장하지 않는다.

$ docker export -o rootFS.tar mycontainer
$ docker import rootFS.tar myimage:0.0

그러나 이미지를 단일 파일로 저장하는 것은 효과적이지 않은 방법이다. 왜냐하면 이미지를 추출하면 이미지 용량이 각기 차기하게 되기 때문이다.

profile
let's go insane

0개의 댓글