CI 执行节点几分钟内就会创建和销毁,容器没有持久磁盘,往往也没有固定 IP,而每次运行都要重新接入外部代理——靠手动打开桌面客户端配置根本行不通。下面说清楚正确的接入方式:镜像里不留凭据,兼顾执行节点的浮动地址,并把流量和隔离都管住。

通过环境变量传递代理参数

把代理传入容器和流水线步骤的标准方式,是 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY 这几个变量(以及部分库改读的小写版本)。变量值就是带账号密码的连接字符串:协议、凭据、主机、端口。多数 HTTP 客户端、包管理器和命令行工具都会自动读取这些变量,无需改动应用代码。

NO_PROXY 单独列出应当直连、不走代理的地址和域名:容器网络内部服务、本地镜像仓库、同一流水线各步骤之间的内部地址。NO_PROXY 配置不对,内部流量也会绕道走外部节点,白白增加消耗和延迟。变量应设在步骤级别而非整条流水线,当不同任务需要不同地址时——构建步骤直连,做外部检查的步骤才走对应地域的代理。

为什么凭据不能写进镜像

容器镜像按层构建,每一层都会进入镜像仓库并长期留存,哪怕后面的层删除了这个密钥也一样——在构建阶段把账号密码写进环境变量的那条指令,会通过分层历史一直可被读取,即使紧接着的下一条指令把它删掉了也无济于事。密钥扫描工具能在几秒内找出这类凭据,公有和私有仓库都不例外——仓库私有不等于安全。

正确做法是在运行时而非构建时注入密钥:环境变量、加密的流水线密钥存储,或者启动时挂载、从不写入任何镜像层的 volume。镜像本身在所有环境下保持一致,变化的只是 CI 系统在任务启动时替换进去的那个值。

白名单对浮动地址的执行节点无效

按执行节点 IP 放行访问,只对拥有固定地址的专用基础设施有效。云端执行节点每次运行都从共享池里取一个容器,外部 IP 逐次运行都会变化,有时节点重建还会在步骤中途改变——写进白名单的地址下一次运行就已经过期,代码本身没有问题,访问却开始莫名其妙地失败。

唯一站得住的方案,是把授权绑在账号上而不是地址上,用账号密码认证。这与桌面客户端的原理一致:连接字符串本身携带凭据,而不依赖执行节点根本无法保证的静态放行地址列表。这类授权下地址如何轮换,见通过 API 轮换 IP一文。

CI 中的流量消耗与控制方法

每次运行的每个步骤都要走外部代理的流水线,流量积累速度比看起来快得多:一千次带图片页面的检查就要消耗 3–5 GB,每天对一百个地址做一次监控,单这一个场景每月大约就是 1.5–3 GB,还没算上不稳定步骤触发的重试。

控制消耗靠三件事:缓存依赖和构建产物,让真正需要走出去的只是确实对外的调用,而不是每次运行都重新构建同样的东西;在只需要文本或 API 响应的场景里关闭媒体加载;以及为无地域敏感性的任务选用按月固定价的数据中心地址——它完全不按流量计费,测试运行也不会推高流量账单。这方面的经济账见便宜与昂贵的代理一文。

并行任务之间的隔离

并行任务是 CI 的常见形态,流水线不应让所有并行分支都走同一个分配到的地址——如果某个步骤因信誉问题被封或触发验证码,共用这个 IP 的所有并行任务都会被牵连,包括与该问题毫无关系的任务。

实际做法是给每条并行分支分配独立会话或独立的凭据分段,以任务或步骤编号作为标识。对按会话分配地址的通道来说,只要会话标识对每次运行都是真正唯一的,而不是整条流水线写死同一个值,每个任务就能自动拿到属于自己的 IP。

常见问题

同一个代理账号能否同时用于多条流水线?

技术上可以,但在并发会话数有共享上限的通道上,这会造成不相关流水线之间抢占会话:高峰时一条流水线会挤占另一条的会话。多条活跃流水线更实际的做法,是把它们分到不同的凭据分段,哪怕用的是同一个套餐。

如果容器内的工具不支持环境变量,该如何传入代理?

部分工具会忽略 HTTP_PROXY,要求把地址写进自己的配置文件或命令行参数——这种情况下应在调用该工具时显式传入连接字符串,从同一环境变量里读取,放在包装该步骤的脚本中完成。

是否需要把代理限制在流水线实际访问的外部域名范围内?

如果账号支持这项设置,值得配置——这与其说是省流量,不如说是排除 NO_PROXY 配置失误导致的内部地址误访问,这类问题不然要等到翻日志时才会被发现。

面向 CI 的账号密码认证代理,可直接通过环境变量传入,不依赖执行节点地址,见代理专区;接入文档与限额说明见代理 API