Skip to content

Instantly share code, notes, and snippets.

@makotom
Last active November 11, 2020 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save makotom/3e8ddec225f698afefd4f997025b6089 to your computer and use it in GitHub Desktop.
Save makotom/3e8ddec225f698afefd4f997025b6089 to your computer and use it in GitHub Desktop.
`registry-mirrors` は HTTPS でないと BuildKit が動作しないが治るらしい

registry-mirrors は HTTPS でないと BuildKit が動作しないが治るらしい

Docker の GitHub Issues のやりとりにいろいろ矛盾があるので, これはもしかして誰も気づいていないだけでいろいろぶっ壊れたままなのでは? と思って調べてみたら, どうやら 20.10 ですべて治るというのだけは本当らしい. 眠気が収まらない間片手間にやった調べものなので内容は不正確かもしれない.

Docker 19.03.13 でのはなし

  • BuildKit の ResolverOptions (レジストリ上にある既存のイメージを pull するときのオプション) は daemon.NewResolveOptionsFunc() により作られる.

    https://github.com/moby/moby/blob/v19.03.13/cmd/dockerd/daemon.go#L312

  • daemon.NewResolveOptionsFunc() は以下の順に動作する.

    https://github.com/moby/moby/blob/v19.03.13/daemon/daemon.go#L152-L204

    1. registry-mirrors が設定されている場合、 m["docker.io"].Mirrors にミラーの一覧を追加する.
    2. Pull するイメージがおかれているレジストリのホスト名 vinsecure-registries が設定されている場合, m[v] を初期化したうえで, m[v].PlainHTTPtrue にする.
    3. Pull するイメージがおかれているレジストリのホスト名 vhost に代入する. 明示的な指定がない場合, host にデフォルトのホスト名 docker.io を使用する.
    4. defResolverOptions として初期化. すべてのプロパティに nil を設定.
    5. m[host].Mirrors が空でない場合, m[host].Mirrors からひとつミラーをランダムに選択し, ミラーのホスト名を def.Host に代入.
    6. def.PlainHTTPm[host].PlainHTTP (デフォルトで nil) を代入.
    7. def を返す.
  • containerd で定義されている dockerResolver.base はイメージ名と ResolverOptions を受け取って以下の順に動作し API コールのための URL オブジェクト base を生成する.

    https://github.com/moby/moby/blob/v19.03.13/vendor/github.com/containerd/containerd/remotes/docker/resolver.go#L146-L148 https://github.com/moby/moby/blob/v19.03.13/vendor/github.com/containerd/containerd/remotes/docker/resolver.go#L365-L377

    1. Pull するイメージ名をパーズして得られたホスト名の部分を base.Host に設定する.
    2. ResolverOptionsHost が設定されている場合, その値を base.Host に設定する. (この時点で Host はミラーのホスト名になっていることに注目.)
    3. ResolverOptionsPlainHTTP が設定されている場合, base.Schemehttp に設定する. (PlainHTTP の値は上記 daemon.NewResolveOptionsFunc() に由来して docker.io の設定が使われる.)

したがって,

  • そもそも, BuildKit の世界ではミラーはランダムに選択される. (ふつうの docker pull とは挙動が異なる.)
  • insecure-registriesdocker.io を代入しない限り, ミラーへの通信が HTTP になることはない.
  • しかし, insecure-registriesdocker.io を代入すると, ミラーの設定がなかったことにされる. そのため, docker.io への通信が平文 HTTP で発生することになり, 結果エラーとなる.

実際に試してみると上記のような挙動になっている.

Docker 20.10-beta1 でのはなし

(以下の処理省略, ざっくりいうと out を前から順に走査してアクセスする. たぶんこのへん.)

したがって, 20.10 以降, insecure-registries にミラーの URL (http などのスキームも含む正規の URL である必要がある) を指定しておくことで, registry-mirrors に平文 HTTP なミラーを設定しても問題なく HTTP で通信できるようになるらしい.

なお, https://github.com/moby/moby/blob/v20.10.0-beta1/daemon/daemon.go#L172-L174 から, insecure-registries は 20.10 以降正規の URL を指定しないといけないと思う (この動作は 19.03 からの変更になる) が, これに関する言及はどこにもない気がするな...... あと引き続き insecure-registriesdocker.io とか指定するとよくわからない動作になるとみられる.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment