2016-06-16 39 views
6

Quando si esegue uno docker push o quando si tira un'immagine, in che modo Docker determina se esiste un server del registro nel nome dell'immagine o se si tratta di un percorso/nome utente nel registro predefinito (ad esempio Docker Hub)?Come vengono analizzati i nomi delle immagini della finestra mobile?

sto vedendo quanto segue dal 1.1 image spec:

Tag

Un tag serve per mappare un nome descrittivo, user-data ad ogni singola immagine ID. I valori di tag sono limitati al set di caratteri [a-zA-Z_0-9].

Repository

Una collezione di etichette raggruppate sotto un prefisso comune (la componente del nome prima :). Ad esempio, in un'immagine taggata con il nome my-app: 3.1.4, my-app è il componente Repository del nome. Il nome del repository è costituito da componenti del nome separati da barre, eventualmente preceduti da un nome host DNS . Il nome host deve essere conforme alle regole DNS standard, ma non può contenere _ caratteri. Se è presente un nome host, è possibile che sia seguito facoltativamente da un numero di porta nel formato: 8080. I componenti del nome possono contenere caratteri minuscoli, cifre e separatori. Un separatore è definito come un punto, uno o due caratteri di sottolineatura o uno o più trattini. Un componente nome non può iniziare o terminare con un separatore.

Per il nome host DNS, è necessario essere pienamente qualificato con punti oppure "my-local-server" è un nome host del registro valido? Per i componenti del nome, vedo periodi come validi, il che implica che "team.user/appserver" è un nome immagine valido. Se il server del registro è in esecuzione sulla porta 80 e quindi non è necessario alcun numero di porta sul nome host nel nome dell'immagine, sembra che ci sarebbe un'ambiguità tra il nome host e il percorso sul server del registro. Sono curioso di sapere come Docker risolve quell'ambiguità.

risposta

3

TL; DR: Il nome host deve contenere un separatore . DNS o un separatore : porto prima della prima /, altrimenti il ​​codice presuppone che si desidera che il Registro di sistema predefinito.


Dopo un po 'scavare attraverso il codice, mi sono imbattuto distribution/reference/reference.go con il seguente:

// 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 

L'effettiva attuazione del cioè tramite un'espressione regolare in distribution/reference/regexp.go.

Ma con alcuni scavi e frugando, ho scoperto che c'è un altro controllo oltre a quello regex (riceverai errori con un nome host in maiuscolo se non includi uno . o :). E ho rintracciato la spaccatura reale del nome al seguente in 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 
} 

La parte importante di questo per me è il controllo per il . e : prima del primo / nella prima istruzione if.Con esso, il nome host viene scomposto prima del primo / e, senza di esso, l'intero nome viene passato al nome host del registro predefinito.

+0

secondo l'immagine-spec il tag è limitato a 127 caratteri. Quindi penso che il tag regex dovrebbe essere /[\w][ww] {0,126}/ –

+0

La lunghezza regolare è da 0 a 127 caratteri, quindi penso che sia giusto. In caso contrario, questo sarebbe un PR per cambiare questo: https://github.com/docker/distribution/blob/master/reference/regexp.go#L37 – BMitch

+0

Ecco come lo immagino .... Comincia l'espressione regolare [/w][\w.-]{0,127} e non c'è | tra i [ ]. Quindi significa abbinare a/w e quindi abbinare fino a 127 \ w o punto o trattino. Provando /^([\w][ww-]{0,4})$/.match('ssss- ') in irb di Ruby conferma che quei 5 caratteri sono consumati ... –

Problemi correlati