2016-06-16 10 views
6

docker pushを実行するとき、または画像をプルするときに、画像名にレジストリサーバがあるかどうか、またはデフォルトのレジストリ(Docker Hubなど)のパス/ユーザ名がDockerによってどのように判断されますか?ドッカーイメージ名はどのように解析されますか?

私は1.1 image specから次のことを見ている:

タグ

は、タグは任意の単一のイメージ IDに記述、ユーザーが指定した名前をマッピングするのに役立ちます。タグ値は文字セット[a-zA-Z_0-9]に制限されています。

リポジトリ

:)の前に共通のプレフィックス(名前コンポーネント の下にグループ化されたタグのコレクション。たとえば、my-app:3.1.4という名前でタグ付けされた画像では、 my-appは名前のリポジトリコンポーネントです。リポジトリ名は、スラッシュで区切られた名前コンポーネントで構成された で、オプションで接頭辞は のDNSホスト名です。ホスト名は、標準DNS規則の に従う必要がありますが、_文字は使用できません。ホスト名が存在する場合は、 の後にオプションで8080の形式のポート番号を続けることができます。名前 には、小文字、数字、および区切り文字を使用できます。 A セパレータは、ピリオド、1つまたは2つのアンダースコア、または1つまたは のダッシュとして定義されます。名前コンポーネントはセパレータで開始または終了できません。

DNSホスト名の場合はドットで完全修飾する必要がありますか、「my-local-server」は有効なレジストリホスト名ですか?名前のコンポーネントについては、ピリオドが有効であることがわかります。これは、「team.user/appserver」が有効なイメージ名であることを意味します。レジストリサーバがポート80で動作しているため、イメージ名のホスト名にポート番号が必要ない場合は、ホスト名とレジストリサーバのパスのあいまいさがあるようです。私はDockerがそのあいまいさをどのように解決するのか不思議です。

答えて

3

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に次に名前の実際の分割を突き止め:if文

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 
} 

私のためにそれの重要な部分は、最初の最初の/.:ためのチェックです。これにより、ホスト名は最初の/より前に分割され、それがなければ、名前全体がデフォルトのレジストリ・ホスト名に渡されます。

+0

です。だから私は、タグの正規表現は/[\w][\w.-]{0,126}/ –

+0

でなければならないと思う正規表現の長さは0から127文字ですので、そうだと思います。そうでなければ、それはこれを変更するためのPRになります:https://github.com/docker/distribution/blob/master/reference/regexp.go#L37 – BMitch

+0

これは私がそれを理解する方法です....正規表現が始まります[/w][\w.-]{0,127}であり、|間に [ ]。だからそれはa/wにマッチすることを意味し、127 \ wまたはドットやハイフンにマッチします。 Rubyのirbに/by([\w][\w.-]{0,4})$/.match('ssss- ')を入力すると、その5文字が消費されることが確認されます。 –

0

https://github.com/moby/moby/blob/master/image/spec/v1.1.mdの画像仕様が更新され、タグは128文字に制限されています。

PRスレッドがいくつかのRubyコードはここhttps://github.com/cyber-dojo/runner/blob/master/server/src/valid_image_name.rb

あり、ここでhttps://github.com/docker/distribution/issues/2248

であるいくつかのRubyのテストは画像仕様に従ってタグ127文字に制限され、ここでhttps://github.com/cyber-dojo/runner/blob/master/server/test/src/valid_image_name_test.rb

関連する問題