我有一个ConfigMap为我保留shell脚本:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Chart.Name }}-script
labels:
app: {{ .Chart.Name }}
data:
backup.sh: |
#!/bin/bash
rolling_backup() {
echo "Found at least 3 backups. Starting rolling backup."
...
rolling_backup
fi
然后我试图将其挂载到CronJob执行这个脚本:
...
containers:
- name: {{ .Chart.Name }}-cronjob
image: busybox
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ['sh', '-c', 'ls -la /etc/scripts/ && /etc/scripts/backup.sh inp-mongo-main-volume']
volumeMounts:
- name: {{ .Chart.Name }}-script
mountPath: "/etc/scripts/"
volumes:
- name: {{ .Chart.Name }}-script
configMap:
name: {{ .Chart.Name }}-script
defaultMode: 0777
...
每当我尝试运行这个作业时,我得到的都是'not found',当ls命令在脚本执行前显示与脚本实际完全不同的内容时。
user@computer scripts % kubectl logs -n <namespace> mongo-cron-46svm
total 12
drwxr-xr-x 2 root root 4096 Aug 5 10:31 .
drwxr-xr-x 1 root root 4096 Aug 5 10:31 ..
-rwxrwxrwx 1 root root 1377 Aug 5 10:31 backup.sh
/bin/sh: /etc/scripts/backup.sh: not found
这里的问题是什么?
Docker Hubbusybox
映像是一个极其最小的映像,仅包含BusyBox,这是一个包含最小标准Unix工具集的单静态二进制应用程序。它包含符合POSIX规范的Bourne shell/bin/sh
的实现,但它不包含GNU bash。
在实践中,您应该能够重写大多数shell脚本以符合POSIX语法。(用.
代替source
;不要以function
开头声明shell函数;您可能需要使用外部工具而不是复杂的模式展开。)你展示的外壳碎片应该没问题。只需要将第一行改为
#!/bin/sh
(因为这是代码而不是配置,也考虑把它放在一个自定义的Docker映像中;您的CI系统需要将其发布到某个映像注册表才能运行它,但随后它将遵循与集群中运行的所有其他自定义代码相同的生命周期。