생각하게 된 계기
우아한테크코스 교육과정에서 “데벨업”이란 이름의 개발자 취준생 커뮤니티 제작 프로젝트를 진행하고 있다. 프로젝트 진행 과정에서 개발 서버와 운영 서버를 분리하게 되었다. 따라서, 두 서버에 다른 이미지로 만들어진 컨테이너가 동작하게 된다. 만약, 이미지 관리를 하나의 레지스트리에서 한다면, 각 서버에서 어떤 이미지를 pull 받아야 하는지 결정하는 과정이 CD 에 추가되어야 한다. 복잡한 작업이 될것이라 예상되어 개발용 레지스트리와 운영용 레지스트리를 분리하는 방법을 찾게 되었다.
상용 서비스 vs 직접 운영
기본적인 레지스트리인 도커 허브에선 무료 플랜에선 프라이빗 레지스트리를 하나만 제공한다. 또 다른 서비스인 깃허브 패키지 역시 무료 플랜에선 용량과 트래픽 제한이 있다. 다른 상용 서비스들도 여럿 있지만, 프라이빗 레지스트리를 위해선 돈을 지불해야 한다. 반면, 직접 운영하는 경우 서버 임대 비용을 제외하면 별도의 비용이 발생하지 않는다. 따라서, 직접 레지스트리를 운영하는 방법에 대해 학습할 가치가 있다고 판단했다.
구축 과정
최종적으로 구현된 자체 레지스트리 웹페이지
위와 같은 레지스트리 웹페이지를 만든 과정을 소개한다.
레지스트리 컨테이너 띄우기
compose.yml
레지스트리에 https 적용하기
도커에서 레지스트리가 https 적용이 되어있지 않은 경우 거부하는 것이 기본 설정이다. 예외 설정을 할 수 있지만, 레지스트리를 따로 운영하는 이유가 보안 때문이므로 앞뒤가 맞지 않는다. 따라서 https 를 적용해야 한다고 생각했다.
레지스트리에 https를 적용하는 방법도 있다. 하지만, 추후 웹 UI 도 붙일 것이고 이 곳에도 https 를 적용해야 하는 것이 자명했다. 따라서 https 적용하는 것을 분리하여 nginx를 추가하고 리버스 프록시와 https 를 적용하는 것이 나을 것이라 판단했다. 아래는 이에 따라 변경된 compose.yml 이다.
compose.yml
nginx 설정
레지스트리에 업로드 및 다운로드 테스트하기
기본적인 nginx 설정으로는 이미지가 크면 413 Request Entity Too Large 오류가 발생한다.
nginx 기본 설정에서는 요청의 크기를 1 MB 로 제한하고 있다. 따라서, 도커 이미지 파일을 전송하기에는 그 크기가 부족하다. 적절하게 늘려야 한다. 화끈하게 10G 로 설정했다. 물론 실제 환경이라면 적절한 값으로 설정해야 문제가 생기지 않는다.
nginx 설정
이후 테스트 용도로 이미지를 만들고 태그를 붙여서 레지스트리에 업로드 해보았다.
# 베이스 이미지로 Nginx 사용
FROM nginx:alpine
# Nginx의 기본 웹 루트에 간단한 HTML 파일 추가
COPY index.html /usr/share/nginx/html/
# Nginx 서버 포트 개방
EXPOSE 80
# Nginx 실행
CMD ["nginx", "-g", "daemon off;"]
Docker
복사
docker build -t mytestimage .
docker tag mytestimage {레지스트리 도메인}/mytestimage:latest
docker push {레지스트리 도메인}/mytestimage:latest
Bash
복사
인증된 사용자만 레지스트리에 접근할 수 있도록 허용하기
지금은 별도의 인증 없이도 우리 레지스트리에 접근할 수 있다. 이를 해결하기 위해서 별도의 인증 수단을 추가해야 한다.
HTTP의 인증 중 가장 간단한 방식인 Basic Auth 방식이 있다. 이는 HTTP 헤더에 유저 이름과 비밀번호를 Base64로 인코딩 한 값을 포함해 인증수단으로 사용하는 방식이다. 취약한 인증 방식이지만, HTTPS 를 적용하는 순간 이를 보완할 수 있다. 따라서, 이를 인증 수단으로 사용하기로 결정했다.
Basic Auth를 사용하기 위해선 결국, 서버에 어떤 방식으로든 아이디와 비밀번호를 저장해야 한다. Apache 서버에서 이를 위해 htpasswd 라는 유틸을 만들었고, 이를 통해 {유저이름}:{비밀번호 MD5 HASH} 형태의 텍스트 파일을 만들고 서버에 적용할 수 있게 했다. Nginx 역시 이를 지원한다.
compose.yml
nginx 설정
웹 UI 붙이기
마지막으로 도커 허브처럼 웹페이지 형태로 이미지를 관리할 수 있으면 좋겠다고 생각했다. 도커 레지스트리는 /v2/ 이하 경로로 여러 API를 제공하고 있다. 따라서 이 API 를 적절히 호출하고 결과를 브라우저에 적절히 표시하기만 하면 웹페이지를 구현할 수 있다. 물론, 이런 작업을 직접 하는 것 보다는 오픈소스를 사용하는 것이 간편하다.
여러 오픈소스 중 konradkleine/docker-registry-frontend를 사용했다. 이를 사용한 이유는 간단하다. 아주 기본적인 기능만 제공하는 만큼 데벨업 프로젝트에 적용하기 적절할 것이라 생각했기 때문이다. 별도의 인증 수단을 제공하지 않기 때문에 앞서 적용한 Basic Auth 를 웹 UI에도 적용했다. 이를 위해 Nginx에 프록시 설정을 변경해 /v2/ 이하 경로만 레지스트리로, 그 외의 경로는 웹 UI 경로로 프록시 되도록 설정했다.
compose.yml
nginx 설정