先记住这个答案
原生 Sidecar 容器通过 initContainers 字段声明并设置 restartPolicy: Always,Pod 启动时按声明顺序先于主容器运行,启动后持续存活直至 Pod 终止。它支持 readinessProbe,其结果决定 Pod 的 Ready 状态;普通容器在 Pod 内无固定启动顺序。终止时主容器先停,Sidecar 后停。生命周期和探针语义与普通容器有本质差异。
- Sidecar是restartPolicy=Always的init容器
- Sidecar必须先于主容器启动并常驻
- Sidecar的readiness探针决定Pod就绪
启动与生命周期机制
Kubernetes从1.28引入、1.29默认启用SidecarContainers特性。在Pod的initContainers列表中加入restartPolicy: Always的容器,kubelet会将其视为Sidecar容器。它遵守init容器顺序,在当前Sidecar启动成功后(含由startupProbe成功),继续启动下一个init或主容器。这意味着Sidecar必然先于主容器运行,并在整个Pod生命周期内保持运行。
普通容器没有顺序保证,可在任意时间被调度创建,通常并行启动。Sidecar与普通容器共享网络和文件系统卷,但生命周期受Pod控制:Pod终止时kubelet先停止主容器,再逆序停止Sidecar容器,允许Sidecar服务在主容器完全停止前继续可用。Sidecar自身支持独立重启而不影响主容器。
日志代理边车监控主容器输出的场景
假设主容器是一个短期批量任务,需要边车持续读取其日志并转发。若用普通容器,可能出现主容器先退出而边车未启动完成,导致日志丢失。改用原生Sidecar:定义initContainers中restartPolicy: Always,且主容器在containers中。Sidecar先于主容器运行并持续tail文件,主容器写日志时边车已在工作。
进一步,若想确保外部服务只在边车就绪后才接收流量,可为Sidecar配置readinessProbe。Pod的Ready条件会等待该探针成功,普通容器没有此语义。对于Job,Sidecar不会阻止Job完成——主容器退出后Sidecar被终止,任务正常结束。
探针与终止边界
关键区别在于Sidecar生命周期由Pod管控,其readiness探针的结果决定Pod的Ready状态,失败会阻止Pod就绪,但不会直接重启Sidecar。Sidecar作为init容器也支持startup探针判断启动是否成功。liveness探针可用于检查自身健康,失败会触发该Sidecar重启(与普通容器类似),但不会影响Pod就绪。
终止时如果主容器使用完宽限期,Sidecar可能收到SIGTERM后很快SIGKILL,退出码非零属正常现象,外部监控应忽略。变更Sidecar镜像不会重启Pod,只会触发该容器自身重启(对应现有行为),而普通容器镜像变更通常会重建Pod(Deployment场景)。
容易答错的地方
- 把Sidecar当作普通常驻容器
- 误区:在
containers里声明多个容器就是Sidecar。实际原生Sidecar必须定义于initContainers且设置restartPolicy: Always,否则不享受生命周期顺序和探针语义。若用普通容器做辅助服务,没有启动顺序保证,其readiness探针同样会影响Pod就绪,但无法获得Sidecar的专用启动顺序和终止顺序保障。 - 混淆Sidecar的readiness和liveness探针
- 误区:以为liveness探针失败会阻止Pod就绪,或readiness失败会重启Sidecar。实际Sidecar的readiness探针决定Pod就绪,liveness探针只用于检查自身健康并触发重启,两者职责不同。
面试官还会怎么问?
Sidecar容器在Pod里何时启动?
在声明位置前序init容器启动成功后启动,主容器之前。若Sidecar后面还有普通init容器,则等所有init完成后主容器才启动。
Sidecar容器可以独立重启而不影响主容器吗?
可以。kubelet会单独重启Sidecar容器,其间主容器继续运行;但重启引起的挂载卷内容等需自恢复。
Job使用Sidecar时完成条件如何变化?
主容器退出后,Job即视为完成,Sidecar会被终止,不会因Sidecar运行而阻塞完成。这是与普通常驻容器的重要差异。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。