将系统日期作为变量传递给 Kubernetes CronJob

passing system date as variable to Kubernetes CronJob

我找到了这个,它很相似,但没有解决我的问题。

我正在尝试使用 cronjob 备份 etcd,但 etcd 映像没有“date”命令。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup
  namespace: kube-system
spec:
  concurrencyPolicy: Allow
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - args:
            - -c
            - etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt
              --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key
              snapshot save /backup/etcd-snapshot-$(DATE_CURR).db
            command:
            - /bin/sh
            env:
            - name: ETCDCTL_API
              value: "3"
            - name: DATE_CURR
              #value: $(date --date= +"%Y-%m-%d_%H:%M:%S_%Z")
              value: $(date +"%Y-%m-%d_%H:%M:%S_%Z")
            image: k8s.gcr.io/etcd:3.4.13-0
            imagePullPolicy: IfNotPresent
            name: backup
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /etc/kubernetes/pki/etcd
              name: etcd-certs
              readOnly: true
            - mountPath: /backup
              name: backup
          - args:
            - -c
            - find /backup -type f -mtime +30 -exec rm -f {} \;
            command:
            - /bin/sh
            env:
            - name: ETCDCTL_API
              value: "3"
            image: k8s.gcr.io/etcd:3.4.13-0
            imagePullPolicy: IfNotPresent
            name: cleanup
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /backup
              name: backup
          dnsPolicy: ClusterFirst
          hostNetwork: true
          nodeName: homelab-a
          restartPolicy: OnFailure
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
          volumes:
          - hostPath:
              path: /etc/kubernetes/pki/etcd
              type: DirectoryOrCreate
            name: etcd-certs
          - hostPath:
              path: /opt/etcd_backups
              type: DirectoryOrCreate
            name: backup
  schedule: 0 */6 * * *
  successfulJobsHistoryLimit: 3
  suspend: false

当它运行时,它会生成一个名为“etcd-snapshot-.db”的文件,没有日期。如果我能捕捉到日志,它会说“date”不是已知命令。果然,当我能够在 pod 为 运行 时执行它时,日期在 etcd 映像中不起作用。我怎样才能将系统中的日期作为变量传递,以便它只使用文本而不尝试实际调用“date”命令?

编辑:感谢@Andrew,这是解决方案:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup
  namespace: kube-system
spec:
  concurrencyPolicy: Allow
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - args:
            - -c
            - etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt
              --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key
              snapshot save /backup/etcd-snapshot-$(echo `printf "%(%Y-%m-%d_%H:%M:%S_%Z)T\n"`).db
            command:
            - /bin/sh
            env:
            - name: ETCDCTL_API
              value: "3"
            image: k8s.gcr.io/etcd:3.4.13-0
            imagePullPolicy: IfNotPresent
            name: backup
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /etc/kubernetes/pki/etcd
              name: etcd-certs
              readOnly: true
            - mountPath: /backup
              name: backup
          - args:
            - -c
            - find /backup -type f -mtime +30 -exec rm -f {} \;
            command:
            - /bin/sh
            env:
            - name: ETCDCTL_API
              value: "3"
            image: k8s.gcr.io/etcd:3.4.13-0
            imagePullPolicy: IfNotPresent
            name: cleanup
            resources: {}
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /backup
              name: backup
          dnsPolicy: ClusterFirst
          hostNetwork: true
          nodeName: homelab-a
          restartPolicy: OnFailure
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
          volumes:
          - hostPath:
              path: /etc/kubernetes/pki/etcd
              type: DirectoryOrCreate
            name: etcd-certs
          - hostPath:
              path: /opt/etcd_backups
              type: DirectoryOrCreate
            name: backup
  schedule: 0 */6 * * *
  successfulJobsHistoryLimit: 3
  suspend: false

你可以这样使用 printf:

printf "%(%Y-%m-%d_%H:%M:%S_%Z)T\n"

使用 man strftime 获取转换规范序列。

刚刚在 kubernetes 1.19 的 etcd 容器中尝试过,

etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/etcd-snapshot-$(printf "%(%Y-%m-%d_%H:%M:%S_%Z)T\n").db 
{"level":"info","ts":1603748998.7475638,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"/tmp/etcd-snapshot-2020-10-26_21:49:58_UTC.db.part"}
{"level":"info","ts":"2020-10-26T21:49:58.760Z","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"}
{"level":"info","ts":1603748998.7616487,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"https://127.0.0.1:2379"}
{"level":"info","ts":"2020-10-26T21:49:58.889Z","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"}
{"level":"info","ts":1603748998.9136698,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"https://127.0.0.1:2379","size":"5.9 MB","took":0.165411663}
{"level":"info","ts":1603748998.914325,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"/tmp/etcd-snapshot-2020-10-26_21:49:58_UTC.db"}
Snapshot saved at /tmp/etcd-snapshot-2020-10-26_21:49:58_UTC.db

编辑:使用作业的可重现示例,不传递任何环境变量:

apiVersion: batch/v1
kind: Job
metadata:
  name: printf
spec:
  template:
    spec:
      containers:
      - name: printf
        image: k8s.gcr.io/etcd:3.4.9-1
        command: ["/bin/sh"]
        args:
        - -c
        - echo `printf "%(%Y-%m-%d_%H:%M:%S_%Z)T\n"`
      restartPolicy: Never
  backoffLimit: 4
# kubectl create -f job.yaml 
job.batch/printf created
# kubectl logs printf-lfcdh 
2020-10-27_10:03:59_UTC

注意使用反引号 `` 而不是 $()