Colima Socks 代理

备注

之前 Colima 代理 设置还是太复杂且记录不清晰,我在2026年5月重新构建Colima工作环境时,改为采用 SSH Tunneling: 动态端口转发 构建socks代理。本文为实践记录,比之前的方式更简洁更有效。

物理主机

物理主机 macOS 上配置 ~/.ssh/config 设置通过墙外VM的ssh连接构件DynamicForward:

设置SSH动态端口转发
Host *
  ServerAliveInterval 60
  ControlMaster auto
  ControlPath ~/.ssh/%h-%p-%r
  ControlPersist yes
  StrictHostKeyChecking no
  Compression yes

Host MyProxy
  HostName <SERVER_IP>
  User admin
  # 1. 保持最激进的存活探测,防范防火墙悄悄掐断连接
  ServerAliveInterval 15
  ServerAliveCountMax 3
  # 2. 彻底关闭压缩,降低老 CPU 负载,减少传输延迟
  Compression no
  # 3. 针对代理隧道,显式关闭连接复用(避开多路复用互锁)
  ControlMaster no
  # 4. 优化 TCP 底层性能
  IPQoS throughput
  TCPKeepAlive yes
  # 5. 采用Host主机所有接口监听代理端口,防止colima在大流量时默认转发给127.0.0.1:1080出现限流而failover到192.168.5.2实际网卡接口
  #DynamicForward 1080
  DynamicForward 0.0.0.0:1080
  IdentitiesOnly yes
  IdentityFile ~/.ssh/proxy/id_rsa

在物理主机上执行 ssh MyProxy 建立ssh tunnel

虚拟机注入proxy环境变量

Colima配置 提供了一种向虚拟机注入环境变量的方式,可以通过修改 ~/.colima/_template/default.yaml 设置虚拟机中 env ,这样虚拟机的操作系统 curl 以及 APT包管理 就会走代理方式 越过长城 :

修订 default.yaml
env:
  # curl / git 能够完美识别 http_proxy、https_proxy 或 ALL_PROXY,优先级是小写变量最高
  # ALL_PROXY 是一个全协议兜底变量 它不仅管 HTTP(S),还管 ftp://、git://、甚至是内部未明确分类的其他 TCP 流量
  http_proxy: socks5h://127.0.0.1:1080
  https_proxy: socks5h://127.0.0.1:1080
  all_proxy: socks5h://127.0.0.1:1080
  no_proxy: localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,*.baidu.com
  # 大写变量兜底防止某些应用忽略大小写
  HTTP_PROXY: socks5h://127.0.0.1:1080
  HTTPS_PROXY: socks5h://127.0.0.1:1080
  ALL_PROXY: socks5h://127.0.0.1:1080
  NO_PROXY: localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,*.baidu.com

备注

上述Colima环境变量注入是对VM操作系统的调整,但是 containerd运行时(runtime)Docker 需要通过两种方式传递该环境变量:

  • Buildkit 需要明确的 --build-arg 参数,或者 BuildKit 守护进程的运行参数来获得这个代理设置

  • dockerdcontainerd运行时(runtime) 同样需要守护进程的运行参数来获知这个代理设置,这样才能正确拉取镜像

BuildKit代理

官方推荐的做法,不需要修改任何底层配置文件。BuildKit 允许你在执行构建时,通过 --build-arg 将宿主机的代理作为参数显式传递给构建沙盒:

直接传递 --build-arg 参数给 nerdctl build
nerdctl build \
  --build-arg HTTP_PROXY=socks5h://192.168.5.2:1080 \
  --build-arg HTTPS_PROXY=socks5h://192.168.5.2:1080 \
  --build-arg ALL_PROXY=socks5h://192.168.5.2:1080 \
  -t your-image:latest

备注

HTTP_PROXYHTTPS_PROXYALL_PROXY 是 BuildKit 内置的特权内置参数(Built-in Build Args)。不需要在 Dockerfile 里写 ARG HTTP_PROXY ,BuildKit 会自动识别并在构建容器内的 RUN 执行阶段将其临时设为环境变量,构建完成后自动擦除,不会将敏感的代理 IP 写入最终的镜像层中。

配置方法(一劳永逸)

如果不想每次敲命令都带上一长串 --build-arg ,则需要进入 Colima 虚拟机内部( colima ssh ),去修改 BuildKit 的守护进程配置。

  • 在虚拟机内部执行以下命令为 BuildKit 服务添加运行环境变量:

BuildKit 服务添加运行环境变量
sudo mkdir -p /etc/systemd/system/buildkit.service.d
sudo vi /etc/systemd/system/buildkit.service.d/proxy.conf
  • proxy.conf 中配置如下(这里 192.168.5.2 是Colima宿主机网关):

proxy.conf 中配置运行参数
[Service]
Environment="HTTP_PROXY=socks5h://192.168.5.2:1080"
Environment="HTTPS_PROXY=socks5h://192.168.5.2:1080"
Environment="ALL_PROXY=socks5h://192.168.5.2:1080"
Environment="NO_PROXY=localhost,127.0.0.1,192.168.5.2,host.docker.internal"
  • 然后重新启动 BuildKit 服务

重启buildkit服务
sudo systemctl daemon-reload
sudo systemctl restart buildkit

Containerd代理

除了 build 阶段需要通过代理,镜像拉取也需要通过代理,否则 containerd运行时(runtime) 也会出现连接报错。同样通过 colima ssh 登陆到虚拟机内部,为 containerd 配置代理:

  • 在虚拟机内部执行以下命令为 Containerd 服务添加运行环境变量:

Containerd 服务添加运行环境变量
sudo mkdir -p /etc/systemd/system/containerd.service.d
sudo vi /etc/systemd/system/containerd.service.d/proxy.conf
  • proxy.conf 中配置如下(和上文配置 BuildKit 是一样的):

proxy.conf 中配置运行参数
[Service]
Environment="HTTP_PROXY=socks5h://192.168.5.2:1080"
Environment="HTTPS_PROXY=socks5h://192.168.5.2:1080"
Environment="ALL_PROXY=socks5h://192.168.5.2:1080"
Environment="NO_PROXY=localhost,127.0.0.1,192.168.5.2,host.docker.internal"
  • 然后重启 Containerd 服务

重启Containerd服务
sudo systemctl daemon-reload
sudo systemctl restart containerd

容器内部代理

wget/curl

在执行 nerdctl build 时,虽然上述BuildKit代理和Containerd代理能够让容器镜像下载丝滑完成,但是当 Dockerfile 中需要安装大量应用时,常常会被防火长城阻塞导致安装失败。此时需要解决构建容器内部注入 socks5h 代理。

详细的方法可以参考 BuildKit代理设置 ,我为了每次都自动将代理配置注入容器,采用了全局网络代理配置: 修订Colima虚拟机内部的 /etc/buildkit/buildkitd.toml 配置:

在 buildkitd.toml 添加代理设置
[worker.oci]
enabled = false
env = [
    "HTTP_PROXY=socks5h://192.168.5.2:1080",
    "HTTPS_PROXY=socks5h://192.168.5.2:1080",
    "ALL_PROXY=socks5h://192.168.5.2:1080",
    "NO_PROXY=localhost,127.0.0.1,192.168.5.2"
]

[worker.containerd]
enabled = true
env = [
    "HTTP_PROXY=socks5h://192.168.5.2:1080",
    "HTTPS_PROXY=socks5h://192.168.5.2:1080",
    "ALL_PROXY=socks5h://192.168.5.2:1080",
    "NO_PROXY=localhost,127.0.0.1,192.168.5.2"
]

[grpc]
gid = 1000

然后重启BuildKit守护进程

重启BuildKit
sudo systemctl restart buildkit

上述配置能够让容器内部的 curl wget 都自动使用代理配置。

apt

需要注意, apt-get 虽然支持 socks5h:// 但是不能通过环境变量直接使用,而是要配置 /etc/apt/apt.conf.d/proxy.conf 设置专属配置。详见 APT代理 :

配置APT代理 /etc/apt/apt.conf.d/proxy.conf
Acquire::http::Proxy "socks5h://127.0.0.1:1080";
Acquire::https::Proxy "socks5h://127.0.0.1:1080";
Acquire::socks::Proxy "socks5h://127.0.0.1:1080";

为了能够在 nerdctl build 使得上述配置生效,也就是在build过程中容器内apt能够走socks代理,需要在Dockerfile的开头添加一个写入配置的命令:

在Dockerfile中添加apt代理配置
FROM debian:latest

# 强行让 apt-get 走内部专属的 socks5h 隧道,直接无视外界环境变量
RUN echo 'Acquire::http::Proxy "socks5h://192.168.5.2:1080/";' > /etc/apt/apt.conf.d/proxy.conf && \
    echo 'Acquire::https::Proxy "socks5h://192.168.5.2:1080/";' >> /etc/apt/apt.conf.d/proxy.conf

ENV DEBIAN_FRONTEND=noninteractive

# 此时 apt-get 闭眼全速通过
RUN apt-get update -y && apt-get install -y --no-install-recommends \
    curl ca-certificates git build-essential \
    && rm -rf /var/lib/apt/lists/*

...