VPN 経由の docker pull:デーモンは独自のネットワークを持つ
プルはシェルではなくデーモンの中で実行されます。コンテキストを確認し、そのエンジンに独自の経路かプロキシを与え、どのレジストリとのやり取りが終わったのかを読み取ってください。
ノートPCは社内 VPN につながっており、curl は内部レジストリに到達するのに、docker pull は依然として EOF で失敗します。この組み合わせは矛盾ではありません。入力したコマンドはシェルで実行されますが、転送は Docker CLI が選択したデーモンの中で実行され、そのデーモンはまったく別のホストにある可能性があります。動作すべきなのはそのデーモンのネットワーク経路であり、適用されるのはそのデーモンのプロキシ設定です。
経路ではなくエンジンを特定するところから始める
docker context show と docker version を実行します。バージョンの出力はクライアントのセクションとサーバーのセクションを表示し、サーバーのブロックが何が応答したかを教えてくれます。ローカルのネイティブエンジン、Docker Desktop の仮想マシン、あるいはリモートマシン上のデーモンです。確実にしたい場合は docker context inspect が選択中のコンテキストのエンドポイントを表示し、これらのコマンドはいずれも何も変更しません。
DOCKER_HOST のような環境変数は、想定しているのとは別のエンジンに CLI を黙って向けることがあり、VPN 上にいるように見えるノートPCでプルが別の場所へ流れる場合の典型的な説明になります。
デーモンには独自のネットワーク識別がある
リモートのエンジンには、プライベートレジストリへの独自の承認済み経路が必要です。ノートPCの VPN クライアントを接続しても、そのノートPCに経路ができるだけで、実験室やクラウドのサブネットにあるデーモンに同じプライベートアドレスが与えられるわけではありません。エンジンが Docker Desktop の場合、プルはその仮想マシンの中で行われ、仮想マシンはシェルの環境とは別の独自のネットワークとプロキシの設定を持っています。
だからこそ、ホスト上で成功した curl はホストに関する証拠にすぎません。
どのレジストリとのやり取りが終わったのかを突き止める
イメージのプルは一連の流れです。認証、マニフェストの取得、そして多くの場合オブジェクトストレージや CDN のエンドポイントへリダイレクトされる blob の転送が続きます。docker login の成功が証明するのは最初の段階だけで、リダイレクト先の blob ホストにデーモンのネットワークから到達できなければ、トークンは完全に有効なままでも失敗します。何かを変える前に、正確な時刻、イメージ参照、デーモンまたはクライアントのログにある最初の有用なイベントを記録してください。
EOF だけでは原因は特定できません。切断された接続、ストリームを落としたプロキシ、タイムアウト、MTU の問題のいずれかであり、時刻付きのイベントなしにそれらを推測することが、健全なエンジンを再構築してしまう原因になります。クライアント出力のバイトオフセットをデータとして扱ってください。毎回同じサイズで止まる転送は、まったく始まらない転送とは別物です。両方の結果を記録し、試行間で比較してください。
転送を行うコンポーネントを設定する
ネイティブの Linux エンジンでは、プロキシはシェルではなくサービスの環境に置きます。/etc/systemd/system/docker.service.d/ の下に HTTP_PROXY、HTTPS_PROXY、NO_PROXY のエントリを持つ drop-in ファイルを置き、続けて systemctl daemon-reload と再起動を行うのが文書化された方法です。Docker Desktop は同じ値を独自の設定で公開しており、シェルのプロファイルを編集してもどちらにも影響しません。
レジストリに VPN 経由で直接到達する必要がある場合、デーモンにはリゾルバー、経路、そして意図的なプロキシ除外が必要で、除外だけでは足りません。NO_PROXY の照合はコンポーネントごとの文字列比較であり、下になる経路のない除外はプロキシの問題のように見える障害を生みます。
企業の TLS 検査が承認済みの経路にある場合は、エンジンまたは Desktop のワークフローを通じて検証済みのルートをインストールします。レジストリを insecure-registries に追加するのは検証を無効にする別の変更であり、トラストストアの設定ではありません。
管理されたプルを一度繰り返し、何が変わったかを確認する
境界を一つ変え、それを所有するコンポーネントを再起動し、同じコンテキストから同じプルを繰り返します。エラーがないことではなく、得られたイメージ参照と digest を検証してください。キャッシュされたレイヤーのせいで、二回目の試行は一回目よりはるかに短い経路しか通らないことがあります。実際に行われた転送をチケットに残してください。再試行が本当に何を試したのかを示す唯一の記録だからです。
ビルドの手順と実行中のコンテナには独自のネットワークコンテキストがあるため、プル自体が動くようになったら別の問いとして扱ってください。