도커 허브 등 레지스트리에 이미지 공유하기
레지스트리, 리포지토리, 태그 등 레지스트리에 이미지 공유를 위한 내용을 알아봅시다 (참고: ‘도커 교과서’책)
레지스트리, 리포지토리, 이미지 태그 다루기
- 도커의 소프트웨어 배포 기능
이미지가 로컬 컴퓨터에 없으면 자동으로 이미지를 내려받아줌.
이 이미지는 도커 레지스트리라고 불리는 서버에 저장되는데, 도커 허브는 도커 레지스트리중 가장 유명한 레지스트리이자 도커엔진에 기본적으로 설정된 레지스트리. - 도커 이미지에는 이름이 부여됨.
이미지 전체 이름(이미지 참조)는 4개의 요소로 구성됨.
이미지가 저장된 도메인/이미지 작성자의 계정이름/이미지 리포지토리 이름/이미지 태그
이미지 참조가 레지스트리에서 특정한 이미지를 식별하는 식별자 역할을 한다.
- 이미지가 저장된 도메인
위에서 말했듯 이미지가 저장된 도메인, 즉 레지스트리의 기본값은 도커허브이다. 만약 다른 도메인에 나의 전용 레지스트리를만들고 이부분을 변경하면 그 도메인으로 가서 이미지 참조를 실행할 것이다. - 이미지 작성자의 계정이름
이 부분엔 도커 허브의 단체 계정 이름 혹은 개인 계정 이름이 들어간다. 공개 레포지토리라면 누구나 이미지를 받을 수 있지만 푸시권한은 개인, 혹은 단체의 소속원에 있다. - 이미지 태그
태그는 같은 애플리케이션의 서로 다른 버전을 구별하기 위해 사용된다. OpenJDK의 공식 도커 이미지에도 수백 개에 달하는 태그가 있다. 이미지를 빌드할 때 태그를 따로 지정하지 않으면 기본적으로 latest 태그가 부여된다. 알아보기 쉽기 위해 레지스트리에 이미지를 푸시할때 항상 명시적으로 태그를 부여하자.
도커 허브에 직접 빌드한 이미지 푸시하기.
(도커 허브 계정이 필요합니다.)
레지스트리에 이미지를 푸시하려면 두 가지 절차가 필요하다.
- 도커 명령행을 통해 레지스트리에 로그인(로그인을 해야 이미지를 푸시할 권한이 부여됨)
- 이미지에 푸시 권한을 가진 계정명을 포함함하는 이미지 참조를 붙여야된다.
각자 도커 허브 계정이 다르므로 혼동을 방지하기 위해 도커 허브 계정을 터미널에서 환경변수로 정의하자.
# 윈도우 환경의 파워셸
$dockerId="도커허브계정이름"
# 리눅스 또는 macOS 환경의 배시 셀
export dockerId="도커허브계정이름"
(주의 :도커허브계정이름은 이메일주소 형식이 아님)
이후 환경변수가 제대로 정의되었는지 확인하려면 echo $dockerId를 입력해 자신의 계정이름이 출력되는지 확인하면 된다.
먼저 도커 허브에 로그인하자. 아래 명령어를 입력하여 명령행에서 로그인할 수 있다.
(winpty)docker login --username $dockerId
나는 이미 image-gallery라는 이미지가 있다. 그러나 이 이미지 참조에는 계정 이름이 지정돼있지 않기 때문에 지금 상태로는 이 이미지를 레지스트리에 푸시할 수 없다. 그러나 이미지 참조를 새로 부여하기 위해 이미지를 다시 빌드할 필요는 없다. 이미지는 여러개의 참조를 가질 수 있다.
일단 이미지 참조를 부여해보자.
docker image tag image-gallery $dockerId/image-gallery:v1
이후 image-gallery 이미지의 이미지 참조 목록을 확인해보자
docker image ls --filter reference=image-gallery --filter reference ='*/image-gallery'
명령에서 지정된 필터와 일치하는 이미지 참조 두 개의 출력을 확인할 수 있다.
또한 용량이 둘다 27.1MB로 같게나오지만 두 이미지 참조 의 논리적 용량일 뿐이다. 물리적으로는 같은 레이어를 공유한다.
자. 위에 이미지 참조까지 생성하였으면 이미지를 공유할 준비가 모두 끝났다. pull명령과 반대되는 기능을 가진 명령인 docker image push 명령을 사용해 로컬 컴퓨터에 저장된 이미지 레이어를 레지스트리로 푸시해보자.
docker image push $dockerId/image-gallery:v1
도커 레지스트리도 로컬 컴퓨터에서 동작하는 도커엔진과 같은 방식으로 이미지를 다룬다. 이미지를 푸시할때 실제로 업로드 대상이 되는것은 이미지 레이어다. 출력되는 내용을 보면 일련의 레이어 식별자와 해당 레이어의 업로드 진행 상황이 표시된다.

레지스트리 역시 도커 엔진과 같은 방식으로 이미지 레이어를 다루면 그만큼 Dockerfile 스크립트의 최적화가 더욱 중요해진다. 레지스트리에서도 캐시상에 레이어 해시와 일치하는 레이어가 없을 경우에만 실제로 업로드가 이루어진다. 도커엔진의 레이어 캐시와 완전히 같은 방식이지만, 레지스트리상의 전체 이미지를 대상으로 한다는점이 다르다. 레이어의 90%가 기존 캐시를 재사용할 수 있도록 이미지를 최적화했다면, 이 이미지를 푸시할 때 90%의 레이어는 레지스트리의 캐시를 재사용할 수 있다. 이렇듯 최적화된 Dockerfile 스크립트는 빌드 시간, 디스크 용량을 넘어 네트워크 대역폭까지 영향을 미치는 중요한 요소다.
이제 도커허브에서 새로 푸시된 이미지를 확인해 보자.
echo "https://hub.docker.com/r/$dockerId/image-gallery/tags"
출력된 URL을 웹브라우저로 접근해보면 잘 올라가있는것을 확인할 수 있다.
이제 올라가 있는 애플리케이션을 누구나 검색하고 내려받고 실행할 수 있다. 다른사람들이 애플리케이션의 사용법까지 알려면 조금 공부가 필요하겠지만, 이 사용법 역시 문서를 통해 도커 허브에서 제공할 수 있다.
나만의 도커 레지스트리 운영하기
로컬 네트워크에 전용 레지스트리가 있으면 편리한 점이 많다.
- 인터넷 회선 사용량을 줄여 주며 전송시간도 절약된다.
- 데이터를 다른사람의 손에 맡기지 않아도 된다.
- 공개 레지스트리가 다운됐을 때 신속하게 전환할 수 있다.
도커 코어 레지스트리 서버는 깃허브 저장소 docker/distribution에서 개발이 진행된다. 코어 레지스트리 서버는 도커 허브와 동일한 레이어 캐시 시스템을 통해 이미지를 내려받고 푸시하는 기본적인 기능을 제공한다. 그러나 도커 허브에서 볼 수 있는 웹 기반 UI 등의 기능은 빠져있다. 코어 레지스트리 서버는 매우 가볍게 동작하는 서버로, 내가 별도로 diamol 계정에 패키징한 이미즈를 사용해 컨테이너 형태로 직접 실행할 수 있다.
내가 패키징한 이미지를 사용해 컨테이너 형태로 도커 레지스트리를 실행해보자.
docker container run -d -p 5000:5000 --restart always diamol/registry
이 명령으로 실행되는 레지스트리 서버의 기본 포트는 5000이다. 이 레지스트리의 도메인 localhost:5000을 사용해 이미지에 태그를 부여할 수 있다. 그러나 이 레지스트리는 로컬 컴퓨터에서만 접근할 수 있기 때문에 크게 유용하진 않다. 그러나 로컬 컴퓨터에 제대로 된 도메인 네임을 붙인다면 더 활용도가 높아질 것이다.
도메인 네임을 별명으로 붙여보자. 로컬컴퓨터에 registry.local이라는 별명을 추가한다. 별명을 추가하려면 도메인과 IP주소의 연결을 기록한 작은 텍스트 파일인 hosts 파일에 새로운 도메인-주소 쌍을 추가하면 된다.
# 윈도우 환경의 파워셸
Add-Content -Value "127.0.0.1 registry.local" -Path /windows/system32/drivers/etc/hosts
# 리눅스 또는 macOS 환경의 배시 셸
echo $'\n127.0.0.1 registry.local' | tee -a /etc/hosts
명령이 잘 수행되었으면 ping registry.local 명령을 입력해 IP 127.0.0.1이 응답하는지 확인해보자.