docker push 가 Harbor 에서 실패할 때 메시지마다 원인이 다르다. 순서대로 보면 대개 세 단계에서 걸린다 — 전송 계층(HTTP/HTTPS), 인증, 그리고 프로젝트 권한이다.
Get "https://registry.example.com:8088/v2/": http: server gave HTTP response to HTTPS client
Harbor 가 HTTP 로 떠 있는데 클라이언트는 HTTPS 로 접속하려 한 것이다. 클라이언트마다 등록해 준다.
{
"insecure-registries": ["registry.example.com:8088"]
}
systemctl daemon-reload
systemctl restart docker
docker info | grep -A3 'Insecure Registries'
docker login 에 http:// 를 붙이면 안 된다. 스킴 없이 호스트:포트 로 적는다. containerd 를 쓰는 노드는 /etc/containerd/certs.d/<호스트:포트>/hosts.toml 에 skip_verify = true 또는 평문 HTTP 주소를 적어 따로 등록한다. 운영 환경이라면 Harbor 에 인증서를 붙여 HTTPS 로 올리는 편이 맞다.
unauthorized: unauthorized to access repository: registry.k8s.io/kube-apiserver, action: push
전송은 됐고 권한에서 막힌 것이다. Harbor 는 이미지 경로의 첫 요소를 프로젝트로 해석한다.
registry.example.com:8088/<프로젝트>/<리포지터리>:<태그>
확인할 것은 넷이다.
registry.k8s.io 라는 이름의 프로젝트가 필요하다. 점이 들어간 이름을 쓸 수 있긴 하지만 혼동을 줄이려면 k8s 처럼 단순한 프로젝트를 만들고 그 아래에 넣는 편이 낫다.~/.docker/config.json 에 남은 옛 자격증명 때문에 실패하는 경우가 있다.태그를 다시 붙여 올린다.
docker login registry.example.com:8088
docker tag registry.k8s.io/kube-apiserver:v1.33.6 \
registry.example.com:8088/k8s/kube-apiserver:v1.33.6
docker push registry.example.com:8088/k8s/kube-apiserver:v1.33.6
로그인을 하지 않았거나, 로그인한 레지스트리 주소와 태그의 주소가 다를 때 나온다. 태그에 레지스트리 주소가 빠져 있으면 Docker Hub 로 올리려 시도하므로 이 메시지가 뜬다. 태그의 앞부분이 docker login 에 쓴 주소와 글자 그대로 같은지 본다.
HTTPS 로 떴지만 사설 CA 를 클라이언트가 신뢰하지 않는 경우다. 진단은 사설 레지스트리 TLS 신뢰 문제 진단 에 있다.