在 Kubernetes 1.33 中,一个非常值得关注的特性是 Sidecar Containers 正式进入 Stable。这意味着 Kubernetes 对 Sidecar 模式有了更加明确、原生、稳定的生命周期管理能力。

过去我们当然也能在一个 Pod 里放多个容器,比如一个业务容器加一个日志采集容器、代理容器、监控容器。但这种“传统 Sidecar”本质上只是普通容器并排运行,Kubernetes 并不知道哪个是主容器,哪个是辅助容器,也不能很好地表达它们之间的启动顺序和退出关系。

到了 Kubernetes 1.33,Sidecar 不再只是“大家约定俗成的用法”,而是成为 Kubernetes 原生支持的一种容器生命周期模型。


一、Sidecar 是什么?

Sidecar 指的是和主应用容器运行在同一个 Pod 中的辅助容器。

它通常不承载核心业务逻辑,而是为主容器提供增强能力,比如:

  • 日志采集

  • 指标上报

  • 服务网格代理

  • 安全代理

  • 配置同步

  • 数据预处理

  • 本地缓存

  • 文件监听和同步

比如一个 Web 应用负责处理 HTTP 请求,而另一个容器负责把日志文件实时采集到远程日志系统,这个日志采集容器就是 Sidecar。

Sidecar 的核心价值是:把通用的基础设施能力从业务代码中剥离出来,让主应用更专注于业务本身。


二、传统 Sidecar 的问题

在 Kubernetes 原生 Sidecar 出现之前,我们通常会这样写:

apiVersion: v1
kind: Pod
metadata:
  name: old-sidecar-demo
spec:
  containers:
    - name: app
      image: my-app:1.0
    - name: log-agent
      image: log-agent:1.0

这种方式虽然简单,但有几个明显问题。

1. 启动顺序不明确

applog-agent 都是普通容器,Kubernetes 不保证 log-agent 一定先于 app 完全准备好。

如果主应用启动时就依赖代理、日志采集器或配置同步器,可能会出现主容器已经启动,但辅助容器还没准备好的问题。

2. Job 场景容易被 Sidecar 卡住

对于 Job 来说,主容器执行完任务后,Pod 应该进入完成状态。

但如果 Sidecar 是普通容器,并且它一直运行,比如日志采集器一直 tail -f,那么整个 Pod 可能无法正常完成,Job 也可能被卡住。

这在批处理、AI 训练、数据处理任务中尤其常见。

3. 生命周期语义不清晰

传统写法里,Kubernetes 并不知道哪个容器是主容器,哪个容器是辅助容器。

它只能看到一组普通容器。

这就导致启动、终止、重启、健康检查、资源计算等行为都缺少更精确的语义表达。


三、Kubernetes 1.33 的原生 Sidecar 是怎么实现的?

Kubernetes 1.33 并没有新增一个 sidecars 字段,而是采用了一个很巧妙的设计:

原生 Sidecar 是一种特殊的 initContainer。

具体来说,就是在 initContainers 中定义容器,并设置:

restartPolicy: Always

示例:

apiVersion: v1
kind: Pod
metadata:
  name: native-sidecar-demo
spec:
  initContainers:
    - name: log-agent
      image: busybox:latest
      restartPolicy: Always
      command: ["sh", "-c", "tail -F /var/log/app.log"]
      volumeMounts:
        - name: logs
          mountPath: /var/log

  containers:
    - name: app
      image: busybox:latest
      command: ["sh", "-c", "while true; do echo hello >> /var/log/app.log; sleep 5; done"]
      volumeMounts:
        - name: logs
          mountPath: /var/log

  volumes:
    - name: logs
      emptyDir: {}

这里的 log-agent 看起来写在 initContainers 里,但因为它设置了 restartPolicy: Always,Kubernetes 会把它识别为原生 Sidecar。

它和普通 initContainer 最大的区别是:

  • 普通 initContainer:执行完成后退出,然后主容器启动

  • 原生 Sidecar:先启动,但不会退出,会继续伴随主容器运行


四、原生 Sidecar 的生命周期

原生 Sidecar 的生命周期可以简单理解为:

启动阶段:
普通 initContainer -> 原生 Sidecar -> 主应用容器

运行阶段:
原生 Sidecar 和主应用容器一起运行

终止阶段:
主应用容器先退出 -> Sidecar 再退出

这解决了很多过去不好处理的问题。

1. Sidecar 可以先于主容器启动

因为它定义在 initContainers 中,所以天然拥有 initContainer 的顺序语义。

如果你希望代理、日志采集器、配置同步器先启动,再启动主应用,原生 Sidecar 会比普通多容器 Pod 更适合。

2. Sidecar 可以持续运行

虽然它是 initContainer 的一种特殊形式,但它不会像普通 initContainer 一样执行完成后退出,而是会在整个 Pod 生命周期中持续运行。

这就非常适合日志采集、网络代理、监控 Agent 这类长期辅助任务。

3. Sidecar 不会阻塞 Job 完成

这是原生 Sidecar 很重要的改进。

在 Job 场景中,只要主容器执行完成,Sidecar 不会阻止 Job 完成。

这对于批处理任务非常关键。比如主容器负责跑数据处理任务,Sidecar 负责日志上传或指标上报。过去 Sidecar 如果一直运行,Job 可能无法结束;现在 Kubernetes 能理解它是辅助容器,不会让它错误地阻塞任务完成。


五、健康检查也更合理了

原生 Sidecar 支持常见的探针能力:

  • startupProbe

  • readinessProbe

  • livenessProbe

这让 Sidecar 不只是“启动了就算成功”,而是可以明确表达它是否已经准备好、是否仍然健康。

例如:

initContainers:
  - name: proxy
    image: my-proxy:1.0
    restartPolicy: Always
    startupProbe:
      httpGet:
        path: /healthz
        port: 15000
      failureThreshold: 30
      periodSeconds: 2

这里要特别注意:

如果主应用强依赖 Sidecar 已经可用,建议使用 startupProbe 来控制启动顺序。

readinessProbe 更多影响的是 Pod 是否 Ready,不一定能阻止主容器启动;而 startupProbe 可以更准确地表达“Sidecar 还没准备好,后续容器先别启动”。


六、原生 Sidecar 适合哪些场景?

1. 日志采集

主容器写日志到共享卷,Sidecar 负责读取并发送到日志系统。

app container -> /var/log/app.log -> log sidecar -> log backend

2. 服务网格代理

比如 Envoy、Istio Proxy 这类代理容器,需要在业务流量进入或发出之前先准备好。

原生 Sidecar 可以更明确地表达代理和主应用之间的生命周期关系。

3. Batch / Job / AI 训练任务

批处理任务经常需要辅助容器做日志上传、模型文件同步、指标采集等工作。

原生 Sidecar 不阻塞 Job 完成,因此非常适合这类“主任务会结束,辅助任务伴随运行”的场景。

4. 配置或密钥同步

有些系统会通过 Sidecar 把外部配置、证书、密钥同步到本地文件系统,然后主容器读取本地文件。

这类场景通常要求 Sidecar 先启动,甚至先准备好数据,原生 Sidecar 的顺序语义会更清晰。


七、和普通 initContainer 的区别

类型

是否先于主容器启动

是否持续运行

是否适合长期辅助任务

普通 initContainer

普通 containers Sidecar

不保证

可以,但语义不清

原生 Sidecar

普通 initContainer 适合“一次性初始化”,比如数据库迁移、配置准备、文件下载。

原生 Sidecar 适合“先启动,并且持续服务主容器”的场景,比如代理、日志采集、监控 Agent。

普通多容器 Pod 仍然有价值,但它更适合多个同等重要的容器一起组成一个应用,而不是表达“主容器 + 辅助容器”的强生命周期关系。


八、迁移时需要注意什么?

1. 不要把所有辅助容器都改成原生 Sidecar

如果两个容器是平等关系,比如一个 Pod 中有两个业务进程共同提供服务,不一定要改成原生 Sidecar。

原生 Sidecar 更适合明显的“辅助主容器”的场景。

2. 注意探针配置

如果主应用依赖 Sidecar 真正可用,不要只依赖容器启动成功。

建议根据场景配置:

  • startupProbe:控制 Sidecar 是否完成启动

  • readinessProbe:影响 Pod Ready 状态

  • livenessProbe:Sidecar 异常时自动重启

3. 注意资源配置

Sidecar 虽然是辅助容器,但也会消耗 CPU、内存和存储资源。

在生产环境中,应该为 Sidecar 配置合理的 requestslimits,避免它抢占主容器资源,或者在资源不足时被频繁重启。

4. 注意终止逻辑

Pod 终止时,Kubernetes 会先终止主容器,然后再终止 Sidecar。

这通常是好事,因为日志采集器、代理容器可以在主容器退出后继续做收尾工作。

但如果 Sidecar 自己也需要优雅退出,也应该处理好 SIGTERM、flush、连接关闭等逻辑。


九、总结

Kubernetes 1.33 中原生 Sidecar Stable,是一个看似不大、但非常实用的改进。

它解决的不是“能不能在 Pod 里跑多个容器”的问题,而是解决:

  • 谁先启动

  • 谁持续运行

  • 谁不应该阻塞 Pod 或 Job 结束

  • 谁应该作为主应用的辅助能力存在

  • Kubernetes 如何正确理解 Sidecar 的生命周期

一句话总结:

原生 Sidecar 让 Kubernetes 从“能跑 Sidecar”变成了“真正理解 Sidecar”。

对于日志采集、服务网格、监控 Agent、批处理任务、AI/ML 任务等场景,Kubernetes 1.33 的原生 Sidecar 都值得认真使用。