Simple is IT, 누구나 보고 누구나 깨닫는 IT

Docker 이미지 정복하기_허브 저장소와 이미지 관리 및 구조 (1/2) 본문

Simple is IT/Cloud & Container

Docker 이미지 정복하기_허브 저장소와 이미지 관리 및 구조 (1/2)

currenjin 2020. 7. 28. 16:17

Docker Image

모든 컨테이너는 이미지를 기반으로 생성됩니다. 그래서 우리가 도커 컨테이너를 생성하기 위해선 이미지 다루는 방법을 알아야 하죠.

다루는 내용은 아래와 같습니다.

  • Docker Hub
  • 이미지 생성과 삭제를 위한 명령어
  • 도커 이미지의 구조 이해
  • 이미지 추출과 배포를 위한 저장소 생성

 


Docker Hub & Docker Engine

도커 허브

데비안/우분투에서 apt-get install 명령을 실행하면 apt 레포지터리에서 패키지를 내려받습니다. 레드햇에서 yum install 명령을 실행하면 yum 레포지터리에서 패키지를 내려받습니다.

이처럼 도커에서도 docker create/run/pull 명령을 사용하면 기본적으로 도커 허브(Docker Hub)라는 중앙 이미지 저장소에서 쫙 스캔한 후 이미지를 내려받아요.

도커 허브는 도커가 공식적으로 제공하는 이미지 저장소로서, 도커 계정을 갖고 있다면 누구든지 이미지를 올리고 내려받을 수 있어 다른 사람들과 쉽게 이미지를 공유할 수 있답니다.

 

docker search 명령을 입력하면 도커 허브의 이미지를 검색할 수 있어요.

# docker search ubuntu
NAME      DESCRIPTION                                     STARS       OFFICIAL   AUTOMATED
ubuntu    Ubuntu is a Debian-based Linux operating sys…   11157       [OK]

 

 

이미지 생성

앞서 입력한 docker search 명령으로 검색한 이미지는 docker pull 명령으로 내려받아 사용할 수도 있습니다. 하지만 도커로 개발하는 많은 경웅에는 컨테이너에 애플리케이션을 위한 특정 개발 환경을 직접 구축한 뒤 사용자만의 이미지를 직접 생성할 것입니다.

이를 위해 컨테이너 안에서 작업한 내용을 이미지로 만들어 볼게요.

# docker run -it --name hello alpine
/ # echo hello! > hello.txt

컨테이너를 생성할 때 사용한 이미지는 alpine linux입니다. 크기가 매우 경량화돼있는 장점이 있죠.

컨테이너에 hello.txt 이름을 가진 파일을 추가했어요.

 

기존 alpine linux 이미지에서 변경 사항이 있다면 hello.txt 파일을 갖고 있는 것입니다.

변경된 사항을 이미지로 저장하는 docker commit 명령어를 입력할게요.

# docker commit \
> -a "hyun0524e" -m "hello image" \
> hello \
> hello:0.0
sha256:f7e6f77ba29996e511d203aa95c0d84654a189c4909ed533d9b107d41195b611

저장소 이름은 입력하지 않아도 상관없어요. 하지만 이미지의 태그를 입력하지 않으면 자동으로 latest로 설정된답니다.

-a 옵션은 author를 뜻하며, 이미지의 작성자를 나타내는 메타데이터를 이미지에 포함시켜요.

-m 옵션은 커밋 메시지를 뜻하며, 이미지에 포함될 부가 설명을 입력해요.

 

생성된 이미지를 확인해봤어요!

# docker images
REPOSITORY      TAG            IMAGE ID         CREATED             SIZE
hello           0.0            f7e6f77ba299     22 seconds ago      5.57MB
alpine          latest         a24bb4013296     8 weeks ago         5.57MB

0.0이라는 태그로 이미지가 생성됐군요.

원본 이미지와는 차이가 없습니다. 겨우 bytes에 불과한 내용이 변경됐기 때문이죠.

 

 

이미지 구조

위 처럼 컨테이너를 이미지로 만드는 방법은 commit 명령으로 손쉽게 구현할 수 있습니다. 하지만 이미지를 좀 더 효율적으로 다루기 위해 컨테이너가 어떻게 이미지로 만들어지는지, 구조는 어떤지를 알 필요가 있죠.

아래 명령어를 입력하면 이미지의 전체 정보를 알 수 있습니다.

# docker inspect alpine
# docker inspect hello:0.0
[alpine]

"Layers": [
                "sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a"



[hello:0.0]

"Layers": [
                "sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a",
                "sha256:85fa24607ff757324074754f25fb18302512ac7ea44f700def4bcfae0f4db8cf"
            ]

 많은 정보 중에서 우리가 주목해야 할 것은 alpine, hello 이미지의 Layers 항목입니다.

이 내용을 알아보기 쉽게 그림으로 나타내볼게요.

alpine linux 이미지와 hello:0.0 이미지가 서로 5.7MB라고 출력이 되어도 5.7MB 크기의 이미지가 각각 존재하는 것은 아니에요. 이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함해 새로운 이미지를 생성하기 때문에 전체 이미지의 실제 크기는 5.7MB + hello:0.0 변경 사항 크기가 되죠.

이런 레이어 구조는 docker history 명령으로 더욱 쉽게 확인할 수 있답니다.

# docker history hello:0.0
IMAGE         CREATED        CREATED BY                           SIZE    COMMENT
f7e6f77ba299  16 minutes ago /bin/sh                              34B     hello image
a24bb4013296  8 weeks ago    /bin/sh -c #(nop)  CMD ["/bin/sh"]   0B
<missing>     8 weeks ago    /bin/sh -c #(nop) ADD file:c92c248…  5.57MB

 

만약 alpine linux 이미지를 삭제하면 어떻게 될까요?

# docker rmi alpine
Error response from daemon: conflict: unable to remove repository reference "alpine" (must force) - container f7d8f3ab9b25 is using its referenced image a24bb4013296

해당 이미지를 사용 중인 컨테이너가 존재하므로 삭제할 수 없다는 내용이군요. -f 옵션을 추가하면 강제로 삭제할 수는 있지만 실제 레이어 파일은 삭제되지 않기 때문에 의미가 없습니다.

사용 중인 이미지를 docker rmi -f로 강제 삭제하면 이미지의 이름이 <none>으로 변경돼요. 이 이미지는 댕글링(dangling) 이미지라고 불리죠. 댕글링 이미지는 docker images -f dangline=true 명령으로 확인할 수 있습니다. (사용 중이지 않은 댕글링 이미지는 docker image prune 명령으로 한 번에 삭제할 수 있습니다)

그렇기 때문에 이미지를 삭제하기 위해선 해당 이미지에 의존하는 모든 것들을 먼저 지워야하죠.

# docker stop hello && docker rm hello
hello
hello

# docker rmi hello:0.0
Untagged: hello:0.0
Deleted: sha256:f7e6f77ba29996e511d203aa95c0d84654a189c4909ed533d9b107d41195b611
Deleted: sha256:d1257920df0f85735b7ff4bffff68bbe30407e137adeecac534a641f9fbf9a6a

# docker rmi alpine
Untagged: alpine:latest
Untagged: alpine@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Deleted: sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e

여기서 Deleted는 이미지 레이어가 실제로 삭제되었다는 의미에요. 역시 부모 이미지가 존재하지 않아야 전부 삭제가 가능합니다.

그렇지만 hello:0.0 이미지만 삭제했을 때에는 alpine 이미지가 같이 삭제되진 않습니다. hello:0.0 이미지에 추가된 파일이 존재하는 레이어만 삭제되고, alpine 이미지 태그는 아직 존재하기 때문이죠.

 

이미지 추출과 배포를 위한 저장소 생성 파트는 다음 포스팅에서 다루겠습니다.

궁금하거나, 이런 부분을 추가했으면 좋겠다는 점은 댓글 남겨주세요. 많은 도움이 됐길 바랍니다!

Comments