如何让Kubernetes CronJob中的Shell解析文件名参数?
问题
我有一个用于数据库备份的Kubernetes CronJob,希望备份文件名附加日期,配置如下:
{{- if .Values.postgresqlBackup.enabled }} apiVersion: batch/v1 kind: CronJob metadata: name: postgres-backup spec: schedule: {{ .Values.postgresqlBackup.cron | quote }} jobTemplate: spec: template: spec: containers: - name: postgres image: postgres:latest imagePullPolicy: IfNotPresent command: - pg_dump - --username=postgres - --no-password - --format=custom - --file=/backups/dragalia-api-$(date +"%Y-%m-%d_%H-%M-%S").bak - --host={{ include "dragalia-api.fullname" . }}-postgresql - --verbose volumeMounts: - name: data mountPath: /backups env: - name: PGPASSWORD valueFrom: secretKeyRef: name: {{ include "dragalia-api.fullname" . }}-postgresql key: postgres-password optional: false restartPolicy: Never volumes: - name: data persistentVolumeClaim: claimName: {{ include "dragalia-api.fullname" . }}-db-backup {{- end }}
任务执行成功,但生成的文件名为字面字符串:
docker@minikube:/dragalia-api/db-backup$ ls 'dragalia-api-$(date +"%Y-%m-%d_%H-%M-%S").bak'
文件名中的Shell表达式未被解析,我该如何让Shell解析该字符串?
我已尝试的方法:
- 使用反引号:
--file=/backups/dragalia-api-1date +"%Y-%m-%d_%H-%M-%S".bak,仍为字面量 - 定义DATE环境变量并使用${DATE},仍为字面量
- 转义%符号如
\%Y,仍为字面量 - 向
sh -c传递多行字符串:任务因无法连接数据库失败,推测--host参数未正确传递
我不想新增其他资源,也可接受其他生成唯一文件名的方式,只要能保留滚动备份即可。
解决方案
问题根源是Kubernetes容器的command字段默认直接执行二进制程序,不会通过Shell解析变量,所以$(date...)被当作纯文本处理。要让Shell解析表达式,需用sh -c包裹整个备份命令,同时确保参数传递正确:
修改CronJob的command和args部分如下:
command: - sh - -c args: - >- pg_dump --username=postgres --no-password --format=custom --file=/backups/dragalia-api-$(date +"%Y-%m-%d_%H-%M-%S").bak --host={{ include "dragalia-api.fullname" . }}-postgresql --verbose
这里用YAML折叠标量>-保留命令的换行格式,既方便阅读,又能让Shell正确解析所有参数,避免之前用sh -c时出现的数据库连接问题。
修改后,CronJob执行时会启动Shell处理$(date)表达式,生成带时间戳的备份文件名,满足滚动备份的需求。
内容的提问来源于stack exchange,提问作者lordnoob
相关产品推荐
相关产品推荐

