エラーメッセージ
Error response from daemon: Get "https://registry.example.com:5000/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
レジストリのホストとポートは環境によって異なります。docker push、pull、login はいずれも「Error response from daemon: Get \"https://<registry>/v2/\": …」と報告します。イメージをプルする containerd、nerdctl、Podman、Kubernetes ノードも、同じ x509 のテキストに独自のプレフィックスを付けて出力します。
Docker Engine (dockerd) — docker pull / push / login against a registry with an untrusted certificate
このエラーの意味
Docker デーモン(docker CLI ではありません)がレジストリの API(/v2/)に接続しようとしましたが、その TLS 証明書を検証できませんでした。チェーンが、デーモンの信頼する CA にたどり着きません。dockerd が信頼するのは、ホストのシステム CA バンドルと、/etc/docker/certs.d/<registry>:<port>/ に配置したレジストリごとの CA です。よくある原因は、社内の証明書を使うプライベートレジストリと、TLS を検査するプロキシです。
発生する理由
プライベート証明書を使うセルフホストのレジストリ
よくある社内 CA や自作の CA が発行した証明書を使う Harbor、GitLab のレジストリ、Nexus、registry:2 が該当します。
Docker Hub などのレジストリの手前にある、TLS を検査するプロキシ
よくあるデーモンにはプロキシの証明書が見えています。そのルートがホストのストアになければ、すべてのプルが失敗します。
デーモンが参照しない場所に CA がインストールされている
ときどきデーモンが別の場所(Docker Desktop の VM、リモートの DOCKER_HOST、CI ランナー)で動いている場合、クライアントマシンのストアに CA をコピーしても効果はありません。certs.d のディレクトリ名は、レジストリのホストとポートに正確に一致していなければなりません。
レジストリが中間証明書を送信していない
ときどきGo(dockerd)は中間証明書を取得しません。リーフ証明書しか送信しないレジストリは、パブリック CA を使っていても失敗します。
修正方法
- 1.
このレジストリ用の CA を certs.d にインストールする
/etc/docker/certs.d/<host>:<port>/ca.crt はリクエストごとに読み込まれます。再現テストでは、追加した直後に docker login が成功しました。
bash # Trust the registry's CA for this registry only (no daemon restart needed) sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000 sudo cp corp-root-ca.pem /etc/docker/certs.d/registry.example.com:5000/ca.crt docker login registry.example.com:5000 - 2.
CA をシステム全体にインストールし、dockerd を再起動する
プロキシや多数のレジストリに対しては、ルートをホストのバンドルに追加してください。デーモンは起動時にこのバンドルを読み込みます。
bash # Or system-wide (proxy roots, many registries), then restart the daemon sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates sudo systemctl restart docker - 3.
Docker Desktop:ホストでルートを信頼する
Docker Desktop の VM は起動時にホスト OS から信頼済みのルートを取り込むため、ルートをホスト側にインストールしてから Docker Desktop を再起動してください。
text Docker Desktop: the daemon runs in a VM. Add the root to the host's trust store (macOS Keychain "System" with "Always Trust", Windows "Trusted Root Certification Authorities") and restart Docker Desktop; it imports trusted host roots into the VM. - 4.
レジストリのチェーンを確認する
リーフ証明書しか送信されていない場合は、レジストリまたはその前段のリバースプロキシに完全なチェーンを設定してください。
bash openssl s_client -connect registry.example.com:5000 -servername registry.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:'
関連するエラー
x509: certificate signed by unknown authorityGo crypto/x509tls: failed to verify certificate: x509: certificate signed by unknown authorityGo crypto/tls (Go ≥ 1.20)http: server gave HTTP response to HTTPS clientGo net/httpUnable to connect to the server: tls: failed to verify certificate: x509: certi…kubectl (client-go)