
배경 상황
Harbor를 Helm chart통해 설치하고 컨테이너 이미지와 헬름 차트를 푸시하려고 하니 docker login / helm registry login와 같은 CLI에서의 레지스트리 로그인이 실패했다. Harbor UI 에서의 로그인은 잘 되는데 로그인을 시도한 Robot account에 문제가 있나 싶어 권한 조정도 해보고 했는데 계정 권한 문제는 아니었고…
harbor-core pod와 harbor-registry pod를 살펴봤는데 registry Pod에서 아래와 같이 core와 registry간의 내부 인증이 실패하는 에러로그가 남아있었다(core pod에는 별 로그가 없었음).
error authenticating user "harbor_registry_user": authentication failure
해결 방법
Harbor에서는 core pod에서 registry pod로 요청 시 인증을 위해 htpasswd를 사용하고 있다. Harbor 헬름 차트의 values.yaml에서는 아래와 같이 시크릿을 생성해서 해당 시크릿을 참조할 수 있도록 설정할 수 있다(values.yaml에 직접 명시도 가능하나 GitOps 환경이라 보안을 위해 External Secret을 활용). 참고로 시크릿을 활용할 경우 키 값이 반드시 REGISTRY_PASSWD, REGISTRY_HTPASSWD여야 한다.
registry:
credentials:
username: "harbor_registry_user"
# If using existingSecret, the key must be REGISTRY_PASSWD and REGISTRY_HTPASSWD
existingSecret: "harbor-registry-htpasswd"
여기서 htpasswd란 Apache HTTP 서버에서 시작된 HTTP Basic Authentication에서 사용자명과 암호화된 패스워드를 저장하는 파일 형식이다. 파일 형태는 아래와 같이 “사용자명:암호화된패스워드” 형식으로 사용하게 되는데 암호화 방식은 MD5, bcrypt 등 여러 알고리즘을 지원하고 있다.
username1:$apr1$xxxxx$xxxxxxxxxxxxxxxxxx
username2:$2y$05$xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
harbor_registry_user:$2a$10$xxxxxxxxxxxxxxxxxxxxx
참고로 Harbor에서는 bcrypt 방식을 사용하는데, httpasswd 파일 생성을 쉘 스크립트로 실행하다보니 파일 형식이 잘못 들어가서 문제가 발생하고 있었다.
# 잘못됨
$$2k$$05$$...
# 정상 htpasswd 형식
$2k$05$...
정상적인 형태로 htpasswd 값을 수정하고 로그인을 시도하니 정상적으로 동작했다.
# 일반 사용자 로그인
echo 'password' | docker login <harbor url> -u username --password-stdin
# Robot Account 로그인
echo "$ROBOT_TOKEN" | docker login <harbor url> -u 'robot$name' --password-stdin