Docker 代理快速起步

备注

本文综合了我的 配置Docker使用代理Colima 代理 实践经验,力求快速准确完成Docker 越过长城

概述

  • 采用我认为最简便且安全的 SSH隧道 将本地回环地址端口 3128 映射到墙外的VPS上 Squid代理服务Privoxy代理服务 服务端口 3128 (本文没有包含VPS上代理服务器安装配置,所以请参考对应章节)

  • HOST物理服务器配置软件仓库代理( YUM代理 / APT代理 )

  • HOST物理服务器全局配置代理(可设置部分不代理),将作用于HOST主机的 curl代理 以及大多数符合Linux代理规范的应用

  • 启用 Docker 客户端代理(部分docker获取META信息需要翻墙,因为docker.com已经完整被墙)

  • 启用 Docker 服务端代理(包括 Docker 控制服务和 containerd运行时(runtime) 运行时服务),这样Docker可以从官方镜像仓库下载镜像

  • 启动 Docker 容器内部操作系统代理,这样Docker容器能够通过Docker NAT网络的网关(也就是HOST物理主机)代理访问外部世界(注意代理地址从回环地址 127.0.0.1 改为Docker NAT网关地址 172.17.0.1 )

请读者根据自己的需求进行调整,可能有些步骤对于你的环境不是必要的

HOST物理服务器构建代理映射( SSH隧道 )

  • 通过 SSH隧道 构建一个本地到远程服务器代理服务端口(服务器上代理服务器仅监听回环地址)的SSH加密连接,方法是配置 ~/.ssh/config ( <SERVER_IP> 以实际地址配置) 端口转发要设置允许Docker NAT网关地址 :

~/.ssh/config 配置 SSH隧道 构建一个本地到远程服务器Proxy端口加密连接
Host *
  ServerAliveInterval 60
  ControlMaster auto
  ControlPath ~/.ssh/%h-%p-%r
  ControlPersist yes
  StrictHostKeyChecking no
  Compression yes

Host MyProxy
  HostName <SERVER_IP>
  User admin
  LocalForward 3128 127.0.0.1:3128
  LocalForward 172.17.0.1:3128 127.0.0.1:3128
  IdentitiesOnly yes
  IdentityFile ~/.ssh/proxy/id_rsa
  • 执行以下命令构建SSL Tunnel:

通过SSH构建了本地的一个SSH Tunneling到远程服务器的 Proxy代理服务 服务
ssh MyProxy

HOST物理服务器apt代理

在 apt 配置中添加代理设置
Acquire::http::Proxy "http://127.0.0.1:3128/";
...

HOST物理服务器全局配置代理

  • 修订 /etc/environment 添加代理配置(该配置对HOST物理服务器上 curl代理 以及大多数符合Linux代理规范的应用起作用):

/etc/environment 设置代理环境变量
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
#LIMA-START
HTTPS_PROXY=http://192.168.5.2:3128
HTTP_PROXY=http://192.168.5.2:3128
NO_PROXY=localhost,127.0.0.1,*.baidu.com,192.168.0.0/16,10.0.0.0/8
http_proxy=http://192.168.5.2:3128
https_proxy=http://192.168.5.2:3128
no_proxy=localhost,127.0.0.1,*.baidu.com,192.168.0.0/16,10.0.0.0/8
#LIMA-END
  • 登陆系统使上述代理环境变量生效

Docker 客户端(容器内部)代理

  • 我在 Linux环境安装Docker 都是采用普通用户账号(如 admin )允许直接运行docker,所以,在这个 admin 管理账号登陆下配置 ~/.docker/config.json :

配置HOST物理服务器 admin 用户(管理docker)客户端使用代理 ~/.docker/config.json
{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://172.17.0.1:3128",
     "httpsProxy": "http://172.17.0.1:3128",
     "noProxy": "*.baidu.com,192.168.0.0/16,10.0.0.0/8"
   }
 }
}

备注

config.json 中配置的环境变量将在Docker容器启动时自动注入容器内部,实际生效是在容器内部生效

一定要 配置为 172.17.0.1 ,这个地址对应前述 SSH隧道 端口映射绑定Docker NAT网关的地址

警告

错误配置容器内部的代理服务器,会导致非常异常的容器无响应问题。例如,我错误配置 127.0.0.1:3128 作为注入地址,在 树莓派Raspberry Pi OS(64位)安装Docker 遇到 Debian镜像(tini进程管理器) 执行 RUN apt install tini 出现找不到软件包,导致 docker build 失败,并且使用简化的Dockerfile构建的容器运行时,容器内部执行任何命令都会无响应。

HOST物理服务器 Docker 服务端代理

在HOST物理服务器上执行以下两个步骤分别设置 Docker 控制服务代理 和 containerd运行时(runtime) 运行时服务代理

Docker 控制服务代理

  • 执行以下脚本为docker服务添加代理配置:

生成 /etc/systemd/system/docker.service.d/http-proxy.conf 为docker服务添加代理配置
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

containerd运行时(runtime) 运行时服务代理

  • 执行以下脚本为containerd服务添加代理配置:

生成 /etc/systemd/system/containerd.service.d/http-proxy.conf 为containerd添加代理配置
if [ ! -d /etc/systemd/system/containerd.service.d ];then
    mkdir -p /etc/systemd/system/containerd.service.d
fi

cat <<EOF >/etc/systemd/system/containerd.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 containerd

现在

现在可以执行 Debian镜像(tini进程管理器) 来验证代理是否正确工作