如何给 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 执行缓慢或者失败的时候才想到要配置代理,浪费大把时间。 ...

April 17, 2026 · 3 min

记一次在 Linux 中根据端口号查找进程的经历

前言 不久之前,我接手了一套服务器集群,这个集群由一个登录节点和多个计算节点组成,其中登录节点可以通过外网访问,而计算节点只能通过登录节点跳板访问。 拿到手,我最先做的便是探查一下这个集群的网络架构,而在我排查过程中,我发现登录节点 80 端口上开了一个 HTTP 访问,是用于计算节点资源管理的后台管理平台,不足为奇。 但是我有点好奇,想看一下这个 80 端口运行的那个服务是哪个进程管理的,顺便也能看一下这个管理平台是如何搭建起来的。 然后,按照运维的惯例,执行以下几个命令来查找对应进程: lsof -i :80 netstat -tlnup | grep :80 ss -tlnup | grep :80 并不奇怪,输出结果显示: $ netstat -tlnup | grep :80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3202/nginx: master 即,80 端口是一个 nginx 进程在提供服务,但是我们知道,管理平台不是静态网页,nginx 大概率是一个反向代理的作用。 因此,我打开了 /etc/nginx/nginx.conf 查看一下 80 端口具体代理了哪里的网络服务(省略无关配置): stream { server { listen 80; proxy_pass 172.20.2.31:80; } } 看样子代理了 172.20.2.31 这个计算节点上 80 端口的服务。 接着,我 ssh 连接上了这个节点,同样使用惯例的指令查询 80 端口上的服务,但是这一次,奇怪的事情出现了,终端里什么输出都没有,也就是说,“没有”任何进程在 80 端口上服务? ...

April 4, 2026 · 5 min