配置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格式配置:
{
"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
见后文参考官方设置。
备注
解决https代理的方法可以采用 Squid SSL拦截 ,但是官方文档语焉不详,所以采用 work around 方法,将 HTTPS_PROXY=
也配置成采用 http://
,见下文
对于主机上的dockerd服务,在下载镜像等工作使用代理,则需要配置服务的环境变量。
创建
/etc/systemd/system/docker.service.d/http-proxy.conf
配置文件:
[Service]
Environment="HTTP_PROXY=http://192.168.6.200:3128/"
Environment="HTTPS_PROXY=http://192.168.6.200:3128/"
然后重新加载配置并重启服务:
systemctl daemon-reload systemctl restart docker
然后检查加载的配置:
systemctl show docker --property Environment
可以看到输出:
Environment=HTTP_PROXY=http://192.168.6.200:3128/ HTTPS_PROXY=http://192.168.6.200:3128/
结合环境变量和脚本配置
上述手工修订配置文件还有一个改进方法是使用脚本生成,方法参考 containerd服务端代理 :
在
/etc/environemt
设置:
HTTP_PROXY="http://192.168.6.200:3128"
HTTPS_PROXY="http://192.168.6.200:3128"
NO_PROXY="*.baidu.com,192.168.0.0/16,10.0.0.0/8"
然后通过脚本添加一个独立的配置
/etc/systemd/system/docker.service.d/http-proxy.conf
:
if [ ! -d /etc/systemd/system/docker.service.d ];then
mkdir -p /etc/systemd/system/docker.service.d
fi
cat <<EOF >/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=${HTTP_PROXY:-}"
Environment="HTTPS_PROXY=${HTTPS_PROXY:-}"
Environment="NO_PROXY=${NO_PROXY:-localhost},${LOCAL_NETWORK}"
EOF
systemctl daemon-reload
systemctl restart docker
配置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客户端的Proxy 和 Docker服务器Proxy ,这迫使我改进 Squid代理服务 部署,实践 Squid SSL拦截
参考 Docker官方文档 Running a Docker daemon behind an HTTPS_PROXY 配置局域网在https代理后使用docker服务:
安装
ca-certificates
软件包:sudo apt install ca-certificates
完成 Squid SSL拦截 配置
在
/etc/pki/tls/certs/ca-bundle.crt
中添加代理服务器证书启动 Docker 时使用参数
HTTPS_PROXY=http://username:password@proxy:port/
备注
这也是前述配置代理后出现证书错误的解决方法:需要在服务器上添加代理服务器证书