起因

卸载了上次在C盘安装的 docker ,这次在非C盘安装了 docker(教程可参考Windows 11 下正确安装 Docker Desktop 到 D 盘的完整教程),发现 docker pull 报错。

无论是否打开电脑上的代理软件,进行 docker pull 时,都会有关键词proxyconnect tcp: dial tcp 127.0.0.1:7890: connect: connection refused

> docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: failed to resolve reference "docker.io/library/hello-world:latest": failed to do request: Head "https://cnb.cool/Anyexyz/cdm/docker-mirror/v2/library/hello-world/manifests/latest?ns=docker.io": proxyconnect tcp: dial tcp 127.0.0.1:7890: connect: connection refused

排错

所以排除镜像问题(那应该报错443),看来是proxy设置问题。

检查docker desktopsettings -> resources -> proxies、检查C:/Users/Yourname/.docker/config.json,均确保没有设置proxy。但是我发现docker info输出了这个:

> docker info
HTTP Proxy: http://127.0.0.1:7890
HTTPS Proxy: http://127.0.0.1:7890
No Proxy: 127.0.0.1,192.168.,172.31.,172.30.,172.29.,172.28.,172.27.,172.26.,172.25.,172.24.,172.23.,172.22.,172.21.,172.20.,172.19.,172.18.,172.17.,172.16.,10.,127.*,localhost,<local>

那就奇怪了。初步判断是我上次在c盘的安装没删干净,或者我安装在别的盘的方法有疏漏。

最终修复 :

经过多次尝试,发现解决问题的方法:

  1. (临时方法)打开 Docker 配置文件:C:\ProgramData\Docker\config\daemon.jsonC:\Users\YourName\.docker\daemon.json,其中后者更加关键 ,如果文件不存在(确实,我连这几个文件夹都没有),可以手动创建一个新的 daemon.json 文件。然后,在 daemon.json 文件中添加或修改 DNS 配置、proxy配置,例如下文,并且请确保 JSON 格式正确。设置结束后,docker info查看当前proxy是否正确设置。
{
  "dns": ["8.8.8.8", "1.1.1.1"],
  "proxies": {
    "default": {
      "httpProxy": "",
      "httpsProxy": "",
      "noProxy": ""
    }
  }
}

docker info的合理结果:

 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal

C:\Users\YourName\AppData\Roaming\Docker\settings-store.json 这个文件里应该也能够查看到正确的内容。(No Proxy那一行换成了: "OverrideProxyExclude": "localhost,127.0.0.1"

  1. (主要的解决方法)如果还不行,依然是打开docker desktop的界面,在设置-Docker Engine中填写下述内容,并且重启docker,重启的时候记得先关闭自己电脑上的代理!!:
{
  "dns": ["8.8.8.8", "1.1.1.1"],
  "proxies": {
    "default": {
      "httpProxy": "http.docker.internal:3128",
      "httpsProxy": "http.docker.internal:3128",
      "noProxy": "hubproxy.docker.internal"
    }
  }
}
  1. (临时)如果还不行,依然是打开docker desktop的界面,在设置-Docker Engine中填写下述内容:(尽管是错的,但它似乎可以起到刷新作用),并且重启docker,重启的时候记得先关闭自己电脑上的代理!!:
{
  "dns": ["8.8.8.8", "1.1.1.1"],
  "proxies": {
    "default": {
      "httpProxy": "http://127.0.0.1:1234",
      "httpsProxy": "http://127.0.0.1:1234",
      "noProxy": ""
    }
  }
}

作用解析:

1. Docker Desktop 的内部代理机制

Docker Desktop 在 Windows 和 macOS 上有一个内部代理机制,即使你没有配置代理,Docker Desktop 本身也会配置一个默认的内部代理地址(如 http.docker.internal:3128)。这个地址是 Docker Desktop 内部的虚拟网络接口,用于处理网络通信。

  • http.docker.internal 是一个特殊的内部域名,指向 Docker Desktop 的网络接口。
  • 当 Docker Desktop 检测到你的环境变量中设置了代理(如 HTTP_PROXYHTTPS_PROXY),或者 Docker Desktop 设置中配置了代理,它会使用这些信息来转发网络请求。
  • 如果没有显式设置代理,Docker Desktop 的内部代理会自动尝试直接连接到外部网络。

因此,即使你没有手动配置代理,Docker Desktop 仍然通过内部代理机制(http.docker.internal)来处理网络流量。

2. DNS 的作用

为什么 DNS 解析可能会导致问题?

  • 当你执行 docker pull 时,Docker 需要解析镜像仓库的域名(如 registry-1.docker.io)。
  • 如果系统的 DNS 设置不稳定或被代理工具修改,可能会导致解析失败。
  • 通过在 daemon.json 中显式指定公共 DNS(如 Google 的 8.8.8.8 或 Cloudflare 的 1.1.1.1),确保 Docker 使用这些 DNS 服务器来解析域名,绕过了本地系统的 DNS 设置。

DNS 配置与代理的关系

  • 即使 Docker Desktop 使用了内部代理,代理仍然需要正确解析域名才能正常工作。
  • 添加 DNS 让 Docker 的网络堆栈变得更稳定,确保代理可以正常解析域名并转发请求。

3. No Proxy 的作用

在你的 docker info 输出中显示了以下 No Proxy 配置:

No Proxy: hubproxy.docker.internal

这意味着对于 hubproxy.docker.internal 这样的内部地址,Docker Desktop 会绕过代理直接连接。这种设置通常是为了确保 Docker Desktop 的内部组件通信不受代理干扰。

  • hubproxy.docker.internal 是 Docker Desktop 的内部组件,用于与 Docker Hub 等外部镜像仓库通信。
  • 通过指定 No Proxy,Docker Desktop 确保了内部组件通信的稳定性,即使代理配置存在问题,也不会影响正常工作。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐