[Docker Registry] 도커 사설 원격 레지스트리 만들기

2019. 10. 31. 17:39Engineering/Container&Kubernetes

Contents

0. Prologue

1. Registry 이미지 다운로드

2. SSL 인증서 생성 및 적용

3. Image Pull/Push 해보기


 

 

 

Docker Registry 를 활용해 개인용 레지스트리를 원격 서버에 구축하고 사용하는 방법을 알아봅니다. 


0. Prologue

본 글에서는 아래 그림과 같이 원격지에 사설 Registry를 구축하는 방법을 소개 합니다. 

 

원격 사설 Registry 구축 구조

 

- Registry Server : Docker Registry 컨테이너를 실행하는 호스트 입니다.
                             구축 편의상 로컬 PC에 Registry 컨테이너를 구축할 수도 있지만,

                             본 글에서는 Registry 만을 위한 서버가 원격지에 따로 있는 환경을 가정합니다. 

 

- Client : 로컬 PC로, Docker Registry 서버에 접근하는 클라이언트 입니다. 

 

 

1. Registry 이미지 다운로드 

Docker Hub에 Docker Registry 공식 이미지가 업로드 되어 있습니다. 

이 이미지를 다운 받아 쉽게 실행 할 수 있습니다. 

 

[@DOCKER REGISTRY SERVER]

우선 docker registry 서버쪽 머신에 접속하여 

$ docker pull registry  명령어를 통해 Docker registry 이미지를 다운 받습니다. 

$ docker pull registry

 

1.1 Local Registry로 활용하기

해당 이미지를 실행만 시켜주면 docker registry를 Local Registry로 바로 사용할 수 있습니다!

docker run 명령어를 통해 registry를 실행할 수 있습니다.

이때, registry 컨테이너가 사용하는 포트가 5000번이므로, registry 서버 호스트와의 포트포워딩 설정을 -p 옵션을 통해 설정합니다. 

registry 서버 호스트의 5000번 포트로 들어오는 요청은 모두 registry 컨테이너의 5000번 포트로 포워딩 됩니다 .

$ docker run -itd --name={containerName} -p 5000:5000 registry

 

 

 registry 컨테이너가 정상적으로 실행중인지 확인합니다. 

$ docker ps

 

 

이제 해당 컨테이너로 컨테이너 이미지를 Pull/Push 할 수 있습니다. 

로컬에 미리 저장해둔  nginx 이미지를 registry 컨테이너로 Push 해보겠습니다.

이를 위해서 먼저 이미지의 tag를 {registryIP}:{registryPort}/{imgName} 와 같은 형태로 변경해야 합니다. 

 

docker tag 명령어를 통해 위와 같은 형식으로 tag를 변경합니다.

현재 registry는 Local에서 동작하고 있으므로 registryIP에는 'localhost'를, registryPort에는 앞서 설정해둔 5000번을 입력합니다.

$ docker tag nginx localhost:5000/nginx

 

 

이제 docker push 명령어를 사용해 해당 이미지를 registry에 업로드할 수 있습니다. 

$ docker push localhost:5000/nginx

 

curl 명령어를 통해 local registry에 업로드된 이미지 목록을 확인하여,

nginx 이미지가 제대로 업로드 되었는지 확인할 수 있습니다.

$ curl -X GET http://localhost:5000/v2/_catalog

 

 

그러나, registry를 원격지에 구축하기 위해서는 몇가지 추가 설정이 필요합니다. 

필요한 설정을 2장에서부터 알아봅니다. 

 

 

2. SSL 인증서 생성 및 적용  

Registry가 원격지에 있는 경우, 클라이언트와 registry 서버는 https 프로토콜을 사용합니다. 

이에 따라 SSL 인증서를 생성하고 설치해주어야 합니다. 

SSL 인증서에 대한 자세한 내용은 https://5equal0.tistory.com/9?category=727993를 참고하시기 바랍니다. 

 

 

본 글에서는 무료 SSL 인증서 사용을 위해 자체서명인증서를 생성하여 registry 컨테이너에 적용하겠습니다.

 

2.1 SSL 인증서 생성

자체서명인증서를 생성 과정은 https://5equal0.tistory.com/9?category=727993의 3번과 유사합니다. 

본 글에서는 '~/certs' 디렉토리에 SSL 인증서와 관련된 파일을 저장하겠습니다. 

$ mkdir ~/certs
$ cd ~/certs

 

가장 먼저 Private Key를 생성합니다.

(pass phrase로 임의의 암호를 사용하시기 바랍니다.)

$ openssl genrsa -des3 -out server.key 2048

 

CSR 파일을 생성합니다. 

이때, CN 값에 registry server의 IP 주소 (또는 도메인명)을 입력합니다. 

다른 값은 공백이어도 괜찮습니다. 

$ openssl req -new -key {keyfilename}.key -out {csrfilename}.csr

 

Key 파일의 암호화를 해제 합니다. 

$ openssl rsa -in server.key -out server.key

 

SAN 설정을 위해 Config 파일을 다음과 같이 생성 합니다. 

$ echo subjectAltName=IP:{registryServerIP},IP:127.0.0.1 > extfile.cnf

 

위 설정을 안하면 후에 이미지 push 시도에 아래와 같은 에러가 발생합니다.

 

마지막으로 자체서명인증서를 생성합니다. 

$ openssl x509 -req -days 800 -signkey server.key -in server.csr -out server.crt -extfile extfile.cnf

 

 

2.2 SSL 인증서 적용 [@Registry Server]

위와 같이 SSL 인증서를 생성 하셨으면, 인증서를 각 서버와 클라이언트 단에 적용 해야 합니다. 

먼저 서버단에서는 생성된 인증서를 사용해 registry 컨테이너를 다시 시작해야 합니다. 

 

먼저 실행해 두었던 registry 컨테이너가 있다면 docker stop, docker rm  명령어로 컨테이너를 중지 시키고 삭제합니다. 

$ docker stop {registryContainer} && docker rm {registryContainer}

 

이제 새로 Registry를 실행해 봅시다.

-v 옵션으로 인증서가 저장되어있는 '~/certs' 폴더를 registry 컨테이너의 '/cert' 경로로 마운트 합니다. 

그리고 Registry 컨테이너의 환경변수로 SSL key 및 인증서 위치를 전달해 줍니다. 

$ docker run -itd --name={registryContainerName} -v {hostCertDir}:{contCertDir} \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
-e REGISTRY_HTTP_TLS_CERTIFICATE={contCertDir}/server.crt \
-e REGISTRY_HTTP_TLS_KEY={contCertDir}/server.key -p 5000:5000 registry

 

 

registry 컨테이너가 정상적으로 실행되었는지 확인합니다. 

$ docker ps 

 

 

2.3 SSL 인증서 적용 [@Client]

이제 원격 Registry에 이미지를 업/다운 로드 하려는 클라이언트에서의 SSL 인증서 설정을 수행하겠습니다.

 

우선 scp를 통해 Registry서버에서 생성했던 SSL 인증서를 클라이언트 머신으로 옮겨옵니다. 

여기서는 편의상 클라이언트의 홈 경로에 'certs' 폴더를 만들고 SSL 관련 파일들을 모두 'certs' 폴더에 옮겨왔습니다.

$ scp {srcHost}@{srcIP}:{srcfile} {dstfile}

 

 

다음으로, SSL 인증서를 클라이언트 시스템에 적용합니다. 

이는 운영체제에 따라 방법이 다를 수 있으며, 자세한 내용은 https://setyourmindpark.github.io/2018/02/06/docker/docker-4/를 참고하시기 바랍니다. 

본 글은 Ubuntu를 기준으로 설명합니다. 

 

 

SSL 인증서를 시스템의 인증서 보관 폴더로 이동합니다. 

$ cp {cerfileDir}/{cerfileName}.crt /usr/share/ca-certificates/

$ echo {certFileName}.crt >> /etc/ca-certificates.conf

 

변경 내용을 시스템에 반영 합니다. 

$ update-ca-certificates

 

클라이언트 시스템의 도커 데몬을 다시 실행합니다. 

$ sudo service docker restart

 

 

3. Image Pull/Push 해보기

드디어 모든 설정이 끝났습니다. 

그럼 이제 클라이언트에서 원격지에 있는 registry 서버에 컨테이너 이미지를 pull/push 해봅시다.

 

먼저, 업로드할 이미지의 tag를 {registryServerIP}:{registryServerPort}/{imageName} 과 같은 형식으로 변경 합니다. 

$ docker tag {srcImage} {registryServerIP}:{registryServerPort}/{dstImage}

 

 

docker push 명령을 통해 해당 이미지를 원격 registry로 업로드 합니다. 

$ docker push {targetImage}

 

 

짜잔 드디어 성공적으로 push가 되었습니다 !!!!!!!!

curl 명령어로 원격 registry의 이미지 목록을 조회해서 진짜 이미지가 제대로 업로드 되었는지 확인해봅시다. 

주의하실 것은 registry 서버 주소를 입력하실때 https를 사용해야 한다는 것입니다 !!!!

이 https 때문에 기나긴  SSL 인증서 등록 절차를 따라 온 것 이니까요!

$ curl -X GET https://{registryServerIP}:{registryServerPort}/v2/_catalog

 

 

클라이언트에서 업로드 했던 cuda 이미지가 원격 registry 에 정상적으로 업로드된것을 확인할 수 있습니다.