当前位置:首页 > 文章列表 > 科技周边 > 业界新闻 > Kubernetes 原生 Sidecar Containers 稳定后怎样理解生命周期

Kubernetes 原生 Sidecar Containers 稳定后怎样理解生命周期

来源:17golang原创 2026-11-03 16:08:05 0浏览 收藏

Kubernetes 原生 Sidecar Containers 稳定后,最容易混淆的一点是:它不是把一个普通辅助容器随手放进 containers,而是把它声明在 initContainers 中,再设置容器级 restartPolicy: Always。这样 Kubernetes 既保留初始化容器的有序启动语义,又允许这个辅助容器在应用运行期间持续工作。

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

Sidecar Containers 自 Kubernetes v1.33 起为 Stable。它会先按 init container 的顺序完成启动判断,随后与应用并行运行;Pod 终止时,应用容器先停止,sidecar 再按声明顺序的反向顺序关闭。这个语义特别适合日志转发、代理和数据同步等伴随服务。

先分清三类容器的职责

在同一个 Pod 里,普通 init container 只负责启动阶段的准备工作,成功退出后才会让后续容器继续;应用容器承载主要业务;原生 sidecar 则处在两者之间:它用 init container 的声明位置获得启动顺序,又通过容器级重启策略保持运行。

类型声明位置生命周期重点典型用途
普通 init containerinitContainers启动阶段执行,结束后退出初始化目录、生成配置
原生 sidecarinitContainers + restartPolicy: Always启动后持续运行,与应用并行日志转发、代理、同步
应用容器containers承载主要业务逻辑接口服务、批处理任务
Kubernetes Pod 中应用容器、原生 sidecar、共享网络和共享卷的关系说明图
图1:Kubernetes Pod 内的容器边界与共享关系说明图,不是截图或运行证据。

最小 YAML 关键在 initContainers

声明原生 sidecar 时,决定性字段不是容器名称,而是它位于 initContainers,并拥有自己的 restartPolicy: Always。下面的示例把应用写入共享卷,sidecar 持续读取这个文件并承担日志转发的角色:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sidecar-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sidecar-demo
  template:
    metadata:
      labels:
        app: sidecar-demo
    spec:
      containers:
        - name: app
          image: alpine:3.20
          command: ["sh", "-c"]
          # 应用把示例日志写入与 sidecar 共享的目录。
          args: ["while true; do date >> /opt/logs/app.log; sleep 5; done"]
          volumeMounts:
            - name: shared-logs
              mountPath: /opt/logs
      initContainers:
        - name: log-sidecar
          image: alpine:3.20
          restartPolicy: Always
          command: ["sh", "-c"]
          # Always 让这个 init container 启动后继续运行,成为原生 sidecar。
          args: ["tail -F /opt/logs/app.log"]
          volumeMounts:
            - name: shared-logs
              mountPath: /opt/logs
      volumes:
        - name: shared-logs
          emptyDir: {}
          # emptyDir 只用于展示同一 Pod 内的共享文件边界。

这里的 emptyDir 只是为了让两个容器看到同一份文件。实际系统可以替换为合适的卷类型,但不要把“共享卷”误解为跨 Pod 的持久化存储。

启动时由 started 决定下一个 init container

普通 init container 必须完成后才会进入下一项;sidecar 则只要被 Kubernetes 判定为已经 started,就可以让后面的 init container 继续。没有配置 startupProbe 时,容器内已有进程运行通常会让 started 变为 true;配置了启动探针后,则以启动探针成功为准。

这带来一个重要结果:sidecar 可以在初始化链路中占据一个有序位置,但不会因为自己长期运行而把后续初始化永久堵住。若配置了 readinessProbe,该探针结果还会参与 Pod 的 Ready 状态,因此“已经 started”和“已经对外就绪”是两个不同判断。

initContainers:
  - name: prepare-config
    image: busybox:1.36
    command: ["sh", "-c"]
    # 先生成 sidecar 和应用都会读取的配置文件。
    args: ["echo ready > /work/status"]
    volumeMounts:
      - name: work
        mountPath: /work
  - name: proxy-sidecar
    image: envoyproxy/envoy:v1.31-latest
    restartPolicy: Always
    startupProbe:
      httpGet:
        path: /ready
        port: 9901
      # 启动探针成功后,后续 init container 才能继续。
      periodSeconds: 2
    readinessProbe:
      httpGet:
        path: /ready
        port: 9901
      # 就绪探针决定 sidecar 是否把 Pod 标记为 Ready。
      periodSeconds: 5

如果 sidecar 需要先完成自身初始化,再允许下一项执行,优先使用 startupProbe 表达这个门槛;如果只是希望控制 Pod 对外是否可用,则配置 readinessProbe。二者不要混成一个“启动成功”概念。

运行期间并行,终止时应用先停

sidecar 被标记为 started 后,会与应用容器并行运行。它们位于同一 Pod,因此共享网络命名空间,也可以按配置共享卷。修改 sidecar 镜像通常只会触发该容器重启,不会因为 sidecar 镜像变化就让整个 Pod 重新启动。

Pod 终止时,kubelet 会先等待应用容器停止,再处理 sidecar。多个 sidecar 按它们在 initContainers 中的声明顺序反向关闭,这样后声明的辅助服务先退出,前面的服务可以继续支撑尚未结束的组件。

还要注意优雅终止时间的现实边界:如果其他容器已经消耗了 Pod 的终止宽限时间,sidecar 可能来不及优雅退出而收到 SIGTERM,随后收到 SIGKILL。因此,sidecar 在 Pod 结束时出现非零退出码并不必然表示业务故障,外部工具需要结合 Pod 终止原因判断。

Kubernetes 原生 sidecar 从 started、就绪到应用先停和反向关闭的生命周期说明图
图2:原生 sidecar 的启动判断、持续运行和反向关闭语义说明图,不是截图或运行证据。

Job 场景不会被长期运行的 sidecar 卡住

在 Job 中,应用容器完成任务后,原生 sidecar 不会因为仍在运行就阻止 Job 完成。这个行为适合“主任务写结果、sidecar 持续采集或转发”的批处理场景。关键是要让应用容器的退出真正代表任务完成,并把 sidecar 当成伴随服务,而不是第二个必须独立完成的主任务。

spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: worker
          image: alpine:3.20
          command: ["sh", "-c"]
          # 主容器完成工作后退出,Job 可以据此判断任务完成。
          args: ["echo result > /work/result.txt"]
      initContainers:
        - name: collector
          image: alpine:3.20
          restartPolicy: Always
          command: ["sh", "-c"]
          # sidecar 持续观察共享目录,但不承担 Job 的完成信号。
          args: ["tail -F /work/result.txt"]

稳定后的兼容与采用边界

Sidecar Containers 首次在 Kubernetes v1.28 提供,v1.29 起默认启用相关能力,v1.33 起标记为 Stable。稳定后不能再通过 feature gate 关闭;即使显式设置相关 gate,Kubernetes 也会忽略该设置而不报错。

如果集群仍低于支持容器级 restartPolicy 的版本,不要把同一份 YAML 直接下发。可以退回普通的多个应用容器模型,但这会失去明确的 init 顺序和 sidecar 终止语义。迁移时重点检查以下项目:

  • 集群版本是否支持在 initContainers 中给单个容器设置 restartPolicy。
  • sidecar 的启动完成条件是进程启动,还是 startupProbe 成功。
  • 是否需要用 readinessProbe 影响 Pod 的 Ready 状态。
  • 日志、代理或同步服务是否真的适合与主容器共享网络和卷。
  • Pod 的资源预算是否把 sidecar 的长期运行成本算进去。

资源计算会影响调度,不只是写法变化

sidecar 虽然写在 initContainers,但它并不是一次性资源。Kubernetes 计算 Pod 的有效资源请求和限制时,会比较所有非 init 容器的合计值与 init 容器的有效值,取其中较高者,再结合 Pod overhead。sidecar 的资源声明因此可能直接影响调度、配额和 QoS,不应只按“辅助进程很轻”来估算。

判断问题采用原生 sidecar 的信号需要谨慎的信号
是否依赖启动顺序需要先启动代理或采集器,再进入下一阶段所有容器无先后关系
是否需要长期运行应用运行期间一直提供伴随服务只需执行一次准备动作
是否共享数据通过同一 Pod 的网络或卷交互需要跨 Pod 持久化或独立扩缩容
是否是批任务主容器退出应能让 Job 完成sidecar 自己也承担独立业务结果

一句话总结:原生 sidecar 解决的是“有序启动、持续伴随、可控终止”这一组生命周期问题,不是把所有辅助服务都塞进 initContainers 的通用替代方案。

相关问题

Sidecar 为什么不直接写在 containers 里?

普通应用容器没有原生 sidecar 的 init 顺序和反向终止语义。写入 initContainers 并设置 restartPolicy: Always,才能表达“先完成启动判断、再持续运行”的关系。

readinessProbe 和 startupProbe 应该怎么选?

startupProbe 用于决定容器何时算 started,影响后续 init container 是否继续;readinessProbe 用于表达是否应该把 Pod 视为就绪。一个控制启动门槛,一个控制就绪状态。

sidecar 退出码非零一定是故障吗?

不一定。Pod 终止时 sidecar 可能因宽限时间耗尽而被强制结束,外部系统需要结合终止场景,而不是只看退出码。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis ACL 怎样限制客户端只能访问指定命令Redis ACL 怎样限制客户端只能访问指定命令
上一篇
Redis ACL 怎样限制客户端只能访问指定命令
小微企业怎样判断能否享受六税两费减免
下一篇
小微企业怎样判断能否享受六税两费减免
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    859次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    864次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    940次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    919次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    750次使用