首页 > 解决方案 > 在 Kubernetes 容器中找不到从 ConfigMap 挂载的脚本

问题描述

我有一个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
      ...

每当我尝试运行此作业时,我得到的只是'未找到',当脚本执行之前的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

这里可能是什么问题?

标签: kubernetesconfigmap

解决方案


Docker Hubbusybox镜像是一个极小的镜像,仅包含BusyBox,这是一个包含最少标准 Unix 工具集的单静态二进制应用程序。它包含/bin/sh符合POSIX 规范的 Bourne shell 的实现,但不包含 GNU bash。

在实践中,您应该能够重写大多数 shell 脚本以符合 POSIX 语法。(使用.代替source; 不要以function; 开始 shell 函数声明,您可能需要使用外部工具而不是复杂的模式扩展。)您显示的 shell 片段应该没问题。您只需要将第一行更改为

#!/bin/sh

(由于这是代码而不是配置,还可以考虑将其放入自定义 Docker 映像中;您的 CI 系统需要将其发布到某个映像注册表才能运行它,但随后它将遵循与所有其他自定义相同的生命周期在您的集群中运行的代码。)


推荐阅读