如何在Kubernetes CronJob中执行Shell脚本?配置后Pod崩溃如何解决
问题根因
你当前Pod崩溃的核心原因是使用的官方busybox镜像内不存在/home/admin_/test.sh这个脚本文件,容器启动后执行命令找不到目标文件,直接报错退出。你可以执行kubectl logs <崩溃的Pod名称>查看具体报错信息,大概率会返回/bin/sh: /home/admin_/test.sh: not found。
正确实现方案
方案1:短脚本直接内嵌到CronJob配置
如果你的Shell脚本逻辑简单、行数少,可以直接把脚本内容写在command字段里,不需要额外准备文件:
apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox:1.35 imagePullPolicy: IfNotPresent command: - /bin/sh - -c - | # 这里直接写你的Shell脚本逻辑,替换成你自己的test.sh里的全部内容即可 echo "CronJob执行成功" date restartPolicy: OnFailure concurrencyPolicy: Forbid # 可选,避免前一次任务没跑完重复启动 failedJobsHistoryLimit: 2 # 可选,保留失败任务历史数量 successfulJobsHistoryLimit: 3 # 可选,保留成功任务历史数量
注意:K8s 1.21及以上版本CronJob的API版本已经从batch/v1beta1升级为batch/v1,请根据你的集群版本调整apiVersion字段。
方案2:长脚本通过ConfigMap挂载使用
如果脚本内容多,内嵌到配置里不好维护,可以先把脚本存到ConfigMap,再挂载到CronJob的容器中使用:
- 先创建ConfigMap,把你的test.sh内容存进去:
# test-script-cm.yaml apiVersion: v1 kind: ConfigMap metadata: name: test-script-cm data: test.sh: | #!/bin/sh # 这里粘贴你原来的test.sh里的全部内容 echo "从ConfigMap加载的脚本执行成功" date
执行kubectl apply -f test-script-cm.yaml创建ConfigMap。
2. 再修改CronJob配置,挂载ConfigMap到容器内:
apiVersion: batch/v1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: volumes: - name: script-volume configMap: name: test-script-cm defaultMode: 0755 # 给脚本加执行权限 containers: - name: hello image: busybox:1.35 imagePullPolicy: IfNotPresent volumeMounts: - name: script-volume mountPath: /home/admin_/ # 挂载到你原来的脚本目录 command: - /bin/sh - -c - /home/admin_/test.sh restartPolicy: OnFailure
执行kubectl apply -f CronJob.yaml更新CronJob即可。
方案3:把脚本打包进自定义镜像
如果你的脚本有额外依赖,也可以基于busybox或者其他基础镜像制作自定义镜像,把test.sh打包到镜像的对应路径下,再把CronJob里的image字段替换成你自己的自定义镜像即可。
内容的提问来源于stack exchange,提问作者Amin Pashna
相关产品推荐
相关产品推荐

