首先,我在Docker自动容器检测模式下为traefik reverse-proxy运行一个容器,如下所示:
docker run \
-d \
--name traefik \
--publish 80:80 \
--volume /dev/null:/etc/traefik/traefik.toml \
--volume /var/run/docker.sock:/var/run/docker.sock \
traefik \
--docker \
--docker.exposedbydefault=true \
--accessLog
然后我为Docker注册表运行一个容器,如下所示。我没有发布固定端口,而是通过/registry
反向代理后面的traefik
端点设置相应的标签来访问注册表。
docker run \
-d \
--label traefik.frontend.rule="PathPrefix: /registry" \
--name registry \
--publish 5000 \
registry:latest
现在我下载一个公共图片并重新标记它以匹配我的注册表的域名和子路径:
docker pull nginx:alpine
docker tag nginx:alpine localhost/registry/nginx:alpine
试图推动它:
docker push localhost/registry/nginx:alpine
这会导致以下错误:
The push refers to repository [localhost/registry/nginx]
951c1d7bace7: Preparing
91295ee17337: Preparing
423678709065: Preparing
cd7100a72410: Preparing
error parsing HTTP 404 response body: invalid character 'p' after top-level value: "404 page not found\n"
查看traefik
容器中的日志,我看到了:
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "GET /v2/ HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 143 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "HEAD /v2/registry/nginx/blobs/sha256:f9fe12447daf15e667ba4c67d66c585ac07273748d5ccf78af1544e67324953b HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 144 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "HEAD /v2/registry/nginx/blobs/sha256:ad017fd52da2cac5b962bc191e9d40397b93e73027d21240477274d154784222 HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 145 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "POST /v2/registry/nginx/blobs/uploads/ HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 146 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "HEAD /v2/registry/nginx/blobs/sha256:ff3a5c916c92643ff77519ffa742d3ec61b7f591b6b7504599d95a4a41134e28 HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 147 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "HEAD /v2/registry/nginx/blobs/sha256:d81b148fab7c3ce295657d0f8b621824e7afc19a8edd4abbf20b9dbafb2f62c7 HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 148 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "POST /v2/registry/nginx/blobs/uploads/ HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 149 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "POST /v2/registry/nginx/blobs/uploads/ HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 150 - - 0ms
172.17.0.1 - - [18/Jun/2018:21:21:09 +0000] "POST /v2/registry/nginx/blobs/uploads/ HTTP/1.1" - - - "docker/18.03.1-ce go/go1.9.5 git-commit/9ee9f40 kernel/4.4.0-128-generic os/linux arch/amd64 UpstreamClient(Docker-Client/18.03.1-ce \(linux\))" 151 - - 0ms
显然,请求被正确路由到注册表后端,输出看起来不太糟糕。谁回来了那个404错误呢?
然后我发现了registry.http.prefix
选项as mentioned in the registry's documentation,听起来就像这个案例一样:
If the server does not run at the root path, set this to the value of the prefix. The root path is the section before v2. It requires both preceding and trailing slashes, such as in the example /path/.
因此,我从上面向我的注册表容器启动命令添加--env "REGISTRY_HTTP_PREFIX=/registry/"
。但是,结果和错误仍然相同。
在子路径中设置注册表的正确方法是什么?