runners避坑:四个底层问题讲透
runners避坑不能停留在“别泄露密钥”这类提醒上。Runner 本质上是在替仓库执行代码,权限、缓存、标签和并发一旦设计错,轻则任务串数据,重则内网凭据被读取。本文从执行机制入手,把常见故障为什么发生、该如何封堵讲清楚。
先看本质:Runner 是代码执行边界
流水线里的 checkout、测试和部署命令,最终都由 Runner 所在机器执行。它能读到哪些文件、访问哪些网络、使用哪些令牌,决定了 job 的能力边界。把 Runner 当成普通插件,是多数安全坑的起点。
平台托管环境通常按任务创建临时实例,残留风险较低;长期自托管节点会留下工作目录、容器层和缓存。只要它接收不可信分支或外部贡献代码,就要假设这些代码会主动寻找凭据。
坑一:权限过大,问题出在信任混用
最危险的做法,是让同一台高权限 Runner 同时运行外部合并请求和生产部署。攻击代码不一定直接读取被屏蔽的日志变量,它还可以查看进程、工作目录、云实例元数据,或者篡改留给下一个任务的文件。
解决办法是按信任级别拆池:公共测试使用无生产网络权限的临时节点,主分支构建使用内部节点,部署再用独立受保护 Runner。令牌设置最小权限和短有效期,比单纯隐藏日志可靠。
坑二:缓存与标签制造了隐性串线
缓存的原理是用 key 查找并恢复一批文件。key 只写固定名称,多个分支或不同依赖版本就可能互相覆盖;把构建产物当缓存,还可能让旧文件混入发布包。缓存 key 至少应包含锁文件摘要、系统与架构,发布制品则交给 artifact 管理。
标签也不是装饰。job 写了过于宽泛的 self-hosted,可能被调度到缺少 Docker、架构不同甚至权限不合适的节点。标签要表达真实能力,例如 linux、arm64、gpu,敏感节点还应配合仓库或环境级访问限制。
坑三:盲目加并发,最后回到可观测性
并发超过 CPU、内存或磁盘承载能力后,任务不是更快,而是一起争抢资源。常见现象是编译随机失败、容器被系统杀掉、下载速度忽高忽低。设置并发前应观察 CPU、可用内存、磁盘空间、I/O 等待和队列长度。
runners避坑的核心可以压成一句话:先划信任边界,再做性能优化。用临时环境承接不可信代码,拆开测试与部署权限,给缓存和标签加明确规则,最后根据队列数据扩容,系统才会越用越稳。
推荐阅读
常见问题
自托管 Runner 能运行外部 Pull Request 吗?
不建议直接运行,尤其不能使用带生产权限的节点。确有需要时,应采用一次性隔离环境,禁用敏感凭据和内网访问,并在执行前设置人工审批。
清空工作目录就能保证 Runner 安全吗?
不能。风险还可能存在于进程、容器、缓存、系统用户目录和主机凭据中。处理不可信任务时,一次性虚拟机或临时容器比脚本清理更可靠。
缓存和 artifact 有什么区别?
缓存用于加速后续任务,允许失效或重建;artifact 是需要保存、下载或传给后续阶段的明确产物。安装依赖适合缓存,安装包和测试报告适合 artifact。