コンテナイメージの名前について調べたメモ
はじめに
コンテナイメージの名前について、厳密の考えると色々ややこしいので、調べてまとめてみようと思った。 しかし、泥臭い変換や補完があったりして、キレイにはまとまらず。 ただ、せっかく調べたのでメモは残しておく。
環境
Docker CLIを前提として、主に最新のドキュメントとソースコードを中心に情報を収集した。 Podman等の別のコンテナ実装や、KubernetesのようなPaaS上でコンテナを扱うときは、異なる仕様/挙動になるかもしれない。 コマンドラインでの試行や設定ファイルの確認は、以下の環境で実施している。
$ cat /etc/os-release | grep PRETTY_NAME PRETTY_NAME="Ubuntu 20.04.3 LTS" $ docker --version Docker version 20.10.8, build 3967b7d
コンテナイメージの名前の構成要素
「コンテナイメージの名前」と書いてみたものの、正しい表現かどうかはよく分からない。 「イメージ名(image name)」と呼ばれることが多い気がするが、文脈によっては誤解しそうなので、ここではあえて「コンテナイメージの名前」と表記しておくことにする。 また、Docker CLIのソースコードの中では「リファレンス(reference)」と呼ばれているようだ。
コンテナイメージの名前のフォーマットは、ざっくりとは以下のような感じ。
hostname:1234/path/name:1.0.0 \___________/ \_______/ \___/ ドメイン パス タグ \_____________________/ リポジトリ
ドメインは省略可能で、省略した場合はDocker CLIだとregistry-1.docker.io
になるようだ。
個人的な感覚としては、「ドメイン」というよりは、Container Registryの「APIサーバ」という表現の方が、名が体を表しているように思う。
以下に、リポジトリとタグの例として、docker image ls
の結果を挙げておく。
表示された表の1行目がリポジトリ、2行目がタグであることが分かる。
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest d1165f221234 6 months ago 13.3kB quay.io/centos/centos latest 300e315adb2f 9 months ago 209MB
なお、コンテナイメージの名前の正確なフォーマット(文法)は、ソースコード中のコメントより、以下の通り。 この文法の中では「リファレンス」と呼ばれている。
// Grammar // // reference := name [ ":" tag ] [ "@" digest ] // name := [domain '/'] path-component ['/' path-component]* // domain := domain-component ['.' domain-component]* [':' port-number] // domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ // port-number := /[0-9]+/ // path-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 // // identifier := /[a-f0-9]{64}/ // short-identifier := /[a-f0-9]{6,64}/
少々気になるのが、文法的にdomain
とpath-component
の区別に曖昧さがあり、このままだと「path-component
のつもりで書いたのにdomain
と解釈された」ということが起こりそうだということ。
推測だが、どこかで「パーサがdomain
と解釈したけど、本当にドメイン(=APIサーバ)なの?」という追加の検査をしていそうに思える。
ドメインの省略について
先ほど「省略した場合はDocker CLIだとregistry-1.docker.io
になるようだ」と書いたが、これはドキュメントから引っ張ってきた情報である。
しかし実際には、ドメインを省略した場合の、ドメインの決定方法は設定によって変更できるようだ。
例えば、調査した環境では、/etc/containers/registries.conf
というファイルに、省略したドメインを補完するための設定情報がある。
(略) # # An array of host[:port] registries to try when pulling an unqualified image, in order. unqualified-search-registries = ["docker.io", "quay.io"] (略)
また、コンテナイメージの名前にエイリアスをつけることができるようであり、これを利用して補完(というかマッピング)することもできる。
調査した環境では、エイリアスは/etc/containers/registries.conf.d/000-shortnames.conf
で定義されていたので、その一部を以下に示しておく。
[aliases] # centos "centos" = "quay.io/centos/centos" # containers "skopeo" = "quay.io/skopeo/stable" "buildah" = "quay.io/buildah/stable" "podman" = "quay.io/podman/stable" # docker "alpine" = "docker.io/library/alpine" "docker" = "docker.io/library/docker" "registry" = "docker.io/library/registry" "hello-world" = "docker.io/library/hello-world" "swarm" = "docker.io/library/swarm" # Fedora "fedora-minimal" = "registry.fedoraproject.org/fedora-minimal" "fedora" = "registry.fedoraproject.org/fedora" (以下略)
特別なパスlibrary/
DockerHub公認のコンテナイメージは特別扱いされており、パスがlibrary/
で始まる。
例えば、上記のエイリアスの中にも含まれているが、docker.io/library/hello-world
等がそれにあたる。
具体的な処理内容までは追いきれていないが、ソースコード中に、パスのプレフィックスがlibrary/
かどうかで条件分岐している処理が数カ所確認できた。
参考
Docker Docs > ReferenceCommand-line > docker tag
- https://docs.docker.com/engine/reference/commandline/tag/
- ドメイン省略時に
registry-1.docker.io
を付与することへの言及あり
コンテナイメージの配布(distribution)に関するOSSのソースコード
- https://github.com/distribution/distribution/tree/main/reference
- コンテナイメージの名前のパーサや文法のドキュメント(コメント)がある
-
- https://github.com/docker/cli
- 上記のdistributionを内部で利用している
Docker Registry HTTP API V2
- https://docs.docker.com/registry/spec/api/
- ドメインへはこのAPIを利用してアクセスすると思われる