Job 主程序已退出,istio-proxy 仍让任务保持 Running
主容器已退出,普通 containers 中的 istio-proxy 仍运行。检查实际注入结果及 Kubernetes、Istio 版本,再评估原生 sidecar 生命周期。
批任务的主容器已经正常退出,Pod 却显示 1/2 Running,Job 迟迟没有完成。检查后发现 istio-proxy 还在运行,并且位于 Pod 的普通 containers 数组中。这种注入方式会让常驻代理参与普通容器的完成判断;主程序写完文件,并不代表整个 Pod 已经结束。
需要先确认实际容器状态,再评估所用 Kubernetes 和 Istio 是否支持原生 sidecar 生命周期。调低 CronJob 的历史保留数、修改 readiness 或等待清理器,都不会让一个仍在运行的普通容器自动完成。
查看的是运行中的 Pod,而不是注入前的模板
以下只读命令中的名称应替换成实际对象:
kubectl get job report-task -n team-app -o yaml
kubectl get pod report-task-abc12 -n team-app -o yaml
kubectl describe pod report-task-abc12 -n team-app
kubectl get nodes -o wide
核对 Pod 的所属 Job、主容器的 terminated 状态与退出码,以及其他普通容器的状态。还要读实际的 containers、initContainers 和各自的 restartPolicy。注入前的 Job 清单没有代理,并不能证明运行中的 Pod 没有代理。
如果主程序还没运行,事件报 ImagePullBackOff,则应检查 Job 镜像拉取与任务期限。主容器非零退出、其他业务容器仍工作,以及代理只是未就绪,也要分开判断。readiness 控制就绪状态,不等于容器已经结束。
原生 sidecar 位于 initContainers
Kubernetes 的原生 sidecar 是带 restartPolicy: Always 的可重启 init container。它会持续运行以支持主容器,但在主容器完成后,不会以普通常驻容器的方式阻止 Job 完成。
这项能力从 Kubernetes 1.28 的 alpha 开始,1.29 起默认启用,1.33 进入稳定阶段。旧集群还需核对特性开关、API 接受能力和节点 kubelet 支持。不能只看控制平面的版本就给混合节点集群启用新字段。
Istio 的注入行为也有版本差异。例如,1.31.1 的 ENABLE_NATIVE_SIDECARS 默认为 auto:能确定节点时检查该节点,否则检查所有节点,要求相应 kubelet 至少为 1.33。集群版本较新,仍可能因旧节点或检测条件而采用普通注入。更早版本的默认值与开关不能直接套到这一版本。
在兼容条件已经确认、并且所用 Istio 支持相应注解时,可通过既有任务模板评估显式启用。下面只展示 Job 模板中的注解位置,需要保留原来的所有其他字段:
spec:
template:
metadata:
annotations:
sidecar.istio.io/nativeSidecar: "true"
这项注解在 Istio 文档中标为 Alpha,并优先于全局环境变量。它不能替旧节点补齐能力。由 CronJob 管理时,需要修改其 Job 模板中的 Pod 模板,不能只改 CronJob 对象顶层的 metadata。
让相容的注入器生成完整代理配置,不要手工把已有 istio-proxy 块移到 initContainers 就结束变更。代理启动、排空、探针、资源、挂载和网格版本之间有配套要求。
用新任务验证完成与网络退出
保存原任务模板和注入设置,确认重跑不会重复写入、重复扣费或覆盖已有产物,再在隔离测试任务中检查新注入结果。模板修改不会把现有 Pod 自动改成另一种容器结构;普通 Job 的 Pod 模板也通常不能这样原地更新。
验收应同时看到主程序完成业务、产物正确、注入后的代理位于预期字段,以及 Job 最终进入完成状态。还要验证任务运行期间的 mTLS、授权、服务访问和结束前的网络交互。容器生命周期得到支持,不代表所有网格连接和应用退出问题都已解决。
不要为了让状态变成 Completed 而随意关闭注入或杀掉仍服务请求的代理。只关闭 Envoy,也可能留下运行中的 pilot-agent;旧资料中的退出端口和脚本不应作为所有 Istio 版本的处理方法。
若原生注入测试失败,恢复任务模板和注入设置,保留新旧 Pod 的实际清单及事件,再按兼容版本处理。已经执行的业务写入不会随模板回退撤销,旧的未完成任务也需要按原任务的业务状态单独收尾。


