如何给 Docker 配置透明代理
前言 通常,代理通常有两种方式,一种是开放端口,让需要代理的应用主动通过暴露的端口被代理访问远程服务;一种是使用 tun mode,即虚拟网卡模式,所有流量都会被虚拟网卡设备拦截从而被动代理访问远程服务。 对我来说,我并不希望在我的服务器上采取被动方式,因为它会对服务器上的所有应用产生影响,而且一旦代理软件崩溃退出,我将无法访问互联网,而且会影响比如 ping 等工具的执行(拦截 ICMP 数据包),这是极其不好的,因此平时在我的服务器上,我更倾向于使用主动方式,只有应用需要被代理才会主动去访问代理端口。 说是主动,也并不完全主动,无非就是设置环境变量: export http_proxy=http://127.0.0.1:7890 export https_proxy=http://127.0.0.1:7890 但是,对于 Docker 来说,通过设置环境变量的方式来配置代理会非常麻烦,如果不使用 docker compose,每次运行 docker run 的时候都需要输入长长的一串环境变量;如果使用 docker compose,要修改的部分也非常多,如下所示: services: app: image: my-app environment: - HTTP_PROXY=http://host.docker.internal:7890 - HTTPS_PROXY=http://host.docker.internal:7890 - NO_PROXY=localhost,127.0.0.1 extra_hosts: - "host.docker.internal:host-gateway" # only for linux 除此之外,使用主动代理还有其他弊端: 如果 docker compose 中有多个 service,你可能需要花费功夫判断哪些 service 需要代理,哪些不需要代理。 如果镜像中的应用不支持通过环境变量配置代理,那么以上配置就完全无效了。 最重要的,在 docker build 的过程中,Docker 会起一个临时容器来运行 dockerfile 中的命令,而在这个过程中,如果没有配置代理或镜像,那么一些基本的命令,比如 apt update、apt install 以及 pip install 等等,就会导致镜像构建缓慢,非常折磨人,而在 dockerfile 中配置代理也是一个非常麻烦的事情,很多时候都是发现 docker build 执行缓慢或者失败的时候才想到要配置代理,浪费大把时间。 ...