Docker 代理和换源

代理

参见: 令人头疼的 docker 代理问题,我整理了解决方法和验证方案 | 阿森毛不多

Docker Daemon 代理

在使用 docker pull 命令时,docker daemon 会从 https://registry-1.docker.io/v2/ 下载镜像。然而这个网址被墙了,所以会下载失败,因此需要为 docker daemon 配置代理。

官方文档提到 docker daemon 在启动时会读取 HTTP_PROXY 等环境变量并自动设置代理,然而在我实际使用的过程中并没有体会到这一点。

除了设置环境变量以外,还有两种方法设置 docker daemon 代理。一种是修改 daemon.json 配置文件,另一种是修改 systemd 单元文件。

daemon 配置文件

  • 对于 Docker Desktop,配置文件为 Settings > Docker Engine
  • 对于 Docker Engine,配置文件为 /etc/docker/daemon.json
  • 对于 rootless mode 的 Docker Engine,配置文件为 ~/.config/docker/daemon.json
{
  "proxies": {
    "http-proxy": "http://127.0.0.1:7890",
    "https-proxy": "http://127.0.0.1:7890",
    "no-proxy": "127.0.0.1,::1,localhost,.local,.lan"
  }
}

接下来,重启 docker 服务:

# Docker Engine
sudo systemctl restart docker

# Rootless Mode
systemctl --user restart docker

验证配置已加载:

$ docker info | grep -A 2 "HTTP Proxy"
 HTTP Proxy: http://127.0.0.1:7890
 HTTPS Proxy: http://127.0.0.1:7890
 No Proxy: localhost,127.0.0.0/8,::1,.local

systemd 单元文件

  • 对于 Docker Engine,单元文件在 /etc/systemd/system/docker.service.d 目录下。
  • 对于 rootless mode 的 Docker Engine,单元文件在 ~/.config/systemd/user/docker.service.d 目录下。

创建一个 http-proxy.conf 文件:

[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.0/8"

重启 docker daemon:

# Docker Engine
sudo systemctl daemon-reload
sudo systemctl restart docker

# Rootless Mode
systemctl --user daemon-reload
systemctl --user restart docker

验证配置已加载:

# Docker Engine
sudo systemctl show --property=Environment docker

# Rootless Mode
systemctl --user show --property=Environment docker

参考:Daemon proxy configuration | Docker Docs

Docker Build 代理

在宿主机设置环境变量即可:

export http_proxy="http://127.0.0.1:7890" https_proxy="http://127.0.0.1:7890" all_proxy="socks5://127.0.0.1:7890"

Docker Container 代理

在容器中设置环境变量:

docker run \
  -e http_proxy="http://host.docker.internal:7890" \
  -e https_proxy="http://host.docker.internal:7890" \
  <image>

host.docker.internal 是宿主机在容器中的默认域名。

换源

  • ⚠️ 自 2024-06-06 开始,国内的 Docker Hub 镜像源相继停止服务。请选择为 Docker 守护程序配置代理。
  • 也可以尝试毫秒镜像
  • 对于 Docker Desktop,配置文件在 Settings > Docker Engine
  • 对于 Docker Engine,配置文件在 /etc/docker/daemon.json
  • 对于 rootless mode 的 Docker Engine,配置文件在 ~/.config/docker/daemon.json

例如,对于 Docker Desktop,需要在 Settings > Docker Engine 中添加如下内容:

{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn",
    "http://hub-mirror.c.163.com"
  ]
}

别忘了在上一个条目的末尾加上逗号 , 以保证 JSON 格式正确。

⚠️ 注意:错误的配置项会导致 Docker 无法启动。如果 Docker 无法启动,请在 Docker 后台图标上右键 > Troubleshoot > Reset to factory defaults

修改完成后的配置如下:

image

重启 Docker:

sudo systemctl restart docker

检查设置是否生效:

$ docker info | grep -A 5 'Registry Mirrors'
 Registry Mirrors:
  https://docker.1ms.run/
  https://registry.docker-cn.com/
  https://docker.mirrors.ustc.edu.cn/
  http://hub-mirror.c.163.com/
  ...

看到 Registry Mirrors 条目下有我们设置的镜像源,说明镜像设置成功了。


镜像源参考:镜像加速器 | Docker 从入门到实践 - yeasy

镜像源测速脚本:Docker-Mirror-Benchmark | GitHub

已知不可用镜像:

参见:

Troubleshooting

Rootless mode 下的 docker daemon 无法使用 127.0.0.1 代理

$ docker pull hello-world:latest
Error response from daemon: Get "https://registry-1.docker.io/v2/": proxyconnect tcp: dial tcp 127.0.0.1:7890: connect: connection refused

问题原因:rootless mode 下的 docker daemon 会创建用户网络命名空间,该网络命名空间下的 lo 接口与宿主网络命名空间下的 lo 接口相互独立。当你指定 127.0.0.1 作为代理服务器时,实际是指定了用户网络命名空间下的 lo 接口作为代理地址,而实际的代理服务监听在宿主网络命名空间下的 lo 接口,因此会导致 docker daemon 无法连接到代理。

解决方法:使用 docker daemon 用户网络命名空间能访问的宿主接口作为代理地址,比如宿主机的局域网地址 192.168.x.x。具体方法如下:

  1. 清理普通模式下的守护程序和网桥:

    # 停止可能正在运行的普通模式 docker daemon
    sudo systemctl stop docker
    # 删除普通模式下创建的 docker0 网桥
    sudo ip link del docker0
    
  2. 设置 rootless mode docker daemon 代理:

    vim ~/.config/docker/daemon.json
    
    {
      "proxies": {
        "http-proxy": "http://192.168.x.x:7890",
        "https-proxy": "http://192.168.x.x:7890",
        "no-proxy": "localhost,127.0.0.0/8,::1,.local"
      }
    }
    
  3. 重启 docker daemon:

    systemctl --user restart docker
    
  4. 测试网络连通性:

    docker pull hello-world:latest
    
posted @ 2024-01-19 22:45  Undefined443  阅读(4860)  评论(0)    收藏  举报