细说 Docker Proxy 配置和误区
简介⌗
近期由于某种不可描述的原因,Docker 相关的服务被 Ban 了,不得已需要使用 Proxy 来拉取镜像或者构建镜像。但是在为 Docker 设置 Proxy 的时候有一些误区,如果没有仔细阅读官方文档,可能导致设置了 Proxy,但是依然无法拉取镜像!
最新情况:
截止 2024-09-10,Docker 的 Registry 已经陆续恢复访问了,但是 Docker Hub 已经无法正常访问!
架构⌗
在明确 Docker Proxy 如何设置之前,首先要了解 Docker 的整体架构,这样有助于理解为什么要分开设置多个代理。Docker 泛指整个工具链和生态,其由多个组件构成:
- Docker Daemon
- Docker Client
- Docker Builder
Docker Daemon⌗
当我们拉取镜像的时候本质上是通过 Docker Client 向 Docker Daemon 发送请求,由 Docker Daemon 执行拉取请求,当无法拉取镜像时需要给 Docker Daemon 配置 Proxy。
Docker Daemon 的配置文件所在位置如下:
- Linux 常规模式:
/etc/docker/daemon.json
- Linux Rootless 模式:
~/.config/docker/daemon.json
- Windows:
C:\ProgramData\docker\config\daemon.json
- macOS Docker Desktop:
~/.docker/config/daemon.json
- macOS OrbStack:
~/.orbstack/config/docker.json
{
"proxies": {
"no-proxy": "*.local,localhost,127.0.0.0/8",
"http-proxy": "http://IP_OR_DOMAIN:6152",
"https-proxy": "https://IP_OR_DOMAIN:6152",
}
}
Docker Daemon 并不支持
ALL_PROXY
或all-proxy
这个配置。
除了配置 daemon.json,我们还可以通过 Systemd 的服务配置来为 Docker Daemon 设置 Proxy:
sudo mkdir -p /etc/systemd/system/docker.service.d
touch /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf 文件内容如下:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=https://proxy.example.com:3129"
Environment="NO_PROXY=localhost,127.0.0.0/8"
Reload 服务配置并重启 Docker Daemon 服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
验证结果是否符合预期:
sudo systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://proxy.example.com:3128 HTTPS_PROXY=https://proxy.example.com:3129 NO_PROXY=localhost,127.0.0.0/8
Docker Client⌗
当我们要运行容器或者构建镜像时,需要用到 Proxy 的话,则需要设置 Docker Client 的 Proxy。
{
"proxies": {
"default": {
"noProxy": "*.test,localhost,127.0.0.0/8",
"allProxy": "socks5://host.docker.internal:6153",
"httpProxy": "http://host.docker.internal:6152",
"httpsProxy": "http://host.docker.internal:6152"
}
}
}
Docker Client 设置 Proxy 后不用重启 Docker,但是需要明白 Docker Client 是通过 ENV 的形式为容器注入代理,这就意味着之前已经存在的容器,在修改配置后是不会生效的,必须停止并删除容器,再重新用 docker run
或者 docker compose up
重新创建容器,这样才会在容器的 ENV 中增加上述 Proxy 配置。
除了这种方式还可以在 CLI 中通过 –env 和 –build-arg 来设置临时代理:
docker build --build-arg HTTP_PROXY="http://proxy.example.com:3128" .
docker run --env HTTP_PROXY="http://proxy.example.com:3128" redis
总结⌗
Docker 的 Proxy 配置虽然比较复杂,但是梳理完之后就非常清楚了:
- Docker Client Proxy:负责
docker run
和docker build
阶段的代理配置 - Docker Daemon Proxy:负责
docker push
和docker pull
阶段的代理配置
I hope this is helpful, Happy hacking…