임대일

3.2 도커(Docker) 이미지와 레지스트리: 이미지 레지스트리 실습 본문

도커/개발자를 위한 쉬운 도커

3.2 도커(Docker) 이미지와 레지스트리: 이미지 레지스트리 실습

limdae94 2024. 6. 28. 16:52
 

개발자를 위한 쉬운 도커 강의 | 데브위키 - 인프런

데브위키 | 현업 개발자가 도커를 사용한 경험을 녹여낸 새로운 커리큘럼으로 기존 교재 및 강의와 차별된 강의를 제공합니다. 단순한 명령어 사용법이 아닌 도커를 왜 사용해야하는지 대한 근

www.inflearn.com

 

1. hub.docker.com

hub.docker.com에 직접 가입하고 이미지를 다운로드하고 업로드한다. docker에서 지원하는 공식 이미지를 확인할 수 있고, 다양한 사용자들이 공유하는 이미지를 볼 수 있다.

docker hub

 

docker에서 공식적으로 지원하는 이미지는 DOCKER OFFICIAL IMAGE 태그가 포함되어 있다. 검색창에 nginx를 검색하면 nginx라는 이미지로 여러 개의 이미지 목록을 조회할 수 있다. 그 중에 맨 위에 뜨는 것이 라이브러리 프로젝트에서 제공하는 도커 오피셜 nginx이다. 우리가 지금까지 실습에서 사용했던 nginx가 바로 이 nginx 이미지이다.

docker hub 에서 nginx 검색하기

 

 

그리고 조금 밑으로 내려 보면 DOCKER OFFICIAL IMAGE 말고도 VERIFIED PUBLISHER라는 태그가 붙은 이미지들이 있다. 이 이미지는 도커에서 직접 관리하는 이미지는 아니지만, 어느 정도 규모가 있는 회사에서 자체적으로 인증한 이미지이기 때문에 다른 이미지보다 더 신뢰할 수 있다고 볼 수 있다.

VERIFIED PUBLISHER

 

아래 그림을 살펴보면 Official Nginx를 클릭하여 이렇게 상세 페이지에서 다운로드 수와 좋아요 수도 확인할 수 있다.

nginx Overview 상세 정보

 

 

태그 탭을 클릭해 보면 Nginx 이미지의 버전 정보도 확인할 수 있다.

nginx Tags

 

태그 탭에서 스테이블이 붙어 있는 이미지들은 안정적인 버전이라고 생각하면 된다. alpine이 포함되어 있는 부분은 nginx 이미지를 만들기 위해서 베이스 이미지로 사용했던 OS의 버전을 의미한다. 각각의 이미지 버전에 해당하는 파일 크기도 확인할 수 있다. 이 끝에 slim이라고 이름이 붙은 이미지는 크기가 5MB 밖에 안된다. 이런 이미지들은 보통 프로그램 실행에 정말 필요한 것들만 남겨놓고 나머지 부분들은 모두 제거한 이미지이다. 그래서 디버깅이 쉽지 않을 수도 있고 실제로 사용하기에는 조금 불편할 수도 있다.

 

대신 이미지의 크기가 작기 때문에 이미지를 전송할 때 들어가는 시간을 크게 단축시킬 수 있다. 이제 홈페이지에서 최상단에 레파지토리스를 클릭해 보자.

 

도커 허브는 기본적으로는 무료로 사용할 수 있다. 특정 IP에서 6시간에 100번, 로그인한 사용자는 6시간에 200번 다운로드가 가능하다. 그리고 하나의 계정당 하루에 5,000번의 다운로드 제한이 있다. 개인 용도로 사용하기에는 크게 무리가 없다. 하지만 엔터프라이즈 환경에서는 기업용 라이선스로 구매해서 사용하시거나 설치형 레지스트리를 활용하는 방법도 있다. 이제 여러분의 도커 허브 계정으로 이미지를 직접 업로드해 보자.

 

 

2. pull, tag, push

먼저 이미지를 다운로드 받을 때는 docker pull 뒤에 다운로드 받을 이미지의 이름을 입력하면 된다. 여기에 들어가는 이미지의 이름은 이전 시간에 배웠던 이미지의 네이밍 규칙에 따라서 작성해주면 된다. 다음으로 docker tag 명령어는 새로운 이미지명을 만드는 명령어이다. 새로운 이미지명을 만들기 위해서는 새로운 이름을 붙일 원래의 이미지가 있어야 한다. 그래서 docker tag 명령에는 기존에 가지고 있는 이미지명과 새롭게 추가할 이미지명을 입력한다. 원래 있던 이미지는 그대로 둔 상태에서 제가 원하는 이미지명으로 새로운 이름을 하나 만든다고 생각하면 된다. 그리고 마지막으로 docker push 명령 뒤에 이미지의 이름을 입력하면 이미지를 업로드할 수 있다.

pull, tag, push

  • docker pull 이미지명: 로컬 스토리지로 이미지 다운로드
  • docker tag 기존이미지명 추가할이미지명: 로컬스토리지의 이미지명 추가
  • docker push 이미지명: 이미지 레지스트리에 이미지 업로드

 

이번 실습에서는 devwikirepo 프로젝트의 이미지를 다운받아서 해당 이미지를 기반으로 새로운 이미지명을 만든 다음에 이미지를 push해 볼 것이다. 이미지명을 바꾸는 이유는 프로젝트의 이름을 바꾸기 위해서이다. Docker Hub에서는 프로젝트의 이름이 도커 사용자의 계정명이라고 언급했다. 다운받을 이미지는 지식공유자의 레파지토리에서 다운받아서 실습용 계정명이 적혀있기 때문에 이 이미지를 그대로 푸시하면 실습용 계정으로 push가 될 것이다. 그래서 지식공유자의 이미지를 베이스로 해서 사용자의 프로젝트명을 포함해서 새로운 이미지의 이름을 추가한 다음에 그 이미지명으로 이미지를 push해야 사용자의 레지스트리로 이미지가 push되는 것이다. 그럼 이제 터미널을 열어보자. 실습용 이미지를 다운받는다.

도커 허브에서 이미지 태크에 따른 흐름

 

docker, pull, devwikirepo의 simple-web 1.0 버전을 다운받는다.이미지가 정상적으로 다운로드 된다. 이번에는 docker tag 명령을 통해서 다운받은 이미지의 이름을 변경한다.

 

원래 이미지 이름은 방금 다운받은 이미지인 devwikirepo의 simple-web 1.0으로 지정한다. 여기서 한 칸을 띄운 다음에 여러분의 레지스트리 계정명을 입력하고 그리고 이미지 이름은 my-simple-web, 버전은 0.1로 지정하겠다.

docker tag devwikirepo/somple-web:1.0
레지스트리명/my-simple-web:0.1

 

 

나는 easydocker123으로 지정했다. 엔터를 입력하고 docker image ls 명령으로 확인해 보면 이렇게 두 개의 심플 웹 이미지를 확인할 수 있다.

 

devwikirepo/simple/web은 온라인에서 다운로드 받은 버전이다. easydocker123my-simple-web은 다운로드 받은 이미지에 이름만 바꾼 버전이다. 이름만 바꿨기 때문에 이미지의 아이디가 똑같은 것을 확인할 수 있다. 하나의 이미지에 여러 개의 이름을 추가할 수 있는 것이다. 이렇게 이름을 추가하는 이유는 같은 파일이더라도 이름을 어떻게 주는지에 따라서 어디에 푸시되는지가 결정되기 때문이다. 파일은 그대로 있고, 이미지명에 따라서 업로드하는 곳이 달라지게 되는 것이다. 그래서 사용자의 이미지를 도커 허브의 여러분의 계정으로 푸시하기 위해서 docker tag 명령을 사용해서 새로운 이미지명을 추가한 것이다. 이렇게 이미지를 원하는 곳에 업로드하고 싶은 경우에는 이미지의 네이밍 규칙을 활용해서 업로드할 곳의 이미지명으로 변경해야 한다. my-simple-web 이미지명을 레지스트리명과 프로젝트명을 어떻게 수정하냐에 따라서 다양한 곳에 다양한 버전으로 배포할 수 있는 것이다. 이번 실습 같은 경우는 Docker Hub의 devwikireposimple-web:1.0 버전을 다운받아서 똑같은 레지스트리인 Docker Hub에 각각의 프로젝트에 my-simpl-Web0.1 버전으로 업로드하는 것이다. 그러면 이제 docker push 명령과 새롭게 추가한 이미지명을 사용해서 이미지를 업로드해 보자.

 

docker push의 레지스트리 계정명에 my-simple-web:0.1 버전을 지정하자. 이렇게 엔터를 치면 push가 시작되다가 인증 관련 에러가 나면서 종료되는 것을 확인할 수 있다.

 

왜냐하면 Docker Hub에 로그인이 되어 있지 않기 때문이다. 웹페이지에는 로그인이 되어 있지만 지금 명령어를 입력하는 터미널에서는 Docker Hub에 계정 정보가 없기 때문이다. Docker Hub에서는 이미지를 다운받을 때는 권한이 없어도 된다. Docker Hub의 이미지를 push할 때는 업로드할 계정의 인증 정보가 필요하다. 아무나 자신의 레지스트리에 이미지를 push할 수 있으면 안 되기 때문이다.

 

3. login, logut, image rm

그럼 다음으로 도커 허브의 계정에 로그인하기 위한 명령어를 확인해 보자. Docker Hub 에는 docker login 명령으로 로그인할 수 있다. 도커 로그인 명령으로 로그인하면 스토리지의 특정 공간에 인증 정보가 생성된다. 그리고 docker logout을 입력하면 이 인증 정보가 저장되어 있는 파일이 삭제된다. 그리고 로컬 스토리지에서 이미지를 삭제하면 docker image rm 뒤에 이미지의 이름을 지정해 주면 된다.

login, logout, image rm

 

  • docker login: 이미지 레지스트리 인증 정보 생성
  • docker logout: 이미지 레지스트리 인증 정보 삭제
  • docker image rm 이미지명: 로컬 스토리지의 이미지 삭제

그럼 터미널로 돌아와서 docker login 명령을 사용해 보자. 먼저 docker login을 입력하자. 유저 네임 부분에 사용자의 계정명을 입력한다. 지식공유자 같은 경우는 eazydocker123 을 입력한다. 그리고 비밀번호를 입력하면 정상적으로 로그인이 된 것을 확인할 수 있다. 인증 정보가 저장되는 곳은 OS마다 조금 다를 수 있다. .docker 폴더에 config.json 파일로 저장이 된다. 굳이 꼭 확인을 하진 않아도 된다.

cat ./docker/config.json # mac, linux 만 확인이 가능합니다.

 

그냥 이렇게 인증 정보가 파일 형태로 저장되는 것만 알아두면 된다. 이제 docker push 명령을 사용해서 이전에 실패했던 이미지를 다시 push하자.

cat ./docker/config.json: 인증 정보 경로(Mac, Linux만 확인 가능)

이제 정상적으로 이미지가 푸시가 되는 것을 확인할 수 있다.

docker push 레지스트리계정명/my-simple-web:0.1

 

이렇게 실행 로그 쪽에는 "https://index.docker.io/v1": {}라는 주소까지 모두 포함이 되어 있는 것을 확인할 수 있다. push된 이미지를 Docker Hub에서 확인해 보자. 새로고침해서 보면 이미지가 정상적으로 push된 것을 확인할 수 있다.

 

지금은 방금 push했고 아무도 다운로드 받지 않았기 때문에 다운로드가 0건일 것이다. 그리고 이미지는 누구나 다운로드 받을 수 있도록 퍼블릭 상태인 것을 확인할 수 있다. 그럼 이 레지스트리의 이미지를 다운 받아서 실제로 컨테이너를 만들어 보자.

 

그런데 여기서 docker run 명령으로 이미지의 이름을 지정하면 이미 로컬 스토리지 안에 같은 이미지가 있기 때문에 온라인에서 이미지를 다운로드 받지 않는다. 그래서 로컬 스토리지에 있는 이미지를 먼저 삭제하고 테스트해 보자. docker, image, rm 사용자의 레지스트리 계정에 my-simple-web0.1 버전을 사용해서 사용자의 로컬 스토리지에 있는 이미지를 삭제하자.

docker image rm 레지스트리명/my-simeple-web:0.1 # 로컬 스트뢰지의 이미지 삭제

 

마찬가지로 docker, image, rm 명령을 사용해서 devwikireposimple-web1.0 버전도 삭제하자.

docker image rm devwikirepo/simple-web:1.0 # 로컬 스토리지의 이미지 삭제

 

잘 보면 첫 번째 삭제에서는 Untagged로만 나온다. 두 번째 삭제에서는 untagged와 동시에 deleted까지 되는 것을 확인할 수 있다. 하나의 이미지를 다운받아서 tag 명령을 사용해서 새로운 이미지명을 추가했기 때문에 하나의 이미지로 두 개의 image tag가 있는 상태였다. 그래서 이미지 태그를 하나만 삭제할 때는 이 이미지를 참조하고 있는 다른 이미지명이 있기 때문에 Untagged가 되고 삭제는 되지 않았지만, 두 번째로 이미지를 삭제할 때는 더 이상 이 이미지를 참조하고 있는 이미지명이 없기 때문에 아예 파일 자체가 삭제되어 버리는 것이다. 이렇게 이미지와 이미지명의 관계는 실제 파일과 참조 링크처럼 생각하면 된다. 물리적인 파일에 여러 개의 링크 형태로 이미지에 이름을 붙일 수 있고, 더 이상 참조하는 이미지명이 없을 경우에 물리적인 파일도 삭제되는 것다.

 

이제 docker image ls 명령을 사용해 보면 my-simple-web 관련 이미지가 로컬 스토리지에서는 모두 제거된 것을 확인할 수 있다.

 

이제 사용자의 허브에 있는 이미지를 사용해서 컨테이너를 실행해 보자. docker run –d –p 80:80 을 지정한다. 이미지의 이름은 레지스트리 계정명에 my-simple-web 0.1 버전을 지정했다.

docker run -d -p80:80 --name my-simple-web
레지스트리계정명/my-simple-web:0.1 # 실습 컨테이너 실행

 

명령을 실행하면 이제 로컬에 이미지가 없기 때문에 이미지를 다시 다운로드 받는 것을 확인할 수 있다.

 

정상적으로 컨테이너가 실행했다. 이제 탭을 열어주고, 로컬호스트로 접속해 보자. 이렇게 Hello NGINX 페이지를 제공하는 NGINX의 응답을 확인할 수 있다. 그리고 Docker Hub 의 레지스트리를 다시 확인해 보면 다운로드 수가 1 증가한 것을 확인할 수 있다.

 

그럼 실습에 사용한 컨테이너를 삭제하고 실습을 마친다. docker-rm-fmy-simple-web으로 컨테이너를 삭제해준다.

docker rm -f my-simple-web

 

이제 이 이미지의 이름을 여러분의 동료나 친구에게 전달해 주면 어떤 환경에서든 도커만 설치되어 있으면 완벽하게 일치하는 서버를 구성하실 수 있다.

 

도커를 사용하기 전에는 이미지가 아닌 소스 코드나 애플리케이션을 파일로 공유했다. 실제로 애플리케이션을 실행할 때 이 OS나 라이브러리가 PC별로 차이가 있기 때문에 개발자의 개발용 PC에서는 잘 실행되던 애플리케이션도 운영 환경이나 다른 PC에서는 제대로 동작하지 않는 문제가 빈번하게 발생하고 있다. 그래서 운영 환경을 테스트할 수 있는 QA 환경을 만들고 운영 환경과 완벽하게 일치시키는데 많은 노력을 기울이게 된다. 그럼에도 불구하고 이러한 환경의 불일치로 인해서 많은 문제들이 발생하고 있다. 컨테이너를 사용하면 이렇게 환경의 차이에서 나오는 문제들을 근본적으로 해결할 수 있다. 간단한 웹서버부터 복잡한 애플리케이션 서버 구성까지 이미지에 실행 가능한 형태로 저장해서 공유하면 서버를 운영하는 비용을 줄이고 새로운 서버를 구성하는 시간을 크게 단축시킬 수 있다.

 

이번 파트에서는 이미지를 저장하고 공유하는 공간인 레지스트리에 대해서 배웠다. 그리고 이미지의 네이밍 룰에 대해서도 학습했다. 그리고 도커 허브 계정을 직접 만들어 보고 이 계정의 이미지를 푸시해 보았다. 이번 파트에서는 이미지를 외부에서 다운받아서 실습을 했다. 다음 파트에서는 이제 본격적으로 도커의 핵심 기술인 이미지를 작성하는 방법에 대해서 배우게 된다.