我有一个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")
因此对于上面的示例,我希望时间范围是从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")
这样做时,文字字符串"$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ")"
将作为--since
标志传入。
像这样可能吗?如果是这样,我该怎么办?
答案 0 :(得分:0)
请注意,在您的CronJob
中,您不会运行bash
或任何其他Shell,而command substitution
是一种Shell功能,没有任何功能将无法运行。在您的示例中,仅一个命令my-process
在容器中启动,并且由于它不是外壳程序,因此无法执行command substitution
。
这个:
$ my-process --since=$(date -v -1H +"%Y-%m-%dT%H:%M:%SZ") --until=$(date -v +1H +"%Y-%m-%dT%H:%M:%SZ")
将在shell
中启动,因此可以正常工作,因此它可以利用诸如command substitution
之类的shell功能
一件事: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"
出于测试目的,我使用this示例中的简单 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
除了使用environment variables的示例外,我还使用以下代码对其进行了测试:
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
正如您在此处看到的,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
它正常工作是因为在两个示例中,我们首先在容器中生成了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
此示例无效,因为其中没有echo
涉及。 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
不是shell的命令将无法执行命令替换,这是shell的功能:
$ 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
不是command substitution
,并且无法执行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
命令与其他命令一起作为外壳参数传递。
在下面的示例中,也许使用更不同的语法可以更清楚地看到它:
man bash
command: ["/bin/sh","-c"]
说:
-c如果存在-c选项,那么将从第一个非选项参数command_string中读取命令。
所以args
基本上意味着运行一个shell并执行以下命令,然后我们使用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')
提供了三个单独的命令:
FROM
将date --date='-1 hour' +'%Y-%m-%dT%H:%M:%SZ'
环境变量设置为执行TILL=$(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
命令的结果
最后我们运行
Private Sub Worksheet_Change(ByVal Target As Range)
Dim xRg01, xRgSel01, xRg02, xRgSel02 As Range
Dim xOutApp As Object
Dim xMailItem As Object
Dim xMailBody, xFolderPath As String
'On Error Resume Next
'---------------------------------
'get workbook path
xFolderPath = ActiveWorkbook.Path
'---------------------------------
'Deal with first range
Set xRg01 = Range("D5:D10")
Set xRgSel01 = Intersect(Target, xRg01)
If Not xRgSel01 Is Nothing Then
ActiveWorkbook.Save
Set xOutApp = CreateObject("Outlook.Application")
Set xMailItem = xOutApp.CreateItem(0)
xMailBody = "Hello," & vbCrLf & vbCrLf & "Cell D" & Target.Row & " has been changed, to value [" & Target.Value & "]." & vbCrLf & vbCrLf & "Workbook path:" & xFolderPath
With xMailItem
.To = "email@email.com"
.Subject = "Subject for xRg01"
.Body = xMailBody
.Display
End With
End If
'---------------------------------
'Deal with the second range
Set xRg02 = Range("D12:D20")
Set xRgSel02 = Intersect(Target, xRg02)
If Not xRgSel02 Is Nothing Then
ActiveWorkbook.Save
Set xOutApp = CreateObject("Outlook.Application")
Set xMailItem = xOutApp.CreateItem(0)
xMailBody = "Hello," & vbCrLf & vbCrLf & "Cell D" & Target.Row & " has been changed, to value [" & Target.Value & "]." & vbCrLf & "Workbook path:" & xFolderPath
With xMailItem
.To = "another.email@email.com"
.Subject = "Subject for xRg02"
.Body = xMailBody
.Display
End With
End If
'---------------------------------
Set xRg01 = Nothing
Set xRgSel01 = Nothing
Set xRg02 = Nothing
Set xRgSel02 = Nothing
Set xOutApp = Nothing
Set xMailItem = Nothing
End Sub
使用两个变量。
可以使用其他任何命令完全相同。