使用nginx的Artifactory和多个docker存储库,使用在映像名称中嵌入存储库名称

时间:2017-11-08 12:59:32

标签: artifactory docker-registry

受本文https://www.jfrog.com/knowledge-base/how-do-i-access-multiple-artifactory-docker-repositories-from-a-single-url/的启发,我们使用nginx作为反向代理,在artifactory上配置了多个docker存储库。

有三个docker存储库可供访问:

  • docker.acme.com(artifactoryhost / artifactory / docker / default)
  • docker.acme.com/repository-a(artifactoryhost / artifactory / docker / repository-a)
  • docker.acme.com/repository-b(artifactoryhost / artifactory / docker / repository-b)

所有三个repos都拥有自己的权限用户。

拉可以,但是如果不允许用户推送到默认存储库,则推送到存储库-a或存储库-b不能正常工作。推送期间的所有上传都首先存储在默认存储库中,并且仅在最后将它们移动到存储库-a。

正如我在神器日志中看到的那样,当我推动像

这样的东西时

docker push docker.acme.com/repository-a/myimage:1.0.0

docker执行一些POST请求,从神器上传位置接收并继续使用PATCH上传图层。但是,artifactory的响应在Location中没有任何存储库路径:

2017/11/08 12:35:17 [debug] 19310#0: *6107899 http upstream request: 
"/artifactory/api/docker/repository-a/v2/myimage/blobs/uploads/?
from=repository-
a%2Fmyimage&mount=sha256%3A6a8bd10c9278a8e1b59bc85f634dd4045e953
63c3b29366e9e8200ac2cd56735"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http upstream process 
header
2017/11/08 12:35:17 [debug] 19310#0: *6107899 malloc: 
0000000000EA8EF0:4096
2017/11/08 12:35:17 [debug] 19310#0: *6107899 recv: fd:23 427 of 4096
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy status 202 
"202 Accepted"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy header: 
"Server: Artifactory/5.0.1"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy header: "X-
Artifactory-Id: 1cfb2a5a96486c54:43202ab7:15ced9e7676:-8000"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy header: 
"Docker-Distribution-Api-Version: registry/2.0"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy header: 
"Docker-Upload-Uuid: d0d4ed31-6539-43a3-bb03-35e47fa13676"
2017/11/08 12:35:17 [debug] 19310#0: *6107899 http proxy header: 
"Location: https://docker.acme.com/v2/myimage/blobs/uploads/d0d4ed31-
6539-43a3-bb03-35e47fa13676"

因此所有下一个PATCH都将转到默认仓库,但不会转到存储库-a。

1 个答案:

答案 0 :(得分:1)

修改

Nginx似乎在某种程度上强制执行"Internet Hosts" RFC(另请参阅this wikipedia section),并reject任何包含非法字符的Host标头,例如斜杠字符400响应代码。您引用的文章使用Apache,它似乎对Host标头没有类似的限制。您可以通过查找用于在Host标头中分隔存储库名称同时保持其有效的不同字符来解决此问题。这显然也需要在反向代理配置中进行调整,特别是对于响应位置标题被修改的部分,如下所述。 但是,我应该从一开始就提到这个解决方案肯定是一个黑客攻击,而且可能不是最强大的解决方案,因为它背负着Artifactory中Docker V2存储库的未记录的API行为。它对于无法设置a flexible subdomain-based mechanism for docker repositories的用户特别有用,因为他们无法使用通配符证书。也就是说,如果你还没有这样做,你至少应该考虑使用两个记录的选项之一in this page

原始回答

看起来原始POST请求的“主机”标头可能不包含其中的存储库名称,否则Artifactory会在响应的Location标头中包含物理存储库名称。您提到的解决方案要求Host标头的格式为$ host / $ repo,即:

主持人:docker.acme.com/repository-a

Artifactory然后使用此信息构造PATCH端点的Location标头。这是一个卷曲的复制案例:

请求:

curl -XPOST -H "Host: docker.acme.com/repository-a" "http://localhost:8080/artifactory/api/docker/repository-a/v2/myimage/blobs/uploads/?from=repository-a%2Fmyimage&mount=sha256%3A6a8bd10c9278a8e1b59bc85f634dd4045e95363c3b29366e9e8200ac2cd56735" -v 

响应中的位置标头:

Location: https://docker.acme.com/repository-a/v2/myimage/blobs/uploads/fc325614-0e65-4c9a-a879-449ac9e8c66

错误的请求将是:

curl -XPOST -H "Host: docker.acme.com" https://...

请注意,Location标头的“v2”和“repoName”元素与Apache服务器拦截它们的方式相反。这里的技巧是通过编辑响应的Location头来改变Apache配置的顺序:

Header edit* Location "^https://<apache-server-name>/(.*?)/v2/(.*)$" "https://<apache-server-name>:<port#>/v2/$1/$2"

HTH,