如何实现Kubernetes Pod无停机定时滚动重启?CronJob故障排查
解决Kubernetes定时滚动重启Pod的CronJob问题
我来帮你一步步搞定这两个核心问题:先理清CronJob执行无效的根源,再解决容器启动失败的错误,最后实现无停机的定时滚动重启需求。
问题根源拆解
1. 初始CronJob无实际作用
你第一个CronJob的容器只是启动了app-image,但没有执行任何和重启Pod相关的逻辑——Job确实被调度完成了,但它只是启动容器后就直接退出,完全没做任何有用的操作,自然看不到Pod被重启的效果。
2. 第二个CronJob的Exit Code 127错误
错误码127的含义是找不到要执行的命令:你用的busybox镜像默认没有预装kubectl工具,当容器尝试执行kubectl patch时,系统找不到这个命令,直接导致容器启动失败。
正确解决方案
要实现定时滚动重启Pod且避免服务停机,我们可以利用Kubernetes原生的kubectl rollout restart命令(这会触发Deployment的滚动更新流程,完美符合无停机要求),同时解决CronJob的工具依赖和权限问题。
步骤1:配置操作Deployment的权限
CronJob的Pod需要有足够权限才能操作Deployment,我们创建专用的ServiceAccount、Role和RoleBinding:
apiVersion: v1 kind: ServiceAccount metadata: name: deployment-restarter namespace: jp-test # 替换为你的目标命名空间 --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: deployment-restarter-role namespace: jp-test rules: - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "patch", "update"] # 执行rollout restart需要这些权限 --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: deployment-restarter-binding namespace: jp-test subjects: - kind: ServiceAccount name: deployment-restarter namespace: jp-test roleRef: kind: Role name: deployment-restarter-role apiGroup: rbac.authorization.k8s.io
步骤2:编写可正常执行的CronJob配置
使用预装kubectl的镜像(比如registry.k8s.io/kubectl:v1.28.0,请选择和你的K8s版本匹配的镜像),并绑定刚才创建的ServiceAccount,执行滚动重启命令:
apiVersion: batch/v1 kind: CronJob # 注意:batch/v1beta1已被废弃,建议使用稳定的batch/v1 metadata: name: scheduled-deployment-restart namespace: jp-test spec: schedule: "*/5 * * * *" # 每5分钟执行一次 concurrencyPolicy: Forbid # 禁止并发执行,避免重复操作 jobTemplate: spec: template: spec: serviceAccountName: deployment-restarter # 使用授权后的ServiceAccount containers: - name: kubectl-restarter image: registry.k8s.io/kubectl:v1.28.0 # 替换为匹配你K8s版本的kubectl镜像 args: - /bin/sh - -c - kubectl rollout restart deployment runners -n jp-test restartPolicy: OnFailure
方案优势说明
- 无停机滚动更新:
kubectl rollout restart会严格遵循Deployment的滚动策略(默认是最多25%的Pod不可用、同时最多新增25%的Pod),先启动新Pod并确认就绪后,再终止旧Pod,完全不会导致服务中断。 - CronJob执行有效:使用预装
kubectl的镜像解决了命令找不到的问题,通过RBAC授权确保Pod有操作Deployment的权限。 - 避免并发冲突:
concurrencyPolicy: Forbid确保上一次Job未完成时,不会启动新的Job,防止重复触发重启。
验证方案有效性
- 先创建权限相关资源:
kubectl apply -f rbac-config.yaml -n jp-test - 创建CronJob:
kubectl apply -f cronjob-config.yaml -n jp-test - 查看CronJob状态:
kubectl get cronjob -n jp-test - 等待调度时间,查看Job和Pod执行日志:
kubectl get jobs -n jp-test kubectl logs <job-pod-name> -n jp-test - 验证Deployment的滚动更新状态:
kubectl rollout status deployment runners -n jp-test
这样就能完美实现你想要的每5分钟滚动重启Pod且无服务停机的需求了。
内容的提问来源于stack exchange,提问作者Chillax
相关产品推荐
相关产品推荐

