도림.로그

Tags

Series

About

나만의 Docker Registry 구축하기

2023. 05. 25.

Mac Mini 사이드 프로젝트 인프라 구성하기

▶ Expand post list

    오늘은 공식 문서를 기반으로 Docker Registry를 구성해서 외부에서 접근이 가능한 나만의 Private Registry를 만들어보려 한다.

    Docker Registry란?

    Registry는 컨테이너 이미지를 저장하기 위한 저장소이다. 이미지를 업로드 시키고, 다운로드 해서 사용하고 하는 등의 동작을 수행할 수 있게 도와준다. 가장 널리 알려져 있는 Registry로는 Docker Hub를 꼽을 수 있다.

    그러면 Docker Hub 쓰면 되잖아?

    물론 굳이 나만의 Registry를 구성하지 않고, Docker Hub를 사용해서 이미지를 업로드할 수도 있다. 하지만 Docker Hub는 무료 계정에 한해서는 Private Registry를 제공하지 않고, 모든 이미지가 공개된다. 내가 생각하는 Private Registry가 필요한 이유는 다음과 같다.

    상용 서비스라면

    당연히 상용 서비스의 경우 백엔드 서버 실행파일 그 자체로 볼 수 있는 이미지를 Public하게 노출하고 싶지 않을 것이다. 비즈니스를 담당하는 서버의 실행 가능본을 노출하는 그 자체가 굉장히 부담이 될 것이다.

    사이드 프로젝트라도

    Docker 이미지를 만들어서 컨테이너에 올리고 싶다는 것은 아마 배포를 염두에 두고 있기 때문일 가능성이 높다. 그런데 서버를 빌드해서 컨테이너 이미지로 만든다는 것은 대부분의 환경에서 동일하게 동작할 수 있도록 하는 의도가 크다. 즉, 서버에서 DB에 접속하는 정보나, 다른 API 서버를 사용하기 위한 API Key 등의 정보가 컨테이너 이미지 내에 Raw 하게 저장돼 있을 가능성이 높다는 것이다. 이런 문제를 해결하기 위해 Hashicorp Vault나 AWS Secrets Manager 와 같은 수단을 사용할 수도 있겠지만 이런 솔루션에 대한 접근 역시도 Key에 의해서 런타임에 수행될 확률이 높다. 즉, 배포가 가능한 이미지를 노출하는 것 자체가 굉장히 위험하다는 의미이다. 따라서 컨테이너 이미지 자체를 Public하게 노출하지 않는 것이 가장 괜찮은 선택지 중 하나가 될 수 있다.

    구성 방법

    이런 Registry를 구성하기 위해 의외로 다양한 솔루션이 존재한다. 충분한 컴퓨팅 파워를 확보할 수 있다면, Harbor와 같은 솔루션을 도입하는 것을 고려해볼만 하다. Web UI를 제공해주기 때문에 사용성이 굉장히 좋아지기 때문이다. 나의 경우 작고 귀여운 M1 Mac Mini에 개발 서버를 띄워두고 있기 때문에, 가볍게 사용할 수 있도록 Docker에서 제공하는 공식 이미지를 사용하도록 하겠다. 공식 문서를 참고하면, 아마 로컬 환경에서 바로 띄워보는 것은 무리가 없을 것이다. 그런데 나의 경우 Docker Compose를 사용하여 nginx, 인증 API, 계정 API, MySQL, Postgres, Grafana 등등 많은 서비스들을 띄워 관리하고 있다. 따라서 Docker Compose를 통해 구성을 진행해보겠다.

    Docker Compose 설정 예시

    version: "3.8"
    
    services:
      registry:
        restart: always
        image: registry:2
        ports:
          - 5005:5000
        environment:
          REGISTRY_HTTP_TLS_CERTIFICATE: /etc/letsencrypt/live/your.domain.here/fullchain.pem
          REGISTRY_HTTP_TLS_KEY: /etc/letsencrypt/live/your.domain.here/privkey.pem
          REGISTRY_AUTH: htpasswd
          REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
          REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
        volumes:
          - /your-letsencrypt-dir-here/conf:/etc/letsencrypt
          - /your-registry-volume-dir-here/data:/var/lib/registry
          - /your-registry-volume-dir-here/auth:/auth
    • 해당 Compose 파일은 공식 문서의 이 부분과 거의 유사하다.
    • 일단 registry 컨테이너의 inbound port는 5000으로 설정돼 있다.
    • 주요하게 봐야 할 부분은 environment 부분이다.
    • 아래에 부가적인 내용들과 함께 해당 설정을 뜯어보자.

    외부에서 접근 가능한 Registry 만들기

    • 공식 문서에서 이 부분을 참고했다.
    • 공식 문서에 따르면, 먼저 Registry를 TLS로 보호해야 한다고 한다.
    • 즉, HTTPS를 위한 키가 필요하다는 뜻이다.
    • 공식 문서에서는 crtkey 파일을 사용했지만, 나의 경우 Certbot을 이용하여 API 서버나 Grafana 등의 인증서를 만들어 사용하고 있었기 때문에, registry를 위한 Certbot 인증서를 생성해주었다.
      • 생성에 사용한 명령어는 다음과 같다.
    certbot certonly --webroot --email myemail@gmail.com \
    --agree-tos --config-dir /your-letsencrypt-dir-here/conf \
    --logs-dir /your-letsencrypt-dir-here/log \
    --work-dir /your-letsencrypt-dir-here/work \
    -d registry.mydomain.com
    • 그리고 Compose 파일에 REGISTRY_HTTP_TLS_CERTIFICATE, REGISTRY_HTTP_TLS_KEY 설정을 잡아주었다.
      • 참고로, 해당 environment컨테이너 안에서 사용할 경로를 잡는 부분이다. 따라서, volumes 설정을 통해서 적절하게 호스트 머신의 디렉토리와 컨테이너 안의 디렉토리를 매핑시켜줘야 한다.

    외부 접근 인증 설정하기

    • 공식 문서에서 이 부분을 참고했다.
    • 참고로, TLS로 보호하지 않으면 인증 관련 설정을 할 수 없다. 따라서 인증서 관련 이해를 간단하게라도 숙지하는 편이 나을 것이다.
    • 인증에 가장 간단하게 사용할 수 있는 방법은 Basic Auth를 사용하는 것이다.
      • HTTP Basic Auth와 비슷하게 구현되어 있는 듯 하다.
    • 나는 예제대로 htpasswd 를 사용해서 인증을 설정했다.
    • 참고로, htpasswd 방법을 사용하기 위해서는 ID / PW 쌍을 만들어줘야 한다.
      • 생성에 사용한 명령어는 다음과 같다.
    htpasswd -c ./htpasswd yourid
    • 그리고 생성한 htpasswd 파일을 Compose 파일의 volumes 설정을 활용하여 컨테이너 안으로 밀어넣어주면 된다.
    • 인증에 필요한 파일을 밀어넣었으니, 이제 Compose 파일의 environment 설정을 통해 htpasswd 를 사용하도록 하면 된다.
      • 요 중에서 REGISTRY_AUTH_HTPASSWD_REALM 이라는 신기한 설정이 있는데, Registry Realm 으로 설정하면, Registry 영역에 대해 접근하는 것에 대한 자동 로그인 설정같은 것으로 보면 된다.

    완료

    생각보다 어려운 부분 없이 설정을 완료할 수 있었다. 이제 Docker Compose를 통해 컨테이너를 띄워주면, 나만의 Private Registry를 구성할 수 있다. Registry가 올바르게 떴는지 확인하고 싶으면, https://registry.yourdomain.com:{port}/v2로 접근해보자. 아마 HTTP Basic Auth 로그인 창이 반겨줄 것이다. nginx를 Registry 앞단에 붙여놓고 사용할 수도 있는데, 그러면 컨테이너 이미지의 사이즈에 따라 또 nginx 설정을 만져야 하는 중복 관리가 들어갈 것 같아 일단은 Registry는 nginx를 거치지 않게 띄워뒀다. 내 경우 GitHub Actions를 통해 요 컨테이너로 이미지를 업로드해서 Mac Mini로 API 개발 서버를 서빙하도록 설정해서 사용하고 있다.

    끝.

    #docker#infra#registry#docker-compose

    © 2024, Built with Gatsby