配置Docker使用代理

如果你也苦于GFW的阻塞,无法正常更新软件,并且在docker需要pull images时候发现无法下载Docker镜像,则可以部署 Squid代理服务Squid父级socks代理 来实现代理翻墙,或者采用非常简便的 SSH Tunneling: 动态端口转发 实现socks5代理 。这里介绍如何配置docker客户端,以便能够通过代理(HTTP或者socks)加速镜像下载。

这个方法也使得容器内部能够不需要单独配置代理,直接通过代理服务器上网。

Docker客户端的Proxy

注解

注意,Docker客户端配置是对创建的容器生效,也就是把代理环境变量配置注入到容器内部。

对于物理主机上的docker服务要实现镜像下载加速,需要配置 Docker服务器Proxy

Docker客户端支持使用代理服务器,主要有两种方式配置:

  • 从Docker 17.07和更高版本,可以配置 Docker 端自动传递代理信息给容器
  • Docker 17.06或低版本,则需要在容器中设置相应的环境变量

配置Docker客户端

  • 在Docker客户端,创建或配置 ~/.docker/config.json 设置以下json格式配置:
配置Docker客户端 ~/.docker/config.json 可以为容器内部注入代理配置
{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://192.168.7.152:3128",
     "httpsProxy": "http://192.168.7.152:3128",
     "noProxy": "*.baidu.com,192.168.0.0/16,10.0.0.0/8"
   }
 }
}
  • 然后创建的新容器,在容器中的环境变量会自动设置代理

注解

可以结合 远程服务器squid提供给本地局域网 配置Docker客户端,这样只需要远程服务器安装部署过一次 Squid代理服务 ,本地局域网Docker就可以简单实现翻墙代理,方便完成很多安装部署工作。

Docker客户端环境变量

可以在 dockerfile 中配置:

ENV HTTP_PROXY "http://127.0.0.1:3001"
ENV HTTP_PROXY "http://127.0.0.1:3001"
ENV FTP_PROXY "ftp://127.0.0.1:3001"
ENV NO_PROXY "*.test.example.com,.example2.com"

也可以在运行命令行使用参数:

--env HTTP_PROXY="http://127.0.0.1:3001"
--env HTTPS_PROXY="https://127.0.0.1:3001"
--env FTP_PROXY="ftp://127.0.0.1:3001"
--env NO_PROXY="*.test.example.com,.example2.com"

注解

需要注意Docker配置环境变量 HTTP_PROXY 是全大写字母,我测试发现全小写字母 http_proxy 不生效

Docker服务器Proxy

systemd配置Docker服务器Proxy

警告

配置Docker服务器使用Proxy是成功的,但是访问Docker Hub证书存在问题,提示报错类似:

Get "https://registry-1.docker.io/v2/": proxyconnect tcp: tls: first record does not look like a TLS handshake

见后文参考官方设置。

对于主机上的dockerd服务,在下载镜像等工作使用代理,则需要配置服务的环境变量。

  • 创建 /etc/systemd/system/docker.service.d/http-proxy.conf 配置文件:

    [Service]
    Environment="HTTP_PROXY=http://user01:password@10.10.10.10:8080/"
    Environment="HTTPS_PROXY=https://user01:password@10.10.10.10:8080/"
    Environment="NO_PROXY= hostname.example.com,172.10.10.10"
    
  • 然后重新加载配置并重启服务:

    systemctl daemon-reload
    systemctl restart docker
    
  • 然后检查加载的配置:

    systemctl show docker --property Environment
    

可以看到输出:

Environment=GOTRACEBACK=crash HTTP_PROXY=http://10.10.10.10:8080/ HTTPS_PROXY=http://10.10.10.10:8080/ NO_PROXY= hostname.example.com,172.10.10.10

配置docker使用socks代理

注解

这步socks代理我实践没有成功,待后续排查

其实更为简便的方法是使用 SSH隧道 方式的socks代理,可以和上文一样配置到 /etc/systemd/system/docker.service.d/http-proxy.conf 中添加:

[Service]
Environment="ALL_PROXY=socks5h://localhost:1080"

或者直接在重启 docker 服务之前先设置好环境变量,然后重启 docker 服务(这样可以临时生效):

export ALL_PROXY=socks5h://localhost:1080
sudo systemctl restart docker

这样就能够够快速实现翻越GFW完成镜像下载,避免安装过程异常

Ubuntu配置Docker服务器Proxy

在Ubuntu上配置Docker服务器Proxy非常简单,只需要编辑 /etc/default/docker

# If you need Docker to use an HTTP proxy, it can also be specified here.
export http_proxy="http://127.0.0.1:3128/"

按照上述配置完成后重启:

sudo systemctl restart docker

Docker官方解决方案

注解

如果没有配置 Squid SSL拦截 ,那么虽然 Docker客户端的Proxy 正常,但是 Docker服务器Proxy 会遇到异常: HTTP下载正常,HTTPS则出现握手错误

我在部署 在Kubernetes部署Stable Diffusion 就遇到GFW阻塞导致需要构建 Squid父级socks代理 ,此时需要同时解决 Docker客户端的ProxyDocker服务器Proxy ,这迫使我改进 Squid代理服务 部署,实践 Squid SSL拦截

参考 Docker官方文档 Running a Docker daemon behind an HTTPS_PROXY 配置局域网在https代理后使用docker服务:

  • 安装 ca-certificates 软件包
  • /etc/pki/tls/certs/ca-bundle.crt 中添加代理服务器证书
  • 启动 Docker 时使用参数 HTTPS_PROXY=http://username:password@proxy:port/

注解

这也是前述配置代理后出现证书错误的解决方法:需要在服务器上添加代理服务器证书