도커 이미지

Q·2022년 7월 24일
0

Docker

목록 보기
8/14

Contents

  • 도커 이미지 생성
  • 이미지 구조 이해
  • 이미지 추출
  • 이미지 배포(Docker Hub / Private Registry)

데비안 운영체제에서 apt install을 실행하면 apt 레포지토리에서 패키지를 내려받는 것처럼 도커는 기본적으로 도커 허브(Docker Hub)는 중앙 이미지 저장소에서 이미지를 내려받습니다. 도커 허브는 도커가 공식적으로 제공하고 있는 이미지 저장소로서, 도커 계정을 가지고 있다면 누구든지 이미지를 올리고 내려받을 수 있어서 쉽게 다른 사람들과 이미지를 공유할 수있습니다.

docker create, docker run, docker pull 명령어로 이미지를 내려받을 때, 도커는 도커허브에서 해당 이미지를 검색한 뒤에 내려 받습니다. 단,누구나 이미지를 올릴 수 있기 때문에 Official 라벨이 없는 이미지는 주의해서 사용해야 합니다.

(Private 저장소도 존재합니다.)

도커 허브에 어떤 이미지가 있는지 확인하기 위해서는 도커 허브 사이트를 직접 접속해서 찾아볼 수도 있지만, 도커 엔진에서 docker search 명령어를 통해 찾아볼 수도 있습니다.

docker search ubuntu를 입력한 결과

1. 도커 이미지 생성


docker search를 통해 검색한 이미지를 pull 명령어로 내려받아 사용할 수도 있지만, 도커를 개발하는 많은 경우에는 컨테이너에 어플리케이션을 위한 특정 개발환경을 직접 구축한 뒤 사용자만의 이미지를 직접 생성해야 합니다.

먼저 컨테이너 안에서 작업한 내용을 이미지로 만드는 방법에 대해서 알아보겠습니다.

docker run -it --name commit_test ubuntu:20.04

우선 위 명령어를 통해 이미지로 만들 컨테이너를 생성하고, 컨테이너 내부에 first라는 이름의 파일을 하나 생성해 기존의 이미지로부터 변경점을 만들겠습니다.

echo test_first! >> first

변경사항을 만들었다면, 컨테이너에서 빠져나와 docker commit 명령어를 입력하여 컨테이너를 이미지로 만듭니다.

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

1. docker commit \
2.     -a "changjun" -m "my first commit" \
3.     commit_test \
4.     commit_test:first

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

-m 옵션은 커밋 메세지로, 이미지에 포함될 decription을 입력합니다.

위 명령어에서 이미지의 이름은 commit_test로, 태그는 first로 설정했습니다. 태그를 설정하지 않으면 자동으로 latest로 설정됩니다.

docker images 명령어로 이미지가 생성된 것을 확인할 수 있습니다.

단지 first라는 파일 하나만 추가되었기 때문에 기존 ubuntu 이미지의 사이즈와 큰 차이가 없습니다.

생성된 commit_test 이미지를 통해서 새로운 컨테이너를 만들어 commit_test:second라는 이미지를 새롭게 생성해보겠습니다.

1. docker run -it --name commit_test2 commit_test:first
2. echo test_second! >> second
3. exit
4. docker commit \
5.     -a "changjun" -m "my second commit" \
6.     commit_test2 \
7.     commit_test:second

commit_test:second가 생성된 것을 확인할 수 있습니다.

2. 이미지 구조 이해


이미지를 조금 더 효율적으로 다루기 위해서 컨테이너가 어떻게 이미지로 만들어지며,이미지의 구조는 어떻게 구성되어 있는지 알아볼 필요가 있습니다.

다음 명령어를 통해서 이미지의 자세한 정보를 확인해보겠습니다.

1. docker inspect ubuntu:20.04
2. docker inspect commit_test:first
3. docker inspect commit_test:second

ubuntu:20.04

commit_test:first

commit_test:second

많은 정보가 출력되지만, Layer 항목만 나타내면 위와 같습니다.

이미지를 커밋할 때에는 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 새롭게 생성한 레이어를 포함하여 새로운 이미지를 생성하게 됩니다.

즉, 위 출력에서 보듯이 ubuntu:20.04 이미지를 기반으로 생성했던 첫 번째 컨테이너 commit_test에서 변경된 사항(first파일)이 포함된 sha256:3812c81ff232 레이어가 추가되어 commit_test:first 이미지를 생성했고, commit_test:second도 마찬가지로 second 파일이 추가된 레이어가 베이스 이미지에 추가되어 이미지가 생성되었습니다.

이미지 삭제

생성된 이미지 삭제는 아래의 명령어로 삭제합니다.

docker rmi commit_test:first

만약 해당 이미지를 사용하는 컨테이너가 존재하면, 아래의 에러를 출력합니다.

위 경우에는 commit_test2가 commit_test:first 이미지를 사용하기 때문에 에러가 출력되었습니다.

이런 경우에는 -f 옵션을 추가하여 강제로 삭제할 수는 있지만, 이것은 이미지 레이어 파일을 실제로 삭제하지는 않으며, 이미지의 이름만 삭제하게 되어 의미가 없습니다. 따라서, 컨테이너를 삭제한 후에 이미지를 삭제하도록 해야합니다.(실행 중이라면 중지한 후)

1. docker stop commit_test2 && docker rm commit_test2
2. docker rmi commit_test:first

위에서 commit_test:first 이미지를 삭제했지만, 실제로 해당 이미지의 레이어 파일이 삭제되지는 않습니다. 이는 commit_test:first 이미지를 베이스로하는 하위 이미지인 commit_test:second가 아직 존재하기 때문입니다.

따라서 위의 경우에는 실제 이미지 파일을 삭제하지 않고, 레이어에 부여된 이름만 삭제하게 됩니다.

이미지를 삭제했을 때 출력된 Untagged:... 이 바로 이미지에 부여된 이름만 삭제한다는 것을 의미합니다.

이번에는 commit_test:second 이미지를 삭제해보겠습니다.

docker rmi commit_test:second

Deleted: 라는 출력 결과는 이미지 레이어가 실제로 삭제됬음을 뜻합니다.

출력 내용을 분석해보면, 출력 내용은 commit_test:second를 가리키는 ID와 실제 레이어를 가리키는 ID가 삭제된 것을 의미합니다. (commit_test:first 관련 레이어 ID 정보도 삭제되었습니다.)

여기서 삭제된 ID는 실제 레이어 파일을 가리키는 ID이며, 이 ID에 의해서 실제 레이어 파일이 참조됩니다.

그리고 commit_test:second 이미지를 삭제했다고해서 ubuntu:20.04 이미지도 함께 삭제되는 것은 아닙니다.

방금 위에서 second, first 파일이 존재하는 레이어만 삭제되었는데, commit_test:first 이미지 태그는 이미 삭제되어 존재하지 않지만, 우분투 이미지를 가리키는 ubuntu:20.04 이미지 태그는 아직 존재하기 때문입니다. 따라서 ubuntu:20.04 이미지의 레이어 파일들은 commit_test:second 이미지를 삭제할 때 함께 삭제되는 레이어 범위에 포함되지 않습니다.

3. 이미지 추출


도커 이미지를 별도로 저장하거나 옮기는 등 필요에 따라 이미지를 단일 바이너리 파일로 저장해야 할 때, docker save 명령어를 통해서 컨테이너의 커맨드, 이미지 이름, 태그 등 이미지의 모든 메타데이터를 포함해 하나의 파일로 추출할 수 있습니다.

-o 옵션에는 추출될 파일명을 입력합니다. 추출된 파일은 현재 터미널 위치에 저장됩니다.

docker save -o ubuntu_20.04.tar ubuntu:20.04

이렇게 추출된 이미지는 load 명령어로 도커에 다시 로드할 수 있습니다. save 커맨드로 추출된 이미지는 이미지의 모든 메타데이터를 포함하기 때문에 load 커맨드로 이미지를 로드하면 이전의 이미지와 완전히 동일한 이미지가 도커 엔진에 생성됩니다.

docker load -i ubuntu_20.04.tar

save, load 명령어와 유사하게 사용할 수 있는 명령어로 export, import가 있습니다.

docker commit을 통해 컨테이너를 이미지로 만들게되면, 컨테이너에서 변경된 사항과 컨테이너가 생성될 때 설정된 옵션들도 모두 이미지에 저장됩니다. 그러나 export 명령어는 컨테이너의 파일시스템을 tar 파일로 추출하며 컨테이너 및 이미지에 대한 설정 정보를 저장하지 않습니다.

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

위 예시는 export 명령어로 mycontainer라는 컨테이너의 파일시스템을 rootFS.tar 파일로 추출하고, import 명령어로 myimage:0.0이라는 이미지로 다시 저장합니다.

그러나 이미지를 단일 파일로 저장하는 것은 비효율적이며, 레이어 구조가 아니기 때문에 여러 버전의 이미지를 추출하면 이미지 용량을 각각 차지하게 됩니다.

4. 이미지 배포


이미지를 단일 파일로 추출해서 배포할 수도 있지만, 이미지 파일의 크기가 너무 크거나 도커 엔진의 수가 많다면 이미지를 파일로 배포하기 힘듭니다. 또한 도커의 이미지 구조인 레이어 형태를 이용하지 않으므로 비효율적입니다.

이런 경우에 도커에서 공식적으로 제공하는 도커 허브 이미지 저장소를 사용하거나(비공개 저장소도 있음), 도커 사설 레지스트리(Docker Private Registry)를 사용할 수도 있습니다.

Private Registry는 사용자가 직접 이미지 저장소 및 사용되는 서버, 저장 공간 등을 관리해야 하므로 도커허브보다는 사용법이 까다롭습니다. (회사 내부망과 같은 곳에서 도커 이미지를 배포한다면, 좋은 방법이 될 수 있습니다.)

4.1. Docker Hub

도커 허브 사이트에서 docker search를 통해 검색했을 때와 같이 이미지를 검색할 수 있습니다.

우분투처럼 많이 사용되는 이미지는 x86, ARM 등 여러 CPU 아키텍처에 알맞는 이미지를 제공하고 있습니다.

docker inspect 명령어를 사용하면 해당 이미지가 어느 CPU 아키텍처에서 사용되도록 설정됬는지
알 수 있습니다.
docker inspect ubuntu | grep Architecture
docker pull과 같은 명령어를 사용하면 자동으로 호스트의 CPU 아키텍처에 해당하는 이미지를 내려> 받기 때문에 신경쓸 필요는 없습니다.

도커 허브는 깃헙(github)과 유사하게 사용하면 됩니다.

테스트를 위해서 practice 저상소를 생성하여 사용해보겠습니다. 회원가입을 할 때 입력한 이름이 저장소 이름이 되고, 생성한 repository가 저장소에 저장될 이미지의 이름입니다.

저장소에 이미지 올리기

방금 생성한 practice에 이미지를 올려보도록 하겠습니다.

먼저 컨테이너를 생성하고, test 파일을 생성한 뒤에 이미지를 생성합니다.

1. docker run -i -t --name commit_container1 ubuntu:20.04
2. echo my first push >> test
3. exit
4. docker commit commit_container1 practice:first_push

위 명령어를 통해 test 파일을 생성해 변경사항을 만들고, practice:first_push라는 이미지로 커밋했습니다. 그러나 이와 같은 이름으로 이미지를 저장소에 올릴 수는 없습니다.

특정 이름의 저장소에 이미지를 올리려면 저장소 이름(계정 이름)을 이미지 앞에 접두어로 추가해야합니다.

아래 명령어로 practice:first_push 이미지에 userID/practice:first_push 라는 이름을 추가합니다.

docker tag practice:first_push changjunlee/practice:first_push

tag 명령어로 이미지의 이름을 변경했다고 기존의 이름이 사라지는 것은 아니며, 같은 이미지를 가리
키는 새로운 이름이 추가될 뿐입니다.

이미지의 이름을 추가하고, 다음 명령어를 입력해 Docker Hub 서버에 로그인하도록 합니다.

docker login

도커 엔진에서 로그인한 정보는 /[계정명]/.docker/config.json 파일에 저장됩니다. 로그인 정보를 삭제하고 싶다면 docker logout 명령어를 입력하면 됩니다.

로그인 후에 push 명령어를 입력해 이미지를 저장소에 올릴 수 있습니다.

docker push changjunlee/practice:first_push

출력 내용을 살펴보면 하나의 레이어만 저장소에 push되고, 나머지 레이어는 허브의 우분투 이미지 저장소(ubuntu:20.04)에 이미 존재하므로 push 되지 않습니다.

도커 허브 사이트에서 실제로 이미지가 올라온 것을 확인할 수있습니다.

도커에서 이 이미지를 내려받으려면 별도의 로그인은 필요없으며, 다음 명령어를 입력하면 됩니다.

docker pull changjunlee/practice:first_push

4.2. Docker Private Registry

Private Registry는 다음 글에서 따로 진행하도록 하겠습니다.

profile
Data Engineer

0개의 댓글