3. 发布流水线典型流程:从代码提交到Pod就绪的全链路分解

在K8s平台中,一次标准的发布流水线通常涉及代码仓库、CI系统、镜像仓库、K8s API Server、etcd、Scheduler、Kubelet等多个组件。理解这条链路上的每一个环节,是后续通过etcd日志进行异常定位的基础。本章将全链路分解为8个关键阶段,并标注每个阶段与etcd的交互点。

3.1 全链路阶段总览

下表列出了从开发者提交代码到Pod最终进入Ready状态的完整阶段、核心操作及etcd参与情况:

阶段 核心操作 etcd交互点 典型耗时
1. 代码提交与CI构建 Git Push → CI触发编译、单元测试、镜像打包 无直接交互 1~10 min
2. 镜像推送与版本标记 Docker Push 至镜像仓库,生成唯一镜像摘要 无直接交互 30 s~3 min
3. 更新Deployment资源 kubectl set image / 调用API修改Deployment镜像版本 写入:Deployment对象更新 1~2 s
4. ReplicaSet版本演进 Deployment Controller创建新RS,期望副本数逐步迁移 写入:RS对象创建;读取:监听Deployment变化 1~5 s
5. Pod调度决策 Scheduler为未绑定Pod选择最优Node,写入绑定信息 写入:Pod绑定记录;读取:Node资源状态 100 ms~5 s
6. Kubelet拉取镜像 Kubelet根据PodSpec拉取新版本镜像 无直接交互(镜像拉取状态通过Pod Status间接写入) 10 s~2 min
7. 容器启动与健康检查 CRI创建容器,执行ReadinessProbe/LivenessProbe 写入:Pod状态更新(Conditions) 5~30 s
8. Pod就绪与流量接入 Endpoint Controller更新Service Endpoints,流量引入新Pod 写入:Endpoints对象更新 1~3 s
关键洞察: 阶段3、4、5、7、8均涉及etcd的写入操作。当发布流水线出现异常时,etcd中对应对象的resourceVersion跳跃、conditions字段缺失或binding记录异常,往往是根因定位的第一手线索。

3.2 核心阶段详细分解

3.2.1 阶段3:更新Deployment资源

这是流水线从CI/CD工具进入K8s集群的第一个etcd写入点。操作通常通过kubectl set image deployment/xxx image=new-version或直接调用API完成。

  • etcd写入内容:Deployment的spec.template.spec.containers[].image字段被修改,同时metadata.generation自增。
  • 异常样本:如果此时etcd写入超时或返回EtcdError: leader changed,Deployment将停留在旧版本,流水线卡死。

3.2.2 阶段5:Pod调度决策

Scheduler通过Watch机制从etcd获取未调度的Pod(spec.nodeName为空),经过预选、优选后,将Pod与Node的绑定关系写入etcd。

  • etcd写入内容:Pod对象的spec.nodeName字段被赋值,同时status.conditions中新增PodScheduled=True。
  • 异常样本:若Scheduler因Node资源不足无法调度,Pod的status.conditions中会出现Unschedulable状态,etcd中该Pod长时间处于Pending。

3.2.3 阶段7:容器启动与健康检查

Kubelet在节点上启动容器后,会持续执行ReadinessProbe。当探测成功时,Kubelet将Pod的status.conditions中的Ready条件置为True,并写入etcd。

  • etcd写入内容:Pod的status.phase从Running变为Running(不变),但status.conditions[].type=Ready变为True。
  • 异常样本:镜像拉取失败或启动命令错误会导致Ready条件长期为False,etcd中Pod的containerStatuses[].state.waiting.reason字段会记录ImagePullBackOff或CrashLoopBackOff。

3.3 全链路数据流与etcd交互SVG

下图展示了从代码提交到Pod就绪的完整数据流,并重点标注了etcd在其中的读写位置:

发布流水线全链路与etcd交互图 发布流水线全链路与etcd交互图 1. 代码提交 2. CI构建+镜像 3. 更新Deployment 4. RS版本演进 5. Pod调度 6. Kubelet拉镜像 7. 健康检查 8. Pod就绪 etcd 数据存储 Deployment ReplicaSet Pod (Pending) Pod (Running) Endpoints 图例说明: 无etcd直接交互阶段(CI/镜像构建) 涉及etcd写入阶段(Deployment/RS/Pod状态更新) 镜像拉取阶段(状态通过Pod Status间接写入etcd) 最终就绪阶段(Endpoints写入etcd,流量接入)

3.4 关键时间窗口与etcd版本号变化

在发布过程中,etcd中对象的resourceVersion是追踪变更顺序的核心指标。以下是一个典型发布过程中Deployment及其子对象在etcd中的版本号变化示例:

# 初始状态:Deployment v1,RS v1,Pod v1~v3
/deployments/nginx    resourceVersion: 1000
/replicasets/nginx-xxx  resourceVersion: 1001
/pods/nginx-xxx-a      resourceVersion: 1002

# 阶段3:更新Deployment镜像(etcd写入)
/deployments/nginx    resourceVersion: 1050  ← 版本跳跃

# 阶段4:Controller创建新RS(etcd写入)
/replicasets/nginx-yyy  resourceVersion: 1051  ← 新RS出现

# 阶段5:Scheduler绑定Pod(etcd写入)
/pods/nginx-yyy-a      resourceVersion: 1052  ← nodeName被赋值

# 阶段7:Kubelet更新Pod状态(etcd写入)
/pods/nginx-yyy-a      resourceVersion: 1060  ← Ready=True
异常定位要点: 如果发布卡在“Pod启动中”阶段,应重点检查etcd中Pod对象的resourceVersion是否长时间未变化。若超过30秒无更新,通常意味着Kubelet未成功将状态写回etcd,可能原因包括:镜像拉取阻塞、CNI网络插件异常、或etcd写入性能瓶颈。

3.5 流水线各阶段异常与etcd日志的对应关系

下表总结了发布流水线各阶段常见异常在etcd日志中的典型表现,为后续章节的根因定位提供直接映射:

流水线阶段 常见异常 etcd日志/对象特征
3. 更新Deployment API Server超时、版本冲突 etcd日志出现 etcdserver: request timed out;Deployment的metadata.generation未递增
4. RS版本演进 Controller未创建新RS etcd中无新的RS对象出现;Deployment的status.observedGeneration落后于generation
5. Pod调度 资源不足、节点故障 Pod的status.conditions包含Unschedulable;etcd中该Pod的spec.nodeName为空
6. 拉取镜像 镜像不存在、仓库认证失败 Pod的status.containerStatuses[].state.waiting.reason为ImagePullBackOff;etcd中Pod状态频繁更新但Ready始终为False
7. 健康检查 启动命令错误、探针配置不当 Pod的status.conditions[].type=Ready为False且lastTransitionTime长时间未更新;etcd中restartCount持续递增
8. Pod就绪 Endpoint未更新、Service选择器不匹配 etcd中Endpoints对象的subsets[].addresses不包含新Pod IP;Service的status.loadBalancer.ingress为空

3.6 全链路时序与etcd写入点SVG

下图以时间轴形式展示发布流水线各阶段与etcd写入事件的对应关系,帮助理解异常发生时etcd日志的时间戳上下文:

发布流水线时序与etcd写入点 发布流水线时序与etcd写入点 T0 T1 T2 T3 T4 T5 更新Deployment etcd写入 创建ReplicaSet etcd写入 调度Pod etcd写入 拉取镜像 无etcd写入 Pod就绪 etcd写入 异常场景与etcd日志关联示例: • 场景A:T1~T2之间etcd日志出现 "etcdserver: request timed out" → Deployment更新失败,流水线卡在T1。 • 场景B:T3之后Pod的 resourceVersion 超过30秒未变化 → Kubelet未写回状态,可能镜像拉取阻塞。 • 场景C:T5时etcd中Endpoints对象 subsets 为空 → Service选择器不匹配或Endpoint Controller异常。 • 场景D:整个流程中etcd的 db.totalSize 突增且伴随 fsync 延迟 → 磁盘IO成为瓶颈,影响所有写入阶段。

3.7 本章小结

发布流水线的全链路分解揭示了以下核心结论:

  • etcd是发布流水线的“状态中枢”:8个阶段中有5个阶段直接依赖etcd的写入操作,任何etcd性能问题或写入失败都会导致流水线阻塞。
  • resourceVersion是追踪异常的时间线:通过对比Deployment、RS、Pod等对象的版本号变化,可以快速定位异常发生的具体阶段。
  • Pod的status.conditions是异常诊断的“第一现场”:Unschedulable、ImagePullBackOff、CrashLoopBackOff等状态直接反映在etcd存储的Pod对象中。