一次 Harbor 拉取三连败:unauthorized、denied、manifest unknown 到底各指什么

接手测试三组那台新机时,我以为装环境无非是跑几条 compose,结果第一条 pull 就给我脸色看。

$ docker pull registry.corp-lz.local/qa/pay-gateway:2.4
Error response from daemon: Get https://registry.corp-lz.local/v2/qa/pay-gateway/manifests/2.4: unauthorized: authentication required

那个 2.4 就是前一篇 〈CI 里 JVM 参数怎么并进容器〉 结尾推上去的那版,tag 是构建组定的,到我手里就这个号。

先登了,可登的不是这家门

机器还是老底子:CentOS 7.9、Docker 20.10.7,compose 是带横杠的 v1。

我以为自己忘了登录,随手敲了不带域名的 login,屏幕回得挺客气。

$ docker login
Login Succeeded

再拉一次,报错换了个更绕的说法:

$ docker pull registry.corp-lz.local/qa/pay-gateway:2.4
Error response from daemon: pull access denied for registry.corp-lz.local/qa/pay-gateway, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

头一句 unauthorized 很干脆,就是没带凭据。 第二句尾巴上挂着 may require 'docker login',我差点顺着它再登一遍。

毛病不在登没登成,在登的是谁家的门。不带域名那条 docker login,默认对象是 https://index.docker.io/v1/ 。

auths 里只有 docker.io 一个键

翻凭据文件,auths 底下果然孤零零一个键。

$ cat ~/.docker/config.json
{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "eHh4...(base64 一长串,抹掉了)"
        }
    }
}

docker.io 底下躺着一屋子公共镜像,所以那句 Login Succeeded 是真的,只是跟 corp-lz 毫无关系。

后来清凭据我只删 corp-lz 该管的那家,index.docker.io 那把一直留着,公共镜像照旧匿名拉。

docker 认门的逻辑很直白:拉哪个域名,就拿它去 auths 里对键。 registry.corp-lz.local 对不上 index.docker.io,这一趟出去仍是匿名,registry 当然回 denied。

全称登完,报错变成 manifest unknown

带上域名再登一次。

$ docker login registry.corp-lz.local
Username: qa03
Password:
Login Succeeded

这回 pull 出去,报错成了第三句:

$ docker pull registry.corp-lz.local/qa/pay-gateway:2.4
Error response from daemon: manifest for registry.corp-lz.local/qa/pay-gateway:2.4 not found: manifest unknown: manifest unknown

认证这关过了,现在是仓库自己开口说它没有这个东西。 去翻 CI 推镜像那步日志,推上去的 tag 是 2.4.0,压根没有 2.4。

两条文案指两个方向,别拿去互相排查。denied 是门没开,unknown 是门开了、架上没这个货。 拿 denied 去查 tag,或者拿 unknown 去要权限,都是白跑。

tag 为什么少一截也问明白了:CI 那头的版本号取自版本号文件,三位齐全,两位短 tag 得人工补推一次,那回谁都没记起来。

换成 2.4.0 就下来了。

$ docker pull registry.corp-lz.local/qa/pay-gateway:2.4.0
2.4.0: Pulling from qa/pay-gateway
Digest: sha256:9b1f2c7e0d4a8f3b6c1e5d2a7f0b3c9e1d4a7b0c5f8e1d4a7b3c6e9f0d2a5b8
Status: Downloaded newer image for registry.corp-lz.local/qa/pay-gateway:2.4.0

digest 那串我没细核,Status 那行才是我等的。

compose 不会替你多认证这一回

还有一处行为得记下。这台本地存着早前 docker load 进来的旧 2.3,compose 里 tag 写对之后 up 一看本地有,就不去 registry 跑那一趟,底下 pull 一步都没发生,login 自然用不上。

我本想给 compose 配个每次强制拉取,翻了半天,v1 这份文件不认 pull_policy 这类字段,手册里这条是新版编排才收的。

所以这台上只剩一条路:up 之前先 docker-compose pull 单独过一遍。 它把文件里每个 service 的镜像对着 registry 过一遍,缺哪个补哪个,registry 上有新版也顺手带下来。

现在我拉之前先 cat 一眼 config.json,看 auths 底下有没有要拉的那个域名键,十秒钟的事。

镜像总算落了地,tag 的账却没收。CI 一天出三四个版本,旧的也都往本地堆,两天下来 docker images 里 <none> 挂了二十几个。 抬头看,df 那栏红数字又往上窜了一截。

posted @ 2026-10-27 13:17  kaka的程序人生  阅读(5)  评论(0)    收藏  举报