背景
关于registry的基本知识已经了解差不多了,现在开始搭建一个可用的私有registry
架构
就采用钟成提到的架构
进展1
搭建了registry+front,配置了https
折腾一天,累成狗了,不详细写拉。直接看代码吧,都写成脚本和compose了
https://github.com/CodeJuan/private_registry
进展2:registry集群
实现了负载均衡
用的是nginx1.9的镜像
https://github.com/CodeJuan/private_registry/commit/7233fbf7def7b32daccc065f6ef546b234606e0d
进展3:后端存储
后端存储采用的是某共享存储技术,所有的registry都访问同一个存储集群,路径都一样
进展4:mirror
If you have multiple instances of Docker running in your environment (e.g., multiple physical or virtual machines, all running the Docker daemon), each time one of them requires an image that it doesn’t have it will go out to the internet and fetch it from the public Docker registry. By running a local registry mirror, you can keep most of the redundant image fetch traffic on your local network.
1 | mirror: |
第一次pull
1 | docker pull django |
mirror log1
2
3
4
5
6time="2016-01-22T13:15:27Z" level=info msg="response completed" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=884f518d-f69c-4d7d-8189-0afb70d1f351 http.request.method=GET http.request.remoteaddr="192.168.1.245:54369" http.request.uri="//v2/" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.duration="142.245µs" http.response.status=301 http.response.written=0 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:15:27 +0000] "GET //v2/ HTTP/1.1" 301 0 "" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
time="2016-01-22T13:15:27Z" level=info msg="response completed" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=d38c459d-b0e8-4e40-9991-537999b206ca http.request.method=GET http.request.referer="http://docker-hub.mymirror.com:5555//v2/" http.request.remoteaddr="192.168.1.245:54370" http.request.uri="/v2/" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=4.311715ms http.response.status=200 http.response.written=2 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:15:27 +0000] "GET /v2/ HTTP/1.1" 200 2 "http://docker-hub.mymirror.com:5555//v2/" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
time="2016-01-22T13:15:27Z" level=error msg="response completed with error" err.code="MANIFEST_UNKNOWN" err.detail="unknown manifest name=library/django tag=latest" err.message="manifest unknown" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=6c236f9c-53e9-4f4a-b61a-bf90e61c4c95 http.request.method=GET http.request.remoteaddr="192.168.1.245:54371" http.request.uri="/v2/library/django/manifests/latest" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=4.919044ms http.response.status=404 http.response.written=120 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 vars.name="library/django" vars.reference=latest version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:15:27 +0000] "GET /v2/library/django/manifests/latest HTTP/1.1" 404 120 "" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
rmi django再次pull
1 | docker pull django |
时间还变长了
mirror log1
2
3
4
5
6time="2016-01-22T13:36:29Z" level=info msg="response completed" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=5317fae0-9ead-4bc4-a016-3df313f7873a http.request.method=GET http.request.remoteaddr="192.168.1.245:54431" http.request.uri="//v2/" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.duration="126.687µs" http.response.status=301 http.response.written=0 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:36:29 +0000] "GET //v2/ HTTP/1.1" 301 0 "" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
time="2016-01-22T13:36:29Z" level=info msg="response completed" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=86ed3aa8-a2ec-4b88-8a28-adcd4780ef78 http.request.method=GET http.request.referer="http://docker-hub.mymirror.com:5555//v2/" http.request.remoteaddr="192.168.1.245:54432" http.request.uri="/v2/" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=4.279031ms http.response.status=200 http.response.written=2 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:36:29 +0000] "GET /v2/ HTTP/1.1" 200 2 "http://docker-hub.mymirror.com:5555//v2/" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
time="2016-01-22T13:36:29Z" level=error msg="response completed with error" err.code="MANIFEST_UNKNOWN" err.detail="unknown manifest name=library/django tag=latest" err.message="manifest unknown" go.version=go1.5.2 http.request.host="docker-hub.mymirror.com:5555" http.request.id=2097bff1-98f8-443b-9e6d-9c4b93d0c87f http.request.method=GET http.request.remoteaddr="192.168.1.245:54433" http.request.uri="/v2/library/django/manifests/latest" http.request.useragent="docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=4.300812ms http.response.status=404 http.response.written=120 instance.id=3d1817be-d0b8-4c98-8560-fe88c5039957 vars.name="library/django" vars.reference=latest version=v2.2.1
192.168.1.245 - - [22/Jan/2016:13:36:29 +0000] "GET /v2/library/django/manifests/latest HTTP/1.1" 404 120 "" "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/3.19.0-25-generic os/linux arch/amd64"
奇怪
更新,搞定了,原因是在compose里写环境变量不管用,等在config.yml里加上proxy,参见
https://github.com/CodeJuan/private_registry/blob/master/mirror_config.yml
进展5:调通删除镜像API
I sent the same request with @adolphlwq ‘s request, and got the same response1
2
3curl -v -X DELETE http://myregistry/v2/busybox/manifests/sha256:blablabla...
{"errors":[{"code":"UNSUPPORTED","message":"The operation is unsupported."}]}
update
I got the solution to delete images
enable delete
set the environment variable REGISTRY_STORAGE_DELETE_ENABLED = True
the API to delete image
- get the manifest from registry
1
get v2/<repoName>/manifests/<tagName>
the Docker-Content-Digest
is response.Header[“Docker-Content-Digest”]
the layerDigests
is response.body[“fsLayers”][“blobSum”]
delete layerDigests
1
delete v2/<repoName>/blobs/<layerDigests>
delete Docker-Content-Digest
1
delete v2/<repoName>/manifests/<Docker-Content-Digest>
then pull the image from registry, the response is
invalid character '<' looking for beginning of value
But when I get ‘v2/repoName/tags/list’, the tag which was been deleted is still exist…….
参考
关于私有安全docker registry的实验
搭建Docker私有仓库Registry-v2
本博客欢迎转发,但请保留原作者信息
github:codejuan
博客地址:http://blog.decbug.com/