docker registry v2 配置 (REGISTRY_PROXY_REMOTEURL) 解釋 + docker pull/push 動作簡析

wiryywiryy 8年前發布 | 82K 次閱讀 Docker 操作系統 虛擬化

來自: http://dockone.io/article/1081

問題回顧

周末的時候,有個朋友在搭建docker registry v2版本( http://dockone.io/article/84 5)的時候遇到了一個問題:

問題描述:倉庫搭建完成后,login沒問題,但是push鏡像會一直在retry,直到超時。

docker push myregistry.com/ubuntu:0.0.1

The push refers to a repository [myregistry.com/ubuntu]

xxxxxxx: Retrying in 5 seconds

xxxxxxx: Retrying in 5 seconds 

unsupported

log:

time="2016-02-27T07:43:30Z" level=warning msg="error authorizing context: authorization token required" go.version=go1.5.3 http.request.host=myregistry.com http.request.id=cf177681-c67a-4ecf-ad9c-7055faaf3331 http.request.method=GET http.request.remoteaddr="192.168.159.136:51585" http.request.uri="/v2/" http.request.useragent="docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64" instance.id=b498d7d9-aaa1-4a16-9fb6-714447085964 version=v2.3.0

192.168.159.136 - - [27/Feb/2016:07:43:30  0000] "GET /v2/ HTTP/1.1" 401 87 "" "docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64"time="2016-02-27T07:43:30Z" level=error msg="response completed with error" auth.user.name=admin err.code=unsupported err.message="The operation is unsupported." go.version=go1.5.3 http.request.host=myregistry.com http.request.id=4a12623f-b8f4-4875-95ba-115eb375f6d5 http.request.method=POST http.request.remoteaddr="192.168.159.136:51587" http.request.uri="/v2/ubuntu/blobs/uploads/" http.request.useragent="docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=4.218218ms http.response.status=405 http.response.written=78 instance.id=b498d7d9-aaa1-4a16-9fb6-714447085964 vars.name=ubuntu version=v2.3.0

192.168.159.136 - - [27/Feb/2016:07:43:30  0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 405 78 "" "docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64"time="2016-02-27T07:43:30Z" level=error msg="response completed with error" auth.user.name=admin err.code=unsupported err.message="The operation is unsupported." go.version=go1.5.3 http.request.host=myregistry.com http.request.id=4c4fc4a9-9cdb-4ab7-a338-40d9da414dcf http.request.method=POST http.request.remoteaddr="192.168.159.136:51588" http.request.uri="/v2/ubuntu/blobs/uploads/" http.request.useragent="docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=73.057308ms http.response.status=405 http.response.written=78 instance.id=b498d7d9-aaa1-4a16-9fb6-714447085964 vars.name=ubuntu version=v2.3.0

192.168.159.136 - - [27/Feb/2016:07:43:30  0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 405 78 "" "docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64"time="2016-02-27T07:43:30Z" level=error msg="response completed with error" auth.user.name=admin err.code=unsupported err.message="The operation is unsupported." go.version=go1.5.3 http.request.host=myregistry.com http.request.id=92c9c5bd-8281-441f-a745-4dadc3e13693 http.request.method=POST http.request.remoteaddr="192.168.159.136:51590" http.request.uri="/v2/ubuntu/blobs/uploads/" http.request.useragent="docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=66.338973ms http.response.status=405 http.response.written=78 instance.id=b498d7d9-aaa1-4a16-9fb6-714447085964 vars.name=ubuntu version=v2.3.0

192.168.159.136 - - [27/Feb/2016:07:43:30  0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 405 78 "" "docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64"time="2016-02-27T07:43:30Z" level=error msg="response completed with error" auth.user.name=admin err.code=unsupported err.message="The operation is unsupported." go.version=go1.5.3 http.request.host=myregistry.com http.request.id=25cf49b8-99df-4d50-9f78-5ccc5d9e4bfc http.request.method=POST http.request.remoteaddr="192.168.159.136:51589" http.request.uri="/v2/ubuntu/blobs/uploads/" http.request.useragent="docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64" http.response.contenttype="application/json; charset=utf-8" http.response.duration=8.280863ms http.response.status=405 http.response.written=78 instance.id=b498d7d9-aaa1-4a16-9fb6-714447085964 vars.name=ubuntu version=v2.3.0

192.168.159.136 - - [27/Feb/2016:07:43:30  0000] "POST /v2/ubuntu/blobs/uploads/ HTTP/1.1" 405 78 "" "docker/1.10.2 go/go1.5.3 git-commit/c3959b1 kernel/3.13.0-24-generic os/linux arch/amd64"

啟動參數

docker run -d -p 5000:5000 -p 443:5000 --restart=always --name registry \

-v pwd/auth:/auth \

-v pwd/data:/var/lib/registry \

-e STANDALONE=false \

-e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \

-e REGISTRY_AUTH=token \

-e REGISTRY_AUTH_TOKEN_REALM=https://myregistry.com:5001/auth \

-e REGISTRY_AUTH_TOKEN_SERVICE="Docker registry" \

-e REGISTRY_AUTH_TOKEN_ISSUER="Acme auth server" \

-e REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/certs/domain.crt \

-v /root/auth_server/ssl:/ssl \

-v pwd/certs:/certs \

-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \

-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \

registry:2.2</pre>

過程

分析

1、大致問了下,如果不加認證,push是沒有問題的,所以先確定了裸registry是沒有問題的;

2、看了下參數,似乎沒什么特別的配置,覺得應該不會有啥問題(好尷尬);

3、看了下push的時候的報錯是個unsupported,好吧,報錯的似乎不知道為啥,像是異常沒獲取到,來了個通量的;

4、看了下日志,這算是一套push(認證 push)完整的流程,但是出現了"405 78" 的狀態,405權限問題,似乎有點頭緒了(這里被這種報錯誤影響了好久好久);

備注:auth server 可以參考開頭的連接中博客的認證服務,用的就是那個

實驗1

好了,405是個突破口了,似乎說明auth server那里出了點狀況,

1、于是乎手動調取了下auth server的API,token是可以拿到的,ok,auth server最起碼是理人的;

2、405權限吶,于是對著auth server的ACL文件是配了又配:

①:確定是否能用,我把admin的密碼改了,然后docker login 不進去,確保能讀取config

②:翻了下它的github,配置沒有問題呀,這里的測試過程省略1W字。

在這個地方一籌莫展,然后就去打LOL了,悲傷的時候必須緩解下。

實驗2

好了,隊友掛機,我又回來了。又把過程想了下,docker 既然可以給我報錯"unsupport",也許405也是錯的呢。然后決定詳細排查下啟動參數:

1、按照不加任何參數直接啟動,push沒問題,啟動也沒問題;

2、發現"STANDALONE"/"REGISTRY_PROXY_REMOTEURL"這2個參數無法判斷是否會影響;

3、加上token驗證(只加了相關的參數),發現push沒問題;

4、初步判斷可能和"STANDALONE"/"REGISTRY_PROXY_REMOTEURL"這2個參數有關;

5、最后確認和REGISTRY_PROXY_REMOTEURL有關

實驗3

按照參數的解釋STANDALONE應該是索引index的開關,但是貌似不會有太大關系,先忽略掉了(大家可以搜下這個參數的具體解釋,個人覺得這個參數在這里不影響(應該關掉false));

參數REGISTRY_PROXY_REMOTEURL意思是mirror模式,具體配置的為遠程docker倉庫,突然察覺到點什么:mirror模式下,docker倉庫在pull的時候會去驗證遠端HUB是否有相應的鏡像,然后緩存,難道push的時候也會?

具體的分析

docker push 代碼

https://github.com/docker/dock ... v2.go

49-59行有個大體解釋。

type pushState struct {

sync.Mutex

// remoteLayers is the set of layers known to exist on the remote side.

// This avoids redundant queries when pushing multiple tags that

// involve the same layers. It is also used to fill in digest and size

// information when building the manifest.

remoteLayers map[layer.DiffID]distribution.Descriptor

// confirmedV2 is set to true if we confirm we're talking to a v2

// registry. This is used to limit fallbacks to the v1 protocol.

confirmedV2 bool

}</pre>

這里只截取了一小段代碼,這里大概的意思是push的時候,會去對比遠端HUB是否有重復的layers。

因為設置參數的時候沒有加相應的用戶名密碼(這里在官方文檔中是確切要求必須添加用戶名密碼的 https://docs.docker.com/registry/mirror /),所以造成了這個過程一直在retry。然后是docker在這一塊處理的時候存在點問題,1是命令行拋了個"unsupported"報錯,2是log中405報錯有點尷尬,現在可以理解成到遠端倉庫中權限不足,但是log中應該不是很明確,但是似乎處理邏輯有些問題。

push過程分析

僅為個人理解:

(login過程省略)

1、docker client接收到push命令后,首先判斷命令是否完整;

2、確保命令完整后,索引到相應的鏡像文件,將image ID提取出來;

3、將image ID發送到倉庫中驗證是否有重復,從而處理增量上傳;

4、registry拿到image ID,先在本地驗證一次,然后到遠端HUB中驗證;

5、registry將驗證的結果發送到client,也就是代碼中的"pushState";

6、docker client根據pushState來進行上傳;

</div>

 本文由用戶 wiryywiryy 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!