<p>I have set the Kubernetes cronJob to prevent concurrent runs <a href="https://stackoverflow.com/a/62892617/2096986">like here</a> using <code>parallelism: 1</code>, <code>concurrencyPolicy: Forbid</code>, and <code>parallelism: 1</code>. However, when I try to create a cronJob manually I am allowed to do that.</p>
<pre><code>$ 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
</code></pre>
<p>I was expecting that a new cronjob would not be created. Or it could be created and fail with a state that references the <code>concurrencyPolicy</code>. If the property <code>concurrencyPolicy</code> is part of the CronJob spec, not the PodSpec, it should prevent a new job to be created. Why it does not?</p>
<pre><code>apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-name
  annotations:
    argocd.argoproj.io/sync-wave: &quot;1&quot;
spec:
  schedule: &quot;0 * * * *&quot;
  suspend: false
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 3
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      parallelism: 1
      completions: 1
      backoffLimit: 3
      template:
        spec:
          restartPolicy: Never
</code></pre>
<p>After reading the <a href="https://kubernetes.io/docs/tasks/job/_print/#creating-a-cron-job" rel="nofollow noreferrer">official documentation</a> about the <code>kubectl create -f</code> I didn't find a way to prevent that. Is this behavior expected? 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?</p>

<p>The <code>concurrencyPolicy: Forbidden</code> spec only prevents concurrent pod creations and executions of <a href="https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#concurrency-policy" rel="nofollow noreferrer">the same <code>CronJob</code></a>. It does not apply across separate CronJobs even though they effectively execute the same commands using the same Docker image. As far as Kubernetes is concerned, they are different jobs. If this was Java, what Kubernetes does is <code>if (stringA == stringB)</code> and not <code>if (stringA.equals(stringB))</code>.</p>
<blockquote>
<p>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?</p>
</blockquote>
<p>One way of using that is to use distributed lock mechanism using separate component such as Redis. Here is the link to the guide to utilize Java Redis library redisson for that purpose: <a href="https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers" rel="nofollow noreferrer">https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers</a>. Below is code sample taken from that page:</p>
<pre><code>RLock lock = redisson.getLock(&quot;myLock&quot;);

// 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
}
</code></pre>
