王厂长经营着一家叫「乐可可乐」的饮料厂。过去,他的产线是一条铁板一块的巨型机器——想换个瓶型,得停机拆装三天;想多灌一种口味,整条线都要返工。工程师们天天救火,产线却越改越僵。有一天,一位顾问告诉他:别再把产线做成「铁板一块」,把它拆成一排标准工位——贴标工位、灌装工位、压盖工位、装箱工位。每个工位只干一件事,都有自己的操作规范;工位之间用传送带连接,用共享仓库传递物料,用传感器自动开工。要换产品?换几个工位、调一下顺序就行。这套思路,正是云原生 CI/CD 框架 Tekton 的底层哲学。 Tekton 运行在 Kubernetes 之上,把「构建、测试、部署」这些 DevOps 动作,全都变成可以声明、复用、组合的积木。你写一份 YAML,声明「这条流水线由哪些任务组成」,剩下的交给 Tekton 去调度。本文会沿着工厂的故事,带你认识 Task、Pipeline、PipelineRun、Workspace、Trigger、Results 这些核心零件,从原理到实践,把一条可移植的云原生构建系统完整搭起来。

岗位关联

对 AI 从业者而言,Tekton 是打通「模型训练到模型上线」的标准化管道——掌握它,你就能把 ML 流水线以声明式方式固化到 Kubernetes,实现「代码即管道、管道即产品」,是 ML 工程化与平台工程方向的核心技能栈。

目录
  1. 可视化演示
  2. 初识 Tekton:从一根流水线说起
  3. 核心资源:工位卡片 Task 与标准动作 Step
  4. 流水线运行:开工单 PipelineRun 与岗位单 TaskRun
  5. 工作空间:共享仓库 Workspace
  6. 触发机制:传感器 Trigger
  7. 结果传递:质检标签 Results
  8. 实践落地:让工厂真正跑起来
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态展示Tekton组件化流水线、控制器执行机制、CI/CD阶段流程与Workspace/Results传递机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

初识 Tekton:从一根流水线说起

王厂长的老朋友全是做软件的。有次他去硅谷参观,发现人家程序员「生产软件」的方式和自己的可乐厂惊人地相似:代码从提交到上线,也要经过编译、测试、打包、部署一道道工序,老办法是在一台服务器上写一堆又长又乱的脚本,谁改谁知道——这就像他那条「铁板一块」的旧产线,换个需求就要拆机器。于是开源社区造出了 Tekton:把 CI/CD 的每一道工序都做成一个标准「工位」,写在 Kubernetes 上,用声明式 YAML 描述整条产线,而不是写命令脚本。

声明式是什么感受?传统脚本像「派活的口令」:先运行这个命令,再 ssh 到那台机器,再执行那个脚本,顺序错了就崩。而 Tekton 的声明式只描述「最终要长成什么样」:我说这条流水线有「编译 → 测试 → 打包」三个工位,具体怎么调度、怎么并发、怎么重试,交给控制器去安排。你像厂长看图纸一样,一眼就能看清管道结构。这个特性让 CI/CD 从「手艺活」变成了「搭积木」:任何一个工位(Task)都能独立拆下来,装到别的流水线上复用。

组件化复用是 Tekton 的核心魅力。就像可乐厂可以把「贴标工位」原封不动搬到果汁产线,一个写好的 Task 也可以在多个 Pipeline 里被反复引用。为了让小白理解调度代价,我们引入一条贯穿全文的公式:整条流水线的耗时,等于所有并行路径中耗时最长的那条,而不是简单相加。

理解了关键路径,你就明白了 Tekton 调度器的良苦用心:它尽量把无依赖的任务并行化,让瓶颈只出现在真正串行的地方。这跟厂长把「吹瓶」和「调配糖浆」同时开工是同一个道理。回到工厂——铁板一块的死机器已经被拆掉,新的工位阵列开始有了雏形。

Tpipeline=max⁡p∈Paths∑i∈ptiT_{\text{pipeline}} = \max_{p \in \mathrm{Paths}} \sum_{i \in p} t_i
公式含义:流水线的总耗时不是各工位耗时简单相加,而是取「关键路径」——最慢那条链路的总耗时。就像可乐厂灌装和贴标虽然可以并行,但压盖必须等灌装完成,最终时长由最慢的链条决定。
  1. 路径集合 Paths流水线中从起点到终点的所有可能依赖路径,每条路径由一串依次执行的任务组成。
    Paths={p1,p2,…,pk}\mathrm{Paths} = \{p_1, p_2, \dots, p_k\}
  2. 路径求和把路径 p 上每个任务的耗时 t_i 累加,得到该路径的总耗时。
    ∑i∈pti=tp1+tp2+⋯+tpn\sum_{i \in p} t_i = t_{p1} + t_{p2} + \dots + t_{pn}
  3. 取最大值在所有路径耗时中挑最大的一个,它就是整条流水线无法再压缩的「关键路径」。
    max⁡p∈Paths(∑i∈pti)\max_{p \in \mathrm{Paths}} \left( \sum_{i \in p} t_i \right)

核心资源:工位卡片 Task 与标准动作 Step

厂长要给每个工位写一张「工位卡片」,上面列着这个工位要按顺序执行的每一步操作。Tekton 里,这张卡片就叫 Task,卡片上的一行行操作叫 Step。Task 是最小的工作单元,Step 则是这个工位里的一个个具体动作。比如「灌装工位」这个 Task,包含三个 Step:打开瓶盖、注入 500ml 可乐、拧紧瓶盖。

理解 Task 的关键在于理解 Step 的运行方式。每个 Step 都是一个 独立的容器镜像——就像工位上每个动作都由一台专门机器完成:注水机和拧盖机互不干扰。多个 Step 在同一个 Task 内按声明顺序依次执行,前一个 Step 退出码为 0 才轮到下一个。Task 还可以声明 params(参数),让工位卡片在重复使用时可以换参数,例如灌装工位接收「容量」参数,这次灌 500ml,下次灌 330ml,卡片不用重写。

从函数式编程的角度看,一个 Task 就是一组容器动作的顺序复合:

一个最小 Task 定义,用 YAML 写出来就是这样:metadata 里的 name 是工位名,spec.steps 下列出每个动作。实际使用中,Task 可以小到一条 echo,大到跑完整套模型训练脚本。写好的工位卡片可以收进共享「积木箱」,谁要谁取——这就是 Tekton 强大的组件复用基础。

steps(Task)=[exec(img1), exec(img2), …, exec(imgm)]\mathrm{steps}(\mathrm{Task}) = [\mathrm{exec}(img_1),\, \mathrm{exec}(img_2),\, \dots,\, \mathrm{exec}(img_m)]
公式含义:Task 的 steps 字段是一个列表,列表里的每个元素都是在指定镜像 img_i 中执行的一段逻辑。列表的次序就是执行次序,不可并行。
  1. steps(Task)读取 Task 这个资源内部的「步骤列表」,列表长度 m 表示该工位有几个动作。
    steps(Task)=[s1,s2,…,sm]\mathrm{steps}(\mathrm{Task}) = [s_1, s_2, \dots, s_m]
  2. exec(img_i)第 i 个 Step 会在镜像 img_i 对应的容器里运行,这个容器是临时创建的,运行完即销毁。
    si=exec(imgi)s_i = \mathrm{exec}(img_i)
  3. 顺序执行方括号是「有序列表」符号——Tekton 保证 s_1 完成后才启动 s_2,这正是工位内动作的严格先后。
    s1→s2→⋯→sms_1 \to s_2 \to \dots \to s_m

流水线运行:开工单 PipelineRun 与岗位单 TaskRun

产线图纸画好了,但图纸不会自己生产。王厂长每接到一笔订单,就要开一张「生产工单」,把排产要求写清楚,车间才真正动起来。Tekton 里,Pipeline 是图纸,PipelineRun 才是开工单——你定义一个 Pipeline 资源只是声明「有这么一条产线」,只有创建一个 PipelineRun 实例,控制器才会真正调度容器去执行。同一张图纸可以开无数张工单,对应同一条流水线的无数次运行。

同理,TaskRun 就是「岗位工单」。当 PipelineRun 启动后,控制器会把流水线上的每个 Task 实例化为一个 TaskRun,并记录这个 Task 某一次运行的输入、输出和状态。这种「定义与运行分离」的设计,让同一套声明可以被反复、并发地执行而不互相污染——就像王厂长用同一张图纸,同时给白班和夜班各开一张互不影响的工单。

每次运行,运行状态都会在几个固定状态间流转:

Runner 还支持 retries(重试次数)和 timeout(超时时间)——某个工位操作失手,可以允许它重来两次;某个工位卡死 10 分钟,自动宣告失败,避免整条产线无限等下去。这就像给每个工位装了「自动求救铃」和「超时断电保护」,让流水线在真实生产环境中足够健壮。

s∈{Pending,Running,Succeeded,Failed}s \in \{\mathrm{Pending}, \mathrm{Running}, \mathrm{Succeeded}, \mathrm{Failed}\}
公式含义:PipelineRun 或 TaskRun 的即时状态,只会是这四个枚举值之一。Pending 表示排队中,Running 表示容器已启动,Succeeded 表示所有 Step 都以 0 退出,Failed 则表示某一步出错。
  1. 状态集合用花括号列出运行可能处于的全部状态,这是 Tekton 状态枚举的完整集合。
    S={Pending,Running,Succeeded,Failed}S = \{\mathrm{Pending}, \mathrm{Running}, \mathrm{Succeeded}, \mathrm{Failed}\}
  2. 状态约束任意时刻 s 只能取集合中的一个值,不会出现「既 Running 又 Succeeded」的模糊状态。
    s∈S,∣{s}∣=1s \in S, \quad |\{s\}| = 1
  3. 终态判定Succeeded 要求所有 Step 的退出码都为 0,只要有一个非 0,整体就进入 Failed。
    Succeeded  ⟺  ⋀i=1m(exit_codei=0)\mathrm{Succeeded} \iff \bigwedge_{i=1}^{m} (\mathrm{exit\_code}_i = 0)

工作空间:共享仓库 Workspace

新产线有个大改动:工位之间不再用「硬连接」的专用传送槽,而是统一到中间设一个共享仓库。贴标工位把贴好标的瓶子放进仓库,灌装工位从仓库取货,灌完再放回去。这样无论工位怎么换顺序、换组合,只要对接仓库就行。Tekton 里的 Workspace 就是这个共享仓库。

Workspace 是一个「共享存储抽象层」。Task 里声明 workspaces 字段,说明这个工位需要挂载一个货架;Pipeline 把不同 Task 的同一命名 Workspace 连到同一个实际存储后端,数据就打通了。后端类型非常灵活:PVC(持久卷)像大型恒温仓库,数据长期保存;ConfigMap 像公告板,适合放只读配置;EmptyDir 像随产线启停的临时棚,流水线一跑完就清空。

在每个 Task 的容器里,Workspace 会被挂载成一个真实路径,容器内读写的文件就会落到共享仓库中。这个「挂载」操作可以形式化地描述为:

用 Workspace 要小心并发:多个 Task 同时写同一个文件会互相覆盖,就像两个工人抢同一支记号笔。所以最佳实践是各 Task 使用不同的子目录,把仓库划分成各自的区域。仓库让产线解耦——工位不认识彼此,只认识货架,这是云原生流水线可移植性的基石。

mount(Task,W)={(pathi,Wi)∣i=1…k}\mathrm{mount}(\mathrm{Task}, W) = \{ (\mathrm{path}_i, W_i) \mid i = 1 \dots k \}
公式含义:mount 操作把 Task 声明的 k 个工作空间一一挂载到容器内的对应路径。Task 写到这些路径的数据,就进入了共享仓库,其他任务可以读取。
  1. 任务与仓库建立映射将 Task 需要的每个工作空间 W_i 对应到容器内的一个目录 path_i。
    (pathi,Wi)(\mathrm{path}_i, W_i)
  2. 集合表示全部挂载花括号内的集合表示 Task 中所有挂载关系的总和,k 个声明就有 k 个映射。
    mount(Task,W)={… }\mathrm{mount}(\mathrm{Task}, W) = \{ \dots \}
  3. 目录即约定如果编译 Task 约定把产物写到 /workspace/output,打包 Task 也从同一路径读取,两者就对接上了——这是工位间协作的「通用语言」。

触发机制:传感器 Trigger

产线不能永远靠人工按开关。王厂长在传送带入口装了一批传感器:空瓶到位,自动启动灌装;订单系统弹出一条「加急 1000 箱」,产线自动插入一条临时任务。Tekton 把这些自动化启动的机制统称为 Trigger(触发)。

Trigger 是一组协同工作的组件。EventListener 是传感器本身——它暴露一个 HTTP 服务地址(Webhook),Git 提交、镜像推送、定时器都会向这个地址发「信号」;TriggerBinding 负责读懂信号:从 JSON 事件里提取 branch、commit SHA、镜像标签等关键字段;TriggerTemplate 是「排产模板」:接收提取出来的参数,统一生成一个 PipelineRun 开工单。三者串联,真正做到了「事件来了,流水线自动开跑」。

这个串联过程可以画成一条清晰的流水线:

有了 Trigger,DevOps 团队才能实现真正的 GitOps:开发者只需要把代码推到主干分支,剩下的构建、测试、部署全部由 Tekton 自动接管。厂长终于可以放心去吃午饭了——传感器看场子,流水线自己知道自己该干什么。

Event→BindingParams→TemplatePipelineRun\mathrm{Event} \xrightarrow{\mathrm{Binding}} \mathrm{Params} \xrightarrow{\mathrm{Template}} \mathrm{PipelineRun}
公式含义:原始事件(如 GitHub Webhook 推送)先进 Binding 单元做字段解析,产出结构化参数列表;这些参数再进入 Template 单元,最终渲染成一个完整的 PipelineRun 实例。
  1. 事件输入Event 是外部系统发出的原始信息,比如一次 git push 请求。
    Event={headers,body}\mathrm{Event} = \{\mathrm{headers}, \mathrm{body}\}
  2. Binding 解析TriggerBinding 按声明好的映射规则,从 Event 中抓取字段,产出键值对形式的参数。
    Params=Binding(Event)\mathrm{Params} = \mathrm{Binding}(\mathrm{Event})
  3. Template 渲染TriggerTemplate 把参数填入预定义的 PipelineRun 模板,实例化出真正的运行对象。
    PipelineRun=Template(Params)\mathrm{PipelineRun} = \mathrm{Template}(\mathrm{Params})

结果传递:质检标签 Results

可乐产线上,每个工位完成工作后,都要在瓶身上贴一张「质检标签」:灌装工位贴上「净含量 500ml」,压盖工位读到「已灌装」才动手压盖,装箱工位统计标签上的数据决定装箱数量。Tekton 里的 Results 就是这种跨工位传递的小体积文本结果。

Task 在 results 字段里声明自己要输出的结果名,执行时把值写入指定路径;下游 Task 通过一个特殊的引用语法把上游结果取进来用。比如编译 Task 声明了一个名叫 jar_path 的 result,值是一个 jar 包名,打包 Task 想引用它,只需写 $(results.compile.jar_path)。这句话可以拆成三部分理解:

Results 适合传递小体积元数据;大体积文件请走 Workspace。除了结果传递,Tekton 还支持 Matrix(矩阵):给同一 Task 的不同参数组合并行铺开多路执行,例如一组测试用例矩阵同时跑 20 个压测工位,最后汇总。质检标签 + 并行矩阵,让流水线既能灵活接力,又能大规模加速。

$(results.⟨task⟩.⟨result⟩)\$(results.\langle task \rangle.\langle result \rangle)
公式含义:$(...) 是引用前缀,results 声明这是取结果,中间两段分别指定「哪个任务」的「哪个结果」。Tekton 在调度前会把这个表达式替换成实际值。
  1. 引用前缀$( 和 ) 框出一个待替换的变量表达式,类似模板字符串的占位符。
    $( ⋯ )\$(\ \cdots\ )
  2. 任务标识<task> 段指向上游某个 Task 的名字,表示「我要拿那个工位的结果」。
    ⟨task⟩=compile\langle task \rangle = \mathrm{compile}
  3. 结果标识<result> 段指定该 Task 输出结果的名字,最终表达式被替换成真实文本。
    ⟨result⟩=jar_path⇒0\langle result \rangle = \mathrm{jar\_path} \Rightarrow \text{0}

实践落地:让工厂真正跑起来

理论讲完,王厂长要动手建厂了。第一步是安装 Tekton Pipelines:在 Kubernetes 集群里执行一条 kubectl apply 安装官方 manifests——相当于把整条产线的「操作系统」装好。装完就能用 kubectl 或 tkn 命令行工具与 Tekton 交互了。

第二步是编写最小示例。一个小到不能再小的流程:先定义一个 Task,执行一句问候;再定义一个 Pipeline 引用这个 Task;最后创建 PipelineRun 触发执行。YAML 长这样:

把这堆 YAML 用 kubectl apply -f 提交,几秒后 kubectl get pipelinerun 就能看到 Succeeded。如果失败,排查三板斧:tkn pipelinerun logs -f <run名> 看整条流水线日志;kubectl get taskrun 定位是哪个岗位单挂了;再 kubectl logs <pod> 看具体容器的输出。大多数问题出在镜像拉不下来、路径写错、参数没传全这三处。

最佳实践总结成四句话:Task 尽量小且单一职责(一个工位只干一件事);产物优先走 Results 传递,大文件走 Workspace;Pipeline 里用 runAfter 显式声明依赖,别指望「恰好顺序」;所有镜像固定 tag,保证可重复构建。厂长看着已经跑通的首条流水线,想起那条拆掉的铁板机器——现在换瓶型只需换工位卡片,加口味只需并联一串新工位,他第一次觉得,生产线的未来真的可以像乐高一样自由。

yaml28 行
apiVersion: tekton.dev/v1kind: Taskmetadata:  name: say-hellospec:  steps:    - name: greeting      image: alpine:3.18      script: |        echo "hello, tekton"---apiVersion: tekton.dev/v1kind: Pipelinemetadata:  name: hello-pipelinespec:  tasks:    - name: first      taskRef:        name: say-hello---apiVersion: tekton.dev/v1kind: PipelineRunmetadata:  name: hello-pipeline-runspec:  pipelineRef:    name: hello-pipeline

AI 应用场景

场景一:ML 模型的自动化训练与发布管道

阶段:模型训练与交付(MLOps 的 CI 环节)

解决的问题:传统 AI 团队训练模型靠「个人笔记本 + 手工拷贝」,数据集一换、参数一改,整个流程要手动重跑一遍,环境依赖极易出错。用 Tekton 把「数据预处理 → 模型训练 → 评估 → 导出模型」声明为四个 Task,每次代码提交自动触发整条流水线,模型产物写入共享 Workspace,评估指标通过 Results 传给通知服务。

具体案例:某推荐系统团队每天十几次实验提交,过去每周浪费 20 人时在「传数据、配环境、跑脚本」上;接入 Tekton 后,实验完全自动化,每个 commit 自动产出带评估分数的模型报告,效果比对一目了然。

场景二:微服务团队的 GitOps 多环境发布

阶段:持续交付(CD 环节)

解决的问题:微服务数量爆炸后,逐个 kubectl rollout 手工发布既慢又容易出错。Tekton Pipeline 构建「构建镜像 → 推送仓库 → 更新 K8s YAML → 滚动发布 → 健康检查」的完整链路,配合 Trigger 监听 Git 提交,实现「推代码即发布」。

具体案例:一个 30 人团队维护 40 个微服务,用 Tekton 加 Argo CD 梳理出 dev/staging/prod 三条 PipelineRun 模板,版本发布从人均 40 分钟降到全自动 5 分钟,回滚只需重新触发上一版本号。

场景三:多任务并行测试矩阵

阶段:质量保障与测试

解决的问题:单机串行跑几千条回归测试要数小时,而 Tekton 的 Matrix 能力可以把同一测试 Task 按不同参数(浏览器、数据集、分片)并行铺到多个节点,总耗时被关键路径大幅压缩。

具体案例:某电商平台在发版前需要跑 3000 个端到端用例,按 6 种浏览器 × 4 个数据分片组成 24 路矩阵并行执行,在集群 8 节点上把耗时从 3 小时压到 20 分钟。

Python 演示

python51 行
import time  class Task:    def __init__(self, name, steps):        self.name = name        self.steps = steps  # 每个元素: (container, function)     def run(self, workspace, params):        print(f"[Task] {self.name} 启动")        for container, action in self.steps:            print(f"  [Step] 容器={container} -> {action.__name__}")            time.sleep(0.05)            result = action(params)            workspace[self.name] = result        print(f"[Task] {self.name} 完成, Result={workspace[self.name]}")  class Pipeline:    def __init__(self, name, tasks):        self.name = name        self.tasks = tasks     def run(self, workspace):        print(f"=== Pipeline {self.name} 开始 ===")        for task in self.tasks:            task.run(workspace, {})        print(f"=== Pipeline {self.name} 成功 ===")  def compile_source(params):    return "app.jar"  def build_image(params):    return "registry.local/app:v1"  def run_tests(params):    return "tests-passed"  if __name__ == "__main__":    shared_workspace = {}    pipeline = Pipeline("build-test-pipeline", [        Task("compile", [("maven:3.8", compile_source)]),        Task("test", [("junit:5", run_tests)]),        Task("package", [("docker:20", build_image)]),    ])    pipeline.run(shared_workspace)    print("共享工作区最终内容:", shared_workspace)
目的:演示 Tekton 的核心抽象——Task 内多个 Step 顺序执行、多个 Task 组成 Pipeline、各 Task 通过共享 Workspace 传递产物。
  1. class Task模拟一个 Tekton Task,构造时接收工位名和步骤列表。
  2. def run(self, workspace, params)模拟 Task 执行:逐个 Step 跑,结果写入共享工作区。
  3. workspace[self.name] = result对应 Tekton 中 Task 把 Results 写入共享存储。
  4. class Pipeline模拟一条流水线,按顺序把 Task 串起来执行。
  5. def run(self, workspace)循环调用各 Task,对应 PipelineRun 的串行调度。
  6. compile_source / build_image / run_tests模拟每个 Step 里的容器动作函数。
  7. shared_workspace = {}模拟 Workspace:一个全流程共享的 Python 字典。
  8. pipeline.run(shared_workspace)相当于创建 PipelineRun 并等待完成。

常见误区

误区我以为写好了 Pipeline YAML 并 `kubectl apply` 之后,流水线就自动开始跑了,结果等半天什么都没发生,差点以为 Tekton 装坏了。

正解Pipeline 只是「图纸」,图纸不会自己生产。必须再创建一个 PipelineRun 实例(或配置 Trigger 自动创建),控制器才会真正调度容器执行。就像可乐厂的产线图纸挂在墙上,要等厂长开「生产工单」才会动工。

为何常见:习惯了「声明后即刻生效」的 Deployment 模型,容易忘掉 Tekton 的「声明与执行分离」设计,其实这正是为了支持同一图纸反复开单。

误区我以为 Task A 写完的文件会自动出现在 Task B 里,毕竟它们在同一台集群上,结果一运行 B 发现目录是空的。

正解每个 Task 的每个 Step 都是独立容器,默认彼此隔离,文件系统互不可见。要传文件必须挂载同一个 Workspace,或用 Results 传文本。就像两个相邻工位不会共享工具台,必须通过公共仓库转运物料。

为何常见:习惯把 CI 脚本当作「同一台机器上的 shell 脚本」,忽略了云原生容器隔离这一根本前提。

误区一个 Task 里的三个 Step 应该像 Shell 脚本里三行命令一样,能随意读取彼此设置的环境变量吧?

正解Task 内的多个 Step 也是不同的容器,虽然顺序执行,但环境变量、进程空间都不共享。共享数据要么通过 Workspace 落盘,要么通过显式的 params 传值。就好比灌装工位的注水机不会自动知道压盖工位的力矩设定,必须写在工位卡片(Task 配置)里。

为何常见:把「组合」误当成「合体」,实际上 Tekton 强调的最小隔离让每个 Step 的镜像和环境都彼此独立。

误区为了省事,我把数据库密码和产物路径都写在 Task YAML 里,反正集群内网别人看不到。

正解Task 应该参数化:密码放进 Kubernetes Secret 再挂载为 Workspace,路径通过 params 传入。这样 Task 才能跨团队、跨环境复用。就像工位卡片上不该写死「用老王的密码开仓库门」,而应写「凭门禁卡进仓库」。

为何常见:初学阶段往往只关注「跑通」,缺少可移植性思维,等要复用到另一个项目时就只能复制粘贴、到处改配置。

面试题

Q1. 声明了一个 Pipeline 资源后,要真正执行流水线必须创建哪个资源?

单选题 · easy

  • A.创建 Task 实例
  • B.修改 Pipeline 定义
  • C.创建 PipelineRun← 正确答案
  • D.部署事件监听器

答案:C。Pipeline 是「图纸」,只有创建 PipelineRun 这个「开工单」才会调度执行。Task 是组成图纸的工位;修改 Pipeline 只会改图纸;事件监听器属于 Trigger,只在配置了自动触发时才会间接创建 PipelineRun。

Q2. 同一个 Task 内的多个 Step 默认如何执行?

单选题 · easy

  • A.所有 Step 并行执行
  • B.按声明顺序执行← 正确答案
  • C.随机顺序执行
  • D.由镜像启动快慢决定

答案:B。Task 内 Step 是串行的:前一个 Step 必须以退出码 0 结束,后一个才启动。虽然它们在不同容器运行,但执行顺序由 steps 列表的次序严格决定,并行发生在 Task 与 Task 之间。

Q3. 两个 Task 之间需要共享一个较大的产物文件,推荐使用什么方式?

单选题 · mid

  • A.挂载同一个 Workspace← 正确答案
  • B.写进容器镜像缓存
  • C.用全局环境变量
  • D.让任务在同一 Pod 驻留

答案:A。Workspace 是共享存储抽象,适合大体积文件传递。容器镜像缓存不可写回;环境变量只能传小文本且不跨容器;多个 Task 默认在不同 Pod 运行,不会因 Task 在同一 Pod 就共享文件。

Q4. Results 机制适合传递什么类型的数据?

单选题 · mid

  • A.大型二进制数据集
  • B.小体积文本结果← 正确答案
  • C.整个容器镜像
  • D.数据库全量备份

答案:B。Results 把结果写入 K8s 资源状态中,适合 jar 包名、镜像 digest、测试统计数等小文本。大体积数据应放 Workspace,镜像和数据库备份属于外部存储系统管理范畴。

Q5. PipelineRun 的正确状态流转顺序是?

单选题 · hard

  • A.Pending → Succeeded → Failed
  • B.Pending → Running → Succeeded/Failed← 正确答案
  • C.Running → Pending → Succeeded
  • D.Failed → Running → Succeeded

答案:B。状态先 Pending 排队,容器启动后进入 Running,最终根据所有 Step 退出码进入唯一的终态 Succeeded 或 Failed。A 的 Failed 是从 Succeeded 之后再失败,不符合单终态语义;C、D 顺序颠倒。

Q6. 以下哪个不是 Tekton Workspace 的内置后端类型?

单选题 · mid

  • A.PersistentVolumeClaim
  • B.ConfigMap
  • C.EmptyDir
  • D.独立物理硬盘← 正确答案

答案:D。Tekton 支持 PVC、ConfigMap、EmptyDir、Secret 等 K8s 原生卷类型。独立物理硬盘不是 K8s 抽象,需先封装成 PV/PVC 才能使用。选 PVC 可持久保存,EmptyDir 则随运行结束释放。

Q7. Trigger 组件链中,负责从 Webhook 事件里提取字段的是哪个组件?

单选题 · hard

  • A.EventListener
  • B.TriggerTemplate
  • C.TriggerBinding← 正确答案
  • D.Interceptor

答案:C。EventListener 负责接收事件;TriggerBinding 负责把事件 JSON 映射成参数;TriggerTemplate 负责用参数渲染 PipelineRun。Interceptor 可选,用来过滤或修改事件,不属于必须的三件套。

Q8. 以下属于 Tekton 设计目标的有哪些?

多选题 · hard

  • A.与 Kubernetes 深度集成← 正确答案
  • B.Task 可复用与组合← 正确答案
  • C.流水线声明式定义← 正确答案
  • D.内置可视化 UI 平台

答案:ABC。Tekton 构建在 K8s CRD 之上,天然深度集成;Task 设计为独立可复用单元;流水线用声明式 YAML 描述。选项 D 错误,Tekton 是底层引擎,UI 由社区工具(如 Tekton Dashboard)另行提供。

Q9. 创建 PipelineRun 之前,通常需要满足哪些前提?

多选题 · mid

  • A.引用的 Task 已存在← 正确答案
  • B.所需参数已经提供← 正确答案
  • C.Workspace 已绑定后端← 正确答案
  • D.镜像已推送到本地 Docker

答案:ABC。Task 不存在会导致运行失败;参数缺失会校验不过;Task 声明了 Workspace 就必须在 PipelineRun 里绑定实际存储。D 错误:Kubernetes 集群从远程仓库拉镜像,和本地 Docker 无关。

Q10. 下列属于 Tekton 核心概念的有哪些?

多选题 · easy

  • A.Task 任务单元← 正确答案
  • B.PipelineRun 运行实例← 正确答案
  • C.Workspace 共享工作区← 正确答案
  • D.Deployment 无状态应用

答案:ABC。Task 是最小工作单元,PipelineRun 是执行实例,Workspace 是共享存储,三者是 Tekton 核心资源。Deployment 是 K8s 原生工作负载概念,不属于 Tekton 流水线的核心概念。