Prologue
사내에서 자체적으로 운용할 Private Container Registry가 필요해서 초기에는 간단하게 Docker에 docker-registry 이미지를 이용해 아주 간단한 형태로 배포해서 사용하고 있었는데요. UI를 붙여보았지만, 너무 심하게 단순한 정보만을 제공하고 있었고, 무엇보다도 유저 관리가 불가능했습니다. 이렇다 보니, 외부 개발자 분들과 소통할 때, Registry 접근을 위해 사내에서만 사용하는 계정 정보가 쉽게 노출되는 등의 문제가 많았습니다.
이런 불편함을 해소하기 위해 이것 저것 조사하다, 가장 활발하게 발전하고 있는 이 프로젝트를 발견했습니다.
Harbor
Harbor는 기존 docker-registry와는 달리 policy와 role 기반으로 access를 제어(RBAC)하는 것이 가능하다는 점이 가장 큰 특징입니다. 또한 Harbor가 보관하고 있는 이미지의 취약성 등을 체크하여 해당 이미지가 신뢰할 수 있는 것인지 증빙해주는 역할도 수행합니다. 그리고 Container Image만 보관할 수 있는 것이 아니라, Helm Package와 Cloud Native Application Bundle이라 하는 CNAB 패키지도 보관할 수 있습니다.
또한 자체 WEB UI도 제공하여 관리가 편리하다는 장점이 있습니다. 물론 기존에도 docker-registry 용 UI container를 구성하여 이용하고는 있었지만, 특정 이미지가 Registry에 보관되어 있는지 등을 확인하는 정도로만 사용할 수 있어서 그 활용도가 굉장히 제한적이었습니다.
본 포스트에서는 docker-compose를 활용해 HTTPS를 지원하는 Harbor를 구축해보고, 이후 포스트에서는 Container Image, Helm Package 등을 push하는 작업을 소개하겠습니다.
Installation
HTTPS 지원을 위한 인증서 생성 및 업데이트
Certification 파일 디렉터리 생성
인증서 생성 및 기타 작업을 수행하기 위한 디렉터리를 생성합니다.
$ cd ~
$ mkdir -p ~/certs
$ cd ~/certs
CA Certificates 생성
실제 RootCA (신뢰할 수 있는 루트 인증 기관)를 사용하는게 아니라면, 직접 CA (인증 기관)를 생성하여 Server의 인증서가 안전하다고 인증해주어야 합니다. 따라서 아래의 명령어로 개인용 Root CA 역할을 할 CA.key를 생성하고, CA.key의 짝이 되는 CA.crt 공개키를 생성합니다.
# Root CA의 비밀키 생성
$ openssl genrsa -out ca.key 4096
# Root CA의 비밀키와 짝을 이룰 공개키 생성
$ openssl req -x509 -new -nodes -sha512 -days 365 \
-key ca.key \
-out ca.crt
Server Certificates 생성
이번에는 서버의 인증서를 생성합니다. Root CA의 비밀키와 공개키를 만들 때와 마찬가지로 서버의 비밀키를 생성하고, 생성한 비밀키를 넣어 CSR 파일을 생성합니다. CSR 파일은 Certificate Signing Request 파일로, 인증서를 발급하기 위해 필요한 정보를 담고 있는 데이터입니다. CSR 파일은 SSL 발급을 신청하기 위해 해당 파일 내용을 Root CA에 제출하는 용도로 사용하게 됩니다.
# Server의 비밀키 생성
$ openssl genrsa -out server.key 4096
# Server의 CSR 파일 생성
$ openssl req -sha512 -new \
-key server.key \
-out server.csr
SAN 등록
이제 위에서 생성한 서버의 CSR 파일을, 직접 만든 Root CA에 인증해달라고 요청하는 작업을 수행합니다. CSR 파일을 가지고 서버의 인증키를 생성하게 됩니다.
$ vi v3ext.cnf
# 아래 내용 추가
subjectAltName = IP:192.168.X.X,IP:127.0.0.1
# 위 작업 수행 이후, SAN 등록하는 작업 수행
$ openssl x509 -req -sha512 -days 365 \
-extfile v3ext.cnf \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in server.csr \
-out server.crt
Certificate 업데이트
Docker에서는 .crt
파일을 CA (인증 기관)의 인증서라고 간주합니다. 서버의 인증서라는 것을 표현하고 싶다면 .crt
형식이 아닌 .cert
형식으로 변환해주어야 합니다. 따라서 server.crt
파일을 server.cert
파일로 변환합니다.
$ openssl x509 -inform PEM -in server.crt -out server.cert
만들어진 인증서 파일들을 Docker와 Host에 등록, 업데이트하는 작업을 수행합니다.
# Docker
# host의 이름을 server라고 했으므로, /certs.d/server로 생성합니다.
sudo mkdir -p /etc/docker/certs.d/server
cp server.cert /etc/docker/certs.d/server/
cp server.key /etc/docker/certs.d/server/
cp ca.crt /etc/docker/certs.d/server/
# Host
sudo cp ca.crt /usr/local/share/ca-certificates/harbor-ca.crt
sudo cp server.crt /usr/local/share/ca-certificates/harbor-server.crt
sudo update-ca-certificates
Harbor package 다운로드
Harbor는 Offline Install과 Online Install 두 가지 방식으로 설치를 지원하고 있습니다. 본 포스트에서는 Offline Install 을 기준으로 설치하도록 하겠습니다. 현재 2021년 5월 27일 기준으로 v2.2.2 릴리즈가 최신입니다.
# 홈 디렉터리로 이동합니다.
$ cd ~
# 설치 파일을 다운로드 합니다.
$ wget https://github.com/goharbor/harbor/releases/download/v2.2.2/harbor-offline-installer-v2.2.2.tgz
# 다운로드한 파일을 압축 해제 합니다.
$ tar xzvf harbor-offline-installer-v2.2.2.tgz
# 압축이 해제된 harbor 디렉터리로 이동하여 작업을 수행합니다.
$ cd ~/harbor
harbor.yml
작성
바로 위 문단에서 이동한 디렉터리에서 아래의 작업을 수행합니다. 기본적으로 디렉터리 내에는 harbor.yml.tmpl
파일이 존재합니다. 이 파일의 이름을 harbor.yml
로 수정하고 내용을 필요에 맞게 수정합니다. 본 포스트에서는 아래 세 개의 내용을 수정했습니다.
$ cp harbor.yml.tmpl harbor.yml
$ vi harbor.yml
# 아래 내용 수정
hostname: {IP주소로 수정 (예시, 192.168.X.X)}
https.certificate: {server.cert로 수정 (예시, /etc/docker/certs.d/server/server.cert)
https.private_key: {server.key로 수정 (예시, /etc/docker/certs.d/server/server.key)
Deploy
위 문단에서 작업한 harbor.yml
의 작성이 끝나면, Harbor 설치의 사전 작업을 수행하는 prepare
스크립트를 실행합니다. prepare
스크립트는 결과적으로 prepare 컨테이너를 생성합니다.
prepare 작업을 완료했다면 이제 설치할 시간입니다. sudo
명령을 사용하지 않으면 권한 관련한 문제가 여럿 발생하는 것을 확인했습니다. sudo
를 붙여주면 문제 없이 설치가 완료됩니다. 이 작업에는 시간이 조금 소요되니 차분히 커피 한 모금하며 기다려주시면 됩니다.
$ ./prepare
$ sudo ./install.sh
완료
설치가 완료됐다면 이제 로그인해봅시다. 단, 접속을 위해서는 사전에 만들어둔 우리의 Root CA 공개키가 현 로컬에 등록되어 있어야 합니다. 해당 내용은 추후 다뤄볼 수 있도록 하겠습니다.
로그인할 때는 기본적으로 admin
과 Harbor12345
로 로그인할 수 있습니다. 보안상 최초 로그인 이후에 해당 패스워드를 변경해줄 필요가 있습니다.
다음 글에서는 이렇게 구축한 Harbor에 Helm Package와 Container Image를 업로드하고 이용하는 내용을 다뤄보겠습니다.
마무리
여기까지 따라오시느라 고생이 많으셨습니다. 만약 이 튜토리얼이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.
혹시라도 튜토리얼에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊
참고
'IT > DevOps' 카테고리의 다른 글
[DevOps/번역글] Helm vs Kustomize: 어떻게 배포할 것인가? (0) | 2021.07.24 |
---|---|
[DevOps/번역글] Github Actions냐 Jenkins냐! 올바른 선택을 해봅시다 (1) | 2021.07.04 |
[DevOps] ArgoCD Slack Notification 설정하기 (3) | 2021.07.03 |
[DevOps] Jenkins Pipeline이 종료되지 않는 경우 (0) | 2021.06.14 |
[DevOps] ArgoCD Best Practice (0) | 2021.06.12 |