TL; DR:主機名必須在第一個/
之前包含.
dns分隔符或:
端口分隔符,否則代碼假定您需要默認註冊表。
後一些通過代碼挖掘,我碰到distribution/reference/reference.go想出了以下內容:
// Grammar
//
// reference := name [ ":" tag ] [ "@" digest ]
// name := [hostname '/'] component ['/' component]*
// hostname := hostcomponent ['.' hostcomponent]* [':' port-number]
// hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
// port-number := /[0-9]+/
// component := alpha-numeric [separator alpha-numeric]*
// alpha-numeric := /[a-z0-9]+/
// separator := /[_.]|__|[-]*/
//
// tag := /[\w][\w.-]{0,127}/
//
// digest := digest-algorithm ":" digest-hex
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
// digest-algorithm-separator := /[+.-_]/
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
實際執行的是通過在distribution/reference/regexp.go一個正則表達式。
但是有些挖掘和戳動,我發現除了那個正則表達式還有另外一個檢查(如果你不包括.
或:
,你會得到一個大寫主機名的錯誤)。我找到了名稱爲以下實際分割中docker/reference.go:
func splitHostname(name string) (hostname, remoteName string) {
i := strings.IndexRune(name, '/')
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
hostname, remoteName = DefaultHostname, name
} else {
hostname, remoteName = name[:i], name[i+1:]
}
if hostname == LegacyDefaultHostname {
hostname = DefaultHostname
}
if hostname == DefaultHostname && !strings.ContainsRune(remoteName, '/') {
remoteName = DefaultRepoPrefix + remoteName
}
return
}
那對我來說最重要的部分是在第一個if語句爲.
和:
檢查第一/
之前。使用它,主機名將從第一個/
之前拆分出來,如果沒有它,則會將整個名稱傳遞給默認的註冊表主機名。
根據圖像符合規範的標籤被限制在127個字符。所以我認爲標籤正則表達式應該是/[\w][\w.-]{0,126}/ –
正則表達式的長度是0到127個字符,所以我認爲是正確的。如果沒有,那麼這將是一個公關改變這個:https://github.com/docker/distribution/blob/master/reference/regexp.go#L37 – BMitch
這是我的方式......正則表達式開始[/ w] [\ w.-] {0,127}並且沒有|在。。之間 [ ]。所以這意味着匹配a/w,然後匹配127 \ w或點或連字符。在Ruby的irb中嘗試/^([\w][\w.-]{0,4}$$.match('ssss-')確認5個字符被消耗... –