当我手动触发它时,如何防止 Kubernetes cronjob 运行 同时发生?
How to prevent Kubernetes cronjob running concurrently when I trigger it manually?
我已设置 Kubernetes cronJob 以防止并发运行 like here 使用 parallelism: 1
、concurrencyPolicy: Forbid
和 parallelism: 1
。但是,当我尝试手动创建 cronJob 时,我可以这样做。
$ kubectl get cronjobs
...
$ kubectl create job new-cronjob-1642417446000 --from=cronjob/original-cronjob-name
job.batch/new-cronjob-1642417446000 created
$ kubectl create job new-cronjob-1642417446001 --from=cronjob/original-cronjob-name
job.batch/new-cronjob-1642417446001 created
我原以为不会创建新的 cronjob。或者它可以创建并失败,并显示引用 concurrencyPolicy
的状态。如果 属性 concurrencyPolicy
是 CronJob 规范的一部分,而不是 PodSpec,它应该会阻止创建新作业。为什么没有?
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-name
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
schedule: "0 * * * *"
suspend: false
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
spec:
parallelism: 1
completions: 1
backoffLimit: 3
template:
spec:
restartPolicy: Never
阅读 official documentation 关于 kubectl create -f
的文章后,我没有找到防止这种情况发生的方法。这种行为是预期的吗?如果是,我想我应该检查我的 Docker 图像(用 Java 编写的应用程序)是否已经有一个 cronjob 运行。我该怎么做?
concurrencyPolicy: Forbidden
规范仅阻止 the same CronJob
的并发 pod 创建和执行。它不适用于单独的 CronJobs,即使它们使用相同的 Docker 图像有效地执行相同的命令。就 Kubernetes 而言,它们是不同的工作。如果这是 Java,Kubernetes 所做的是 if (stringA == stringB)
而不是 if (stringA.equals(stringB))
。
If it is, I think I should check inside my Docker image (app written in Java) if there is already a cronjob running. How would I do that?
一种使用方式是使用分布式锁机制,使用单独的组件,例如Redis。这是使用 Java Redis 库 redisson 的指南的 link:https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers。以下是从该页面获取的代码示例:
RLock lock = redisson.getLock("myLock");
// wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
// do operation
} else {
// some other execution is doing it so just chill
}
我已设置 Kubernetes cronJob 以防止并发运行 like here 使用 parallelism: 1
、concurrencyPolicy: Forbid
和 parallelism: 1
。但是,当我尝试手动创建 cronJob 时,我可以这样做。
$ kubectl get cronjobs
...
$ kubectl create job new-cronjob-1642417446000 --from=cronjob/original-cronjob-name
job.batch/new-cronjob-1642417446000 created
$ kubectl create job new-cronjob-1642417446001 --from=cronjob/original-cronjob-name
job.batch/new-cronjob-1642417446001 created
我原以为不会创建新的 cronjob。或者它可以创建并失败,并显示引用 concurrencyPolicy
的状态。如果 属性 concurrencyPolicy
是 CronJob 规范的一部分,而不是 PodSpec,它应该会阻止创建新作业。为什么没有?
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-name
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
schedule: "0 * * * *"
suspend: false
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
concurrencyPolicy: Forbid
jobTemplate:
spec:
parallelism: 1
completions: 1
backoffLimit: 3
template:
spec:
restartPolicy: Never
阅读 official documentation 关于 kubectl create -f
的文章后,我没有找到防止这种情况发生的方法。这种行为是预期的吗?如果是,我想我应该检查我的 Docker 图像(用 Java 编写的应用程序)是否已经有一个 cronjob 运行。我该怎么做?
concurrencyPolicy: Forbidden
规范仅阻止 the same CronJob
的并发 pod 创建和执行。它不适用于单独的 CronJobs,即使它们使用相同的 Docker 图像有效地执行相同的命令。就 Kubernetes 而言,它们是不同的工作。如果这是 Java,Kubernetes 所做的是 if (stringA == stringB)
而不是 if (stringA.equals(stringB))
。
If it is, I think I should check inside my Docker image (app written in Java) if there is already a cronjob running. How would I do that?
一种使用方式是使用分布式锁机制,使用单独的组件,例如Redis。这是使用 Java Redis 库 redisson 的指南的 link:https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers。以下是从该页面获取的代码示例:
RLock lock = redisson.getLock("myLock");
// wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
// do operation
} else {
// some other execution is doing it so just chill
}