이미지 레지스트리는 도커 이미지를 저장하기 위한 저장소이다. 이미지 레지스트리를 통해 개인이나 팀 이미지를 다른 사람과 공유하거나 필요한 이미지를 다운받을 수 있다.
(마치 Github에서 자신의 소스 코드를 보관하고 쉽게 다른 개발자들과 공유할 수 있는 것처럼 이미지 레지스트리도 매우 비슷하다.)
가장 많이 사용되는 Public Image Registry는 DockerHub가 있다.
Github엔 소스코드만 보관하고, Dockerhub엔 이 소스 코드를 사용해서 만들어진 애플리케이션과 그 애플리케이션을 실행할 수 있는 환경이 모두 포함되어 있는 이미지를 저장한다.
이미지가 저장되는 공간은 크게 세가지로 나눌 수 있다.
먼저, 도커가 설치되어 있는 호스트 머신의 Local Storage가 있고, 온라인 저장소엔 Private Registry, Public Registry로 크게 두가지로 총 3가지이다.
컨테이너를 실행할 때 이미지의 이름을 입력했는데, docker run 명령어에서 이미지의 이름을 지정하면 먼저 로컬 스토리지에서 해당 이미지가 있는지 검색한다.
로컬 스토리지는 도커를 실행하는 호스트 OS의 특정 폴더를 의미한다. (실습 환경에선 내 PC에 특정 폴더를 의미한다.) 그래서 이 로컬 스토리지에 이미지가 있으면 바로 실행된다. 없을 경우 호스트 외부의 온라인 레지스트리에서 이미지를 로컬 스토리지로 다운 받는다. 그리고 다운 받은 로컬 스토리지의 이미지를 사용해서 컨테이너를 실행한다.
한 번 다운 받아 온 경우 로컬 스토리지에 이미 다운로드 받아놓은 이미지가 있기 때문에 온라인 레지스트리를 검색하지 않고 바로 컨테이너로 실행된다.
온라인 저장소는 기업에서 많이 사용하는 Private Registry와 Dockerhub 같은 Public Registry로 두 종류가 있다. 특정한 네트워크에만 접근이 가능하면 Private Registry, 모든 네트워크에서 접근이 가능하면 Public Registry이다.
도커 허브와 같은 Public Registry는 모두가 접근할 수 있는 레지스트리이기 때문에 이런 공간에 이미지를 저장하는 것은 보안상 문제가 될 수 있다. 그래서 도커 허브 같은 서비스를 사용하지 않고, 본인만의 레지스트리를 사용하는 방법도 있다.
서버에 설치하는 레지스트리 소프트웨어는 Harbor, Docker Private Registry같은 제품이 있으며, Public Cloud의 서비스로는 AWS ECR, Azure ACR 같은 서비스를 사용할 수 있다.
설치형 레지스트리는 사용자가 직접 레지스트리를 서버에 설치해야 하며, 퍼블릭 클라우드의 레지스트리를 사용하면 시간당 사용 요금을 지불하고 레지스트리를 사용할 수 있다.
이미지의 네이밍 규칙은 이미지를 만들고 공유하는 데 있어서 꼭 필요한 정보이다.
이미지 이름에는 이미지를 어디서 다운 받는지, 어떤 버전을 다운 받는지에 대한 정보가 모두 포함되어 있어야 한다.
이미지 이름은 크게 레지스트리 주소, 프로젝트명, 이미지명, 이미지 태그로 구성된다.
레지스트리 주소는 어떤 레지스트리를 사용할 지 지정한다. 도커 허브 말고도 레지스트리가 다양하기 때문에 이미지를 어떤 레지스트리에서 다운로드하고 업로드 할 지를 지정해준다. 비어있을 경우, 기본 값으로 지정된 레지스트리 주소가 사용된다. 도커를 사용하면 기본 레지스토리 값은 도커 허브의 주소인 docker.io가 default 값이다. 만약 개인 레지스트리 주소가 devwiki.com이고, 이 레지스트리에서 이미지를 다운 받거나 업로드하고 싶으면 맨 앞에 devwiki.com라는 레지스트리 주소를 적어야 한다.
프로젝트명은 이미지를 보관하는 폴더 같은 개념이다. 레지스트리마다 프로젝트를 정의하는 방식이 조금 다르기도 하다. 도커 허브의 경우 가입한 사용자의 계정명이 프로젝트 명이 된다. (도커는 도커사가 직접 검증한 이미지는 오피셜 이미지로 제공하고 있다. 이 오피셜 이미지를 library 라는 프로젝트에서 관리하기 때문에 별도로 계정명을 입력하지 않을 경우 library가 기본 값으로 적용된다.)
이미지명은 다운로드 받을 이미지의 이름이다. 이미지 태그는 이미지의 버전이며, 숫자와 영문을 모두 사용할 수 있다. 기본 값은 lastest이므로, 이미지 태그를 생략할 경우 lastest로 가장 최근 버전이 사용된다.
hub.docker.com 에서 가입 할 때 Username이 프로젝트명이 된다. (구글 회원가입하니까 알아서 자동으로 이름이 입력됐다.)
nginx를 검색해보면 맨 위에 뜨는 것이 library 프로젝트에서 제공하는 도커 오피셜 nginx이다. 그리고 오피셜 이미지 말고 Verified Publisher 라는 태그가 붙은 이미지들이 있다. 이 이미지들은 도커에서 직접 관리하는 이미지는 아니지만 어느정도 규모가 있는 회사에서 자체적으로 인증한 이미지여서 다른 이미지보다는 신뢰할 수 있다.
하나의 이미지를 클릭하면 상세페이지에서 다운로드 수, 좋아요 수를 확인할 수 있다.
Tags 탭을 클릭하면 이미지의 버전 정보도 확인할 수 있는데 nginx의 경우 stable이 붙어있는 이미지들은 안정적인 버전이라고 생각하면 된다. 추가로 alpine 부분은 nginx 이미지를 만들기 위해서 베이스 이미지로 사용했던 OS의 버전을 확인할 수 있다.
상단의 Repositories가 나의 이미지 저장소라 생각하면 된다. 이미지를 푸시하면 이 곳에 저장된다.
다음은 관련된 명령어이다.
docker pull 이미지명
docker tag 기존이미지명 추가할이미지명
docker push 이미지명
기존 devwikirepo 프로젝트의 이미지를 다운 받아 이 이미지를 기반으로 새로운 이미지명을 만든 다음에 이미지를 푸시하는 실습이다. (여기서 이미지명을 바꾸는 이유는 프로젝트의 이름을 바꾸기 위해서 라고 한다. 여기서 본인의 프로젝트명(도커의 계정)으로 변경해서 본인의 레지스트리에 올라간다.)
simple-web은 이름만 my-simple-web으로 변경된 것이기에 IMAGE ID가 같은 것을 확인할 수 있다. 이미지의 아이디가 같다는 것은 실제로 파일이 하나만 있다는 것을 의미한다. 하나의 이미지에 여러 개의 이름을 추가할 수 있는 것이다.
이름을 추가하는 이유는 같은 파일이더라도 이름을 어떻게 주는지에 따라서 어디에 푸시되는지가 결정되기 때문이다. 파일은 그대로 있고, 이미지명에 따라서 업로드하는 곳이 달라지는 것이다.
이미지를 원하는 곳에 업로드 하고 싶으면 위처럼 이미지의 네이밍 규칙을 활용해서 업로드할 곳의 이미지 이름으로 변경하면 된다. 또한, 레지스트리 명과 프로젝트 명을 어떻게 설정하냐에 따라서 다양한 곳에 다양한 버전으로 배포할 수 있다.
원래 denied: requestd access to the resource is denied 오류가 나야하는데 … 난 그냥 바로 됐다.
저 에러가 나는 이유는 도커 허브의 이미지를 푸시할 때는 업로드할 계정의 인증 정보가 필요한데, 로그인이 되어있지 않기 때문이다.
docker login
docker logout
docker image rm 이미지명
실제 실습을 하고 삭제할 때 이름 변경한 이미지와 원본 이미지를 모두 삭제한다. 처음 삭제는 Untagged만 되고, 두번째 삭제할 때 Untagged와 Deleted까지 되는 걸 볼 수 있다.
하나의 이미지를 받아서 태그 명령어를 사용해서 새로운 이미지명을 추가했기 때문에 하나의 이미지로 두 개의 이미지 태그가 있는 상태였다. 그래서 이미지 태그를 하나만 삭제할 때는 이 이미지를 참조하고 있는 다른 이미지명이 있기 때문에 Untagged가 되고 삭제되지 않았지만 두번째 이미지를 삭제할 때는 더이상 이 이미지를 참조하고 있는 이미지명이 없기 때문에 아예 파일 자체가 삭제되는 것을 볼 수 있다.
이렇게 이미지와 이미지명의 관계는 실제 파일과 참조 링크처럼 생각하면 된다. 물리적인 파일에 여러 개의 링크 형태로 이미지에 이름을 붙일 수 있고, 더이상 참조하는 이미지명이 없을 경우에 물리적인 파일도 삭제되는 것이다.
번외로 참조라는 단어를 써서 혹시 처음에 만들어진 이미지가 생성되면 아예 삭제되는 것인가? 라는 생각이 문득 들었다. 그래서 실습과 반대로 삭제해봤다.
이미지명을 추가해서 만든 것보다 기존 이미지인 devwikirepo/simple-web:1.0을 먼저 지워봤다. Untagged만 뜨고, image 목록에도 추가로 생성한 yoonjeongwon/my-simple-web:0.1은 존재하는 것을 알 수 있었다. 그리고 그 후에 yoonjeongwon/my-simple-web:0.1를 삭제하니 Untagged와 Delete가 같이 발생했다.
따라서 “더이상 참조하는 이미지명이 없을 경우에 물리적인 파일도 삭제” 에 집중해서 이해하면 좋을 것 같다.
삭제 후 본인 레포에서 다시 다운받으면 이미지가 로컬스토리지에 없기 때문에 다운받아진다. (이때 도커 허브로 다운로드 수가 증가함을 볼 수 있다.)
이제 이미지의 이름을 다른 사람들에게 전달해주면 어떤 환경에서든 도커만 설치되어 있으면 완벽하게 일치하는 서버를 구성할 수 있다.
도커를 사용하기 전에는 이미지가 아닌 소스 코드나 애플리케이션을 파일로 공유했다. 이렇게 공유하면 실제로 애플리케이션을 실행할 때 OS나 라이브러리가 PC별로 차이가 있기 때문에 개발자의 개발용 PC에서는 잘 실행되던 애플리케이션도 운영 환경이나 다른 PC에서는 제대로 동작하지 않는 문제가 종종 생긴다. 그래서 운영 환경을 테스트할 수 있는 QA환경을 만들고 운영 환경과 완벽하게 일치시키는데 많은 리소스를 투자한다. 그럼에도 불구하고 이렇게 환경의 불일치로 문제들이 발생한다.
컨테이너를 사용하면 위처럼 환경의 차이에서 발생하는 문제들을 근본적으로 해결할 수 있다. 간단한 웹서버부터 복잡한 애플리케이션 서버 구성까지 이미지에 실행 가능한 형태로 저장해서 공유하면 서버 운영비를 줄이고 새로운 서버를 구성하는 시간을 크게 단축시킬 수 있다.
너무 머싯어요....😻
혹시 앱잼때 도커 필수인가횽..?!!