nor*_*ght 2 containers kubernetes kubernetes-cronjob
我有一个CronJob在 Kubernetes 的容器中运行一个进程。
此过程需要一个由--since和--until标志定义的时间窗口。这个时间窗口需要在容器启动时间(cron 被触发时)定义,并且是当前时间的函数。运行此过程的示例是:
$ my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
Run Code Online (Sandbox Code Playgroud)
所以对于上面的例子,我希望时间窗口是从 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")
Run Code Online (Sandbox Code Playgroud)
这样做时,文字字符串"$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ")"将作为--since标志传入。
这样的事情可能吗?如果是这样,我该怎么做?
请注意,在您CronJob不运行bash或任何其他 shell 中,它command substitution是一个 shell 功能,没有一个将无法工作。在您的示例my-process中,容器中仅启动了一个命令,并且由于它不是 shell,因此无法执行command substitution.
这个:
$ my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
Run Code Online (Sandbox Code Playgroud)
将正常工作,因为它是在 a 中启动的,shell因此它可以利用提到的 shell 功能command substitution
一件事:date -v -1H +"%Y-%m-%dT%H:%M:%SZ"在bash shell默认GNU/Linux date实现中没有正确扩展。其他-v选项无法识别,所以我猜您正在MacOSX或某种BSD系统上使用它。在下面的示例中,我将使用适用于Debian.
因此,为了对其进行测试,GNU/Linux它将是这样的:
date --date='-1 hour' +"%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
Run Code Online (Sandbox Code Playgroud)
它工作正常。下面你可以看到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
Run Code Online (Sandbox Code Playgroud)
除了使用环境变量的示例之外,我还使用以下代码对其进行了测试:
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
Run Code Online (Sandbox Code Playgroud)
正如您在此处所看到的,它command substitution也可以正常工作:
$ 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
Run Code Online (Sandbox Code Playgroud)
它工作正常,因为在两个示例中,我们首先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")
Run Code Online (Sandbox Code Playgroud)
这个例子将不起作用,因为没有shell涉及。echo命令不是 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
Run Code Online (Sandbox Code Playgroud)
结果将是一个文字字符串:
$ 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")
Run Code Online (Sandbox Code Playgroud)
这与您的命令的情况类似,例如echois not ashell并且它不能执行command substitution。
总结:解决方案是将您的命令包装为 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
Run Code Online (Sandbox Code Playgroud)
man bash 说:
-c 如果存在 -c 选项,则从第一个非选项参数 command_string 读取命令。
所以command: ["/bin/sh","-c"]基本上意味着运行一个 shell 并执行以下命令,然后我们使用args. inbash命令应该用分号分隔,;以便它们独立运行(无论执行前一个命令/命令的结果如何,都会执行后续命令)。
在以下片段中:
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"]
Run Code Online (Sandbox Code Playgroud)
我们提供/bin/sh -c三个单独的命令:
FROM=$(date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ')
Run Code Online (Sandbox Code Playgroud)
将FROM环境变量设置为date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ'命令执行的结果,
TILL=$(date --date='+1 hour' +'%Y-%m-%dT%H:%M:%SZ')
Run Code Online (Sandbox Code Playgroud)
它将TILL环境变量设置为date --date='+1 hour' +'%Y-%m-%dT%H:%M:%SZ'命令执行的结果
最后我们跑
echo from $FROM till $TILL
Run Code Online (Sandbox Code Playgroud)
它使用两个变量。
可以使用任何其他命令完成完全相同的操作。
| 归档时间: |
|
| 查看次数: |
2106 次 |
| 最近记录: |