当前位置:首页 > 文章列表 > 科技周边 > 业界新闻 > Kubernetes 1.35 sidecar原生 sidecar 稳定后工作负载怎样调整

Kubernetes 1.35 sidecar原生 sidecar 稳定后工作负载怎样调整

来源:17golang原创 2026-11-04 14:45:22 0浏览 收藏

Kubernetes 1.35 里,原生 sidecar 已经不应该再被当成“需要额外开关才能试用”的实验能力:官方文档标明它从 v1.33 起稳定,原来的 SidecarContainers feature gate 也已经锁定。真正需要调整的是工作负载模板,把辅助容器的启动顺序、就绪条件、终止顺序和 Job 完成语义写清楚。

我在迁移这类 Pod 时会先问一个问题:这个辅助进程是否必须先于应用启动、持续伴随应用,并且在应用结束后再退出?如果三个条件都成立,才优先使用原生 sidecar;只需要一次性准备文件的仍然是普通 init 容器,不要求顺序的并行进程则继续放在 containers。

最小改法是把长驻辅助容器从 containers 移到 initContainers,并设置 restartPolicy: Always;然后为真正的依赖补上探针,分别审查 Deployment 和 Job 的退出逻辑。

官方地址:https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/

先把 sidecar 的职责放回 Pod 生命周期

普通容器并排放在 spec.containers 时,Kubernetes 不会替你表达“谁先启动、谁最后退出”。很多旧模板只能靠入口脚本轮询本地端口,或者让 sidecar 自己无限等待。原生 sidecar 的关键区别在于:它仍写在 initContainers,但带有容器级 restartPolicy: Always,启动后保持运行,同时保留 init 容器的有序启动语义。

原生 sidecar 与常规 init 和应用容器的启动顺序结构说明图
图1:结构说明图,展示原生 sidecar 的启动顺序、就绪关系和共享 Pod 资源。

例如日志转发器需要在应用产生日志前就位,但应用又不应该等待一个永远不会结束的普通 init 容器。可以这样改写模板:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: report-api
spec:
  selector:
    matchLabels:
      app: report-api
  template:
    metadata:
      labels:
        app: report-api
    spec:
      # 只做一次性文件准备的容器仍然是普通 init 容器
      initContainers:
        - name: prepare-config
          image: busybox:1.36
          command: ["sh", "-c", "cp /input/config.yaml /work/config.yaml"]
          volumeMounts:
            - name: work
              mountPath: /work
        # restartPolicy: Always 让这个 init 容器成为原生 sidecar
        - name: log-forwarder
          image: example/log-forwarder:1.4
          restartPolicy: Always
          startupProbe:
            httpGet:
              path: /healthz
              port: 15020
            failureThreshold: 30
            periodSeconds: 2
          readinessProbe:
            httpGet:
              path: /ready
              port: 15020
            periodSeconds: 2
          volumeMounts:
            - name: work
              mountPath: /var/log/app
      containers:
        - name: api
          image: example/report-api:2.8
          # 应用与 sidecar 通过同一个 Pod 网络和 volume 协作
          volumeMounts:
            - name: work
              mountPath: /var/log/app
      volumes:
        - name: work
          emptyDir: {}

这里的重点不是复制字段,而是把职责拆开:prepare-config 做完就退出,log-forwarder 保持运行,api 只承担业务。原生 sidecar 和应用容器共享 Pod 的网络命名空间,也可以通过 emptyDir 共享文件,但这不意味着它们的资源请求可以省略。

候选方案怎么选:原生 sidecar、普通容器还是 init

稳定之后最容易出现的误区,是把所有辅助进程都迁移到原生 sidecar。我的做法是先按约束筛选,而不是按“新能力”筛选。

场景推荐写法理由不必迁移的情况
一次性下载配置或生成目录普通 init 容器完成后退出,应用只消费结果需要持续刷新配置
长驻日志、代理或同步辅助进程原生 sidecar可表达先启动、伴随运行、最后退出不依赖启动顺序且与应用完全独立
两个同等重要的服务共同决定 Pod 健康普通容器不需要 init 阶段的有序保证辅助进程必须先就绪
一次性 Job 中的日志收集原生 sidecar主容器完成后 sidecar 不会阻塞 Job 完成收集结果必须在主容器退出前落盘

如果 sidecar 只是在同一个 Pod 里“顺手启动”,但应用并不等待它,也没有共享数据或生命周期要求,继续使用普通容器反而更直白。稳定能力的价值是准确表达约束,而不是增加模板字段。

把“进程已启动”改成“服务已就绪”

原生 sidecar 会在其启动状态满足条件后允许后续 init 容器继续推进。没有 startup probe 时,容器里有进程运行就可能被认为已经 started;如果应用依赖 sidecar 的 HTTP 接口、证书或本地 socket,仅仅看到进程存在并不够。

迁移时应把等待逻辑从应用入口脚本移到 sidecar 的探针。startupProbe 适合描述“初始化完成”,readinessProbe 适合描述“现在可以接收依赖请求”。如果 Pod 的 Ready 状态必须反映 sidecar 的工作状态,就给 sidecar 配置 readiness probe;否则 sidecar 短暂未就绪可能被应用误判成自身故障。

# 查看 Pod 中 init、sidecar 和应用容器的状态字段
kubectl get pod report-api-0 -o jsonpath='{range .status.initContainerStatuses[*]}{.name}{" started="}{.started}{" ready="}{.ready}{"\n"}{end}'

# 查看事件,区分探针失败、镜像拉取和真正的调度问题
kubectl describe pod report-api-0

上面的命令只读状态,不改变工作负载。排查时我会先看 started、ready 和事件时间,再判断是探针路径错误、端口未监听、镜像问题,还是变更准入后字段被抹掉。

Deployment 和 Job 要分别调整

长驻 Deployment 和一次性 Job 的生命周期目标不同,不能共享一套“等待 sidecar 退出”的脚本。

Deployment 与 Job 使用原生 sidecar 时的终止和完成关系说明图
图2:生命周期说明图,对比 Deployment 与 Job 使用原生 sidecar 时的结束语义。

对于 Deployment,Pod 终止时 kubelet 会先让主要应用容器结束,再按相反顺序处理 sidecar。这样日志转发或代理有机会处理应用最后产生的数据,但 sidecar 不应承担不可丢失的事务提交,真正需要持久化的结果仍要落到合适的外部存储。

对于 restartPolicy: Never 或 OnFailure 的 Job,原生 sidecar 不会因为自己持续运行而阻止 Pod 完成。主容器完成后,Job 可以进入完成状态;这正是迁移时最值得删除的旧逻辑:不要再让主容器等待一个永不退出的 sidecar,也不要为“sidecar 最后退出”额外写一个共享信号文件来欺骗 Job 控制器。

apiVersion: batch/v1
kind: Job
metadata:
  name: export-report
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: exporter
          image: example/exporter:3.2
          command: ["/bin/export"]
          # 主容器完成后,Job 可以结束,不等待 sidecar 自己退出
      initContainers:
        - name: upload-log
          image: example/log-uploader:1.4
          restartPolicy: Always
          command: ["/bin/sidecar"]
          # sidecar 只负责伴随收集,不能替代结果持久化
          volumeMounts:
            - name: logs
              mountPath: /var/log/export
      volumes:
        - name: logs
          emptyDir: {}

如果上传动作必须确认成功后 Job 才算成功,就把“确认上传”设计成主容器的显式步骤,或者使用独立的后处理工作流,不要把业务成功条件藏在 sidecar 的退出时机里。

稳定能力落地前,先检查三个兼容边界

原生 sidecar 稳定不等于所有集群周边组件都已经正确处理该字段。迁移前我会重点检查以下边界:

  1. 控制面和节点版本:确保 API Server、kubelet 与实际使用的客户端能够识别并保留 init 容器上的 restartPolicy。不要只看本地 kubectl 版本。
  2. 变更准入与注入器:全量更新 Pod 的 webhook、模板渲染器或旧客户端可能在重写对象时丢弃未知字段。用 kubectl describe pod 查看变更后的最终对象,而不是只看 Helm 输入文件。
  3. 资源与 QoS:sidecar 仍然消耗资源。Pod 的有效请求会同时受到 init/sidecar 阶段和运行阶段容器请求影响,不能因为 sidecar 放到了 initContainers 就把它当作零成本。

若注入器同时保留旧式普通容器 sidecar 和原生 sidecar,可能造成重复进程和重复资源请求。迁移方案必须明确“旧模式关闭条件”,并准备一个只删除新字段、恢复旧模板的回滚版本。

我的迁移决策表

最后可以用下面的规则快速判断,不必因为版本升级就全量改写:

问题是否
辅助容器必须在应用前启动并保持运行?继续判断探针和共享资源,优先原生 sidecar普通容器或普通 init 更简单
主容器完成后,辅助进程还要短暂收尾?使用原生 sidecar,删除 Job 等待脚本按应用自身退出即可
注入器会完整重写 Pod 对象?先升级或审查注入器字段保留能力可以从单个工作负载灰度
sidecar 的就绪决定应用能否接收请求?补 readinessProbe 并观察 Pod Ready只需要 startupProbe 或不设置依赖探针

一句话总结:Kubernetes 1.35 的原生 sidecar 适合把“伴随关系”交给 Pod 生命周期管理,但不替你定义业务成功、数据持久化和组件兼容。先按职责选择容器类型,再把探针、Job 完成条件、资源请求和准入链路一起迁移,工作负载才会真正变得可维护。

相关问题

  • 原生 sidecar 为什么要写在 initContainers 而不是 containers?
  • Job 使用原生 sidecar 后,主容器完成时还需要显式关闭 sidecar 吗?
  • sidecar 的 readinessProbe 会不会影响整个 Pod 的 Ready 状态?
  • 旧版 webhook 丢掉 restartPolicy: Always 时应该从哪里排查?
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
OpenTelemetry OBI 1.0稳定配置发布后迁移关注什么OpenTelemetry OBI 1.0稳定配置发布后迁移关注什么
上一篇
OpenTelemetry OBI 1.0稳定配置发布后迁移关注什么
GitHub Actions lockfiles工作流锁文件能力解决什么依赖风险
下一篇
GitHub Actions lockfiles工作流锁文件能力解决什么依赖风险
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    881次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    879次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    963次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    942次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    768次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码