给流水线挑运行环境:镜像和构建节点
流水线里的每条命令,都是跑在一个 Docker 容器里的。所以第一件要想清楚的事:容器里有什么。
一、两种给环境的方式
方式 1:直接用现成镜像(最快)
.cnb.yml
main:
push:
- docker:
image: node:22
stages:
- name: node version
script: node -v
适合官方镜像、团队预置镜像。私有镜像需要额外配认证。
方式 2:用 Dockerfile 现场建(最灵活)
image/Dockerfile
FROM node:20
RUN apt-get update && apt-get install -y jq
.cnb.yml
main:
push:
- docker:
build: image/Dockerfile
stages:
- name: jq version
script: jq --version
它的聪明之处在于会先算镜像版本哈希:命中缓存就直接用,没命中才 docker build,并自动推到流水线所属的制品库复用。所以稍微慢一点,但不用你操心。
:::tip 优先级
build 和 image 同时写时 build 生效。任务级(stage 里)只能用 image,不支持 build。
:::
二、单条命令临时换镜像
有时候一整个 pipeline 用 node 镜像,但某一步要用 python 处理数据:
.cnb.yml
main:
push:
- docker:
image: node:22
stages:
- name: 用 node
script: node -v
- name: 临时换 python
image: python:3.12
script: python -V
image 写在 stage 里,只对这一条任务生效。
三、选构建节点:核数与架构
默认节点是 amd64 通用节点,日常够用。需要指定时:
.cnb.yml
main:
push:
- runner:
tags: cnb:arch:amd64
cpus: 8
stages:
- name: uname
script: uname -a
可用节点:
| Tags | 架构 | CPU 核数 | 说明 |
|---|---|---|---|
cnb:arch:amd64 | amd64 | 1~64(默认 8) | 最常用 |
cnb:arch:arm64:v8 | arm64/v8 | 1~16(默认 8) | 需要 arm 产物时用 |
cnb:arch:amd64:gpu | amd64 | 固定 16 | 48GB 显存 |
cnb:arch:amd64:gpu:L40 | amd64 | 固定 16 | 48GB 显存 |
三者单次最长都按 18 小时算,但集群会做动态管控,实际以管控为准。
四、cpus 是不是越多越快
不是。cpus 只是资源上限,不改变程序本身的并行度。
判据很简单:
- 编译类任务(C++、Go、Rust、前端大包):加 CPU 有效,
make -j$(nproc)吃得下 - 纯 IO 任务(拉依赖、传文件、调 API):加 CPU 基本无效,瓶颈在网络
- 单线程脚本:加 CPU 完全无效
所以调优顺序应该是:先看构建日志里哪一步最慢 → 判断是哪类任务 → 再决定加核还是加缓存。
五、缺省镜像是什么
不写 docker.image 也不写 docker.build 时会用平台缺省镜像:
- 云原生构建:
CNB_DEFAULT_DOCKER_IMAGE - 云原生开发:
CNB_DEFAULT_DEV_DOCKER_IMAGE
缺省镜像里有 git、curl 等基础工具,但不保证有你项目的语言运行时。所以能写就写上,别依赖缺省。
六、团队自建节点(进阶)
根组织管理员可以接入自己的 Mac / Windows / Linux 机器当专属 Runner,比如 iOS 打包必须 mac、Windows 桌面应用必须 windows。
配置方式是 runner.namespace: group 加自定义 tags:
.cnb.yml
main:
push:
- runner:
namespace: group
tags:
- mac
- arm64
stages:
- name: build-on-mac
script: sw_vers && uname -m
注意自建节点默认不开启 Docker,脚本直接跑在宿主机上,所以 cpus 配置无效,也不能用 docker.image。它只服务于云原生构建,不支持云原生开发。