Kubernetes 将动态格式化的日期时间传递到K8s容器配置

Kubernetes 将动态格式化的日期时间传递到K8s容器配置,kubernetes,containers,kubernetes-cronjob,Kubernetes,Containers,Kubernetes Cronjob,我有一个CronJob,它在Kubernetes的容器中运行一个进程 此过程接收一个时间窗口,该时间窗口由--自和--至标志定义。这个时间窗口需要在容器开始时(当cron被触发时)定义,并且是当前时间的函数。运行此流程的示例如下: $my process--begin=$(日期-v-1H+%Y-%m-%dT%H:%m:%SZ)--begin=$(日期-v+1H+%Y-%m-%dT%H:%m:%SZ) 因此,对于上面的示例,我希望时间窗口是从1小时前到未来的1小时。Kubernetes中有没有一

我有一个
CronJob
,它在Kubernetes的容器中运行一个进程

此过程接收一个时间窗口,该时间窗口由
--自
--至
标志定义。这个时间窗口需要在容器开始时(当cron被触发时)定义,并且是当前时间的函数。运行此流程的示例如下:

$my process--begin=$(日期-v-1H+%Y-%m-%dT%H:%m:%SZ)--begin=$(日期-v+1H+%Y-%m-%dT%H:%m:%SZ)
因此,对于上面的示例,我希望时间窗口是从1小时前到未来的1小时。Kubernetes中有没有一种方法可以将格式化的日期时间作为命令参数传递给进程

我尝试执行的一个示例是以下配置:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: my-process
spec:
  schedule: "*/2 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: my-process
            image: my-image
            args:
            - my-process
            - --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ")
            - --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
执行此操作时,文本字符串
“$(日期-v-1H+%Y-%m-%dT%H:%m:%SZ”)”
将作为
--since
标志传入


这样的事情可能吗?如果是这样的话,我该怎么做?

请注意,在
CronJob
中,您不运行
bash
或任何其他shell,
命令替换
是shell功能,没有它就无法工作。在您的示例中,容器中只启动了一个命令
my process
,由于它不是shell,因此无法执行
命令替换

这个:

$ my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
将正常工作,因为它是在
shell中启动的
,因此它可以利用shell功能,如前面提到的
命令替换

有一件事:
date-v-1H+%Y-%m-%dT%H:%m:%SZ“
在默认的
GNU/Linux
日期实现下不能在
bashshell
中正确展开。除此之外,
-v
选项无法识别,因此我猜您正在
MacOSX
或某种
BSD
系统上使用它。在下面的示例中,我将使用在
Debian
上工作的日期版本

因此,在
GNU/Linux
上对其进行测试时,应该是这样的:

args:
- /bin/sh
- -c
- my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
date--date='-1小时'+%Y-%m-%dT%H:%m:%SZ'

出于测试目的,我使用简单的CronJob对示例进行了一些修改:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: debian
            env:
            - name: FROM
              value: $(date --date="-1 hour" +"%Y-%m-%dT%H:%M:%SZ")
            - name: TILL
              value: $(date --date="+1 hour" +"%Y-%m-%dT%H:%M:%SZ")
            args:
            - /bin/sh
            - -c
            - date; echo from $(FROM) till $(TILL)
          restartPolicy: OnFailure
它工作正常。下面您可以看到
CronJob
执行的结果:

$ kubectl logs hello-1569947100-xmglq
 Tue Oct  1 16:25:11 UTC 2019
 from 2019-10-01T15:25:11Z till 2019-10-01T17:25:11Z
除了使用的示例外,我还使用以下代码对其进行了测试:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: debian
            args:
            - /bin/sh
            - -c
            - date; echo from $(date --date="-1 hour" +"%Y-%m-%dT%H:%M:%SZ") till $(date --date="+1 hour" +"%Y-%m-%dT%H:%M:%SZ")
          restartPolicy: OnFailure
正如您在这里看到的
命令替换
也可以正常工作:

$ kubectl logs hello-1569949680-fk782
Tue Oct  1 17:08:09 UTC 2019
from 2019-10-01T16:08:09Z till 2019-10-01T18:08:09Z
它工作正常,因为在这两个示例中,首先我们在容器中生成
bash shell
,然后它运行其他命令,就像它的参数提供的简单
echo
一样。您可以使用
my process
命令代替
echo
,只需在一行中提供它的所有参数,如下所示:

args:
- /bin/sh
- -c
- my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
此示例不起作用,因为不涉及
shell
<代码>回显命令不是shell将无法执行命令替换,这是shell的一项功能:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: debian
            args:
            - /bin/echo
            - from $(date --date="-1 hour" +"%Y-%m-%dT%H:%M:%SZ") till $(date --date="+1 hour" +"%Y-%m-%dT%H:%M:%SZ")
          restartPolicy: OnFailure
结果将是一个文本字符串:

$ kubectl logs hello-1569951180-fvghz
from $(date --date="-1 hour" +"%Y-%m-%dT%H:%M:%SZ") till $(date --date="+1 hour" +"%Y-%m-%dT%H:%M:%SZ")
这与您的命令类似,比如
echo
不是
shell
,它不能执行
命令替换

总而言之:解决方案是将命令包装为shell参数。在前两个示例中,
echo
命令与其他命令一起作为shell参数传递

在下面的示例中,可能会更清楚地看到它,但语法有点不同:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: debian
            command: ["/bin/sh","-c"]
            args: ["FROM=$(date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ'); TILL=$(date --date='+1 hour' +'%Y-%m-%dT%H:%M:%SZ') ;echo from $FROM till $TILL"]
          restartPolicy: OnFailure
manbash
说:

-c如果存在-c选项,则从第一个非选项参数command_字符串读取命令

所以
命令:[“/bin/sh”、“-c”]
基本上意味着运行一个shell并执行以下命令,然后我们使用
args
传递给它。在
bash
中,命令应该用分号
分隔因此它们是独立运行的(无论执行以前的命令的结果如何,都会执行后续命令)

在以下片段中:

args: ["FROM=$(date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ'); TILL=$(date --date='+1 hour' +'%Y-%m-%dT%H:%M:%SZ') ;echo from $FROM till $TILL"]
我们向
/bin/sh-c
提供三个单独的命令:

FROM=$(date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ')
它将环境变量中的
设置为执行
date--date='-1小时'+%Y-%m-%dT%H:%m:%SZ'
命令的结果

TILL=$(date --date='+1 hour' +'%Y-%m-%dT%H:%M:%SZ')
它将
TILL
环境变量设置为执行
date--date='+1小时'+%Y-%m-%dT%H:%m:%SZ'
命令的结果

最后我们跑了

echo from $FROM till $TILL
它使用两个变量

任何其他命令都可以执行完全相同的操作