<p>I have the following cronjob which deletes pods in a specific namespace.</p>
<p>I run the job as-is but it seems that the job doesn't run for each 20 min, it runs every few (2-3) min,
what I need is that on each 20 min the job will start deleting the pods in the specified namespace and then terminate, any idea what could be wrong here?</p>
<pre><code>apiVersion: batch/v1
kind: CronJob
metadata:
  name: restart
spec:
  schedule: &quot;*/20 * * * *&quot;
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 0
  failedJobsHistoryLimit: 0
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        spec:
          serviceAccountName: sa
          restartPolicy: Never
          containers:
            - name: kubectl
              image: bitnami/kubectl:1.22.3
              command:
                - /bin/sh
                - -c
                - kubectl get pods -o name | while read -r POD; do kubectl delete &quot;$POD&quot;; sleep 30; done
</code></pre>
<p>I'm really not sure why this happens...</p>
<p>Maybe the delete of the pod collapse</p>
<p><strong>update</strong></p>
<p>I tried the following but no pods were deleted,any idea?</p>
<pre><code>apiVersion: batch/v1
kind: CronJob
metadata:
  name: restart
spec:
  schedule: &quot;*/1 * * * *&quot;
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 0
  failedJobsHistoryLimit: 0
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        metadata:
          labels:
            name: restart
        spec:
          serviceAccountName: pod-exterminator
          restartPolicy: Never
          containers:
            - name: kubectl
              image: bitnami/kubectl:1.22.3
              command:
                - /bin/sh
                - -c
                - kubectl get pods -o name --selector name!=restart | while read -r POD; do kubectl delete &quot;$POD&quot;; sleep 10; done.
</code></pre>

<p>This cronjob pod will delete itself at some point during the execution. Causing the job to fail and additionally resetting its back-off count.</p>
<p>The <a href="https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy" rel="nofollow noreferrer">docs</a> say:</p>
<blockquote>
<p>The back-off count is reset when a Job's Pod is deleted or successful without any other Pods for the Job failing around that time.</p>
</blockquote>
<p>You need to apply an appropriate filter. Also note that you can delete all pods with a single command.</p>
<p>Add a label to <code>spec.jobTemplate.spec.template.metadata</code> that you can use for filtering.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: batch/v1
kind: CronJob
metadata:
  name: restart
spec:
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            name: restart # label the pod
</code></pre>
<p>Then use this label to delete all pods that are not the cronjob pod.</p>
<pre class="lang-sh prettyprint-override"><code>kubectl delete pod --selector name!=restart
</code></pre>
<hr />
<p>Since you state in the comments, you <em>need</em> a loop, a full working example may look like this.</p>
<pre class="lang-yaml prettyprint-override"><code>---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: restart
  namespace: sandbox
spec:
  schedule: &quot;*/20 * * * *&quot;
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 0
  failedJobsHistoryLimit: 0
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        metadata:
          labels:
            name: restart
        spec:
          serviceAccountName: restart
          restartPolicy: Never
          containers:
            - name: kubectl
              image: bitnami/kubectl:1.22.3
              command:
                - /bin/sh
                - -c
                - |
                  kubectl get pods -o name --selector &quot;name!=restart&quot; |
                    while read -r POD; do
                      kubectl delete &quot;$POD&quot;
                      sleep 30
                    done
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: restart
  namespace: sandbox
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-management
  namespace: sandbox
rules:
  - apiGroups: [&quot;&quot;]
    resources: [&quot;pods&quot;]
    verbs: [&quot;get&quot;, &quot;watch&quot;, &quot;list&quot;, &quot;delete&quot;]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: restart-pod-management
  namespace: sandbox
subjects:
  - kind: ServiceAccount
    name: restart
    namespace: sandbox
roleRef:
  kind: Role
  name: pod-management
  apiGroup: rbac.authorization.k8s.io
</code></pre>
<pre class="lang-sh prettyprint-override"><code>kubectl create namespace sandbox
kubectl config set-context --current --namespace sandbox
kubectl run pod1 --image busybox -- sleep infinity
kubectl run pod2 --image busybox -- sleep infinity
kubectl apply -f restart.yaml # the above file
</code></pre>
<p>Here you can see how the first pod is getting terminated.</p>
<pre><code>$ kubectl get all
NAME                         READY   STATUS        RESTARTS   AGE
pod/pod1                     1/1     Terminating   0          43s
pod/pod2                     1/1     Running       0          39s
pod/restart-27432801-rrtvm   1/1     Running       0          16s

NAME                    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/restart   */1 * * * *   False     1        17s             36s

NAME                         COMPLETIONS   DURATION   AGE
job.batch/restart-27432801   0/1           17s        17s
</code></pre>
<p>Note that this is actually slightly buggy. Because from the time you're reading the pod list to the time you delete an individual pod in the list, the pod may not exist any more. You could use the below to ignore those cases, since when they are gone you don't need to delete them.</p>
<pre><code>kubectl delete &quot;$POD&quot; || true
</code></pre>
<hr />
<p>That said, since you name your job restart, I assume the purpose of this is to restart the pods of some deployments. You could actually use a proper restart, leveraging Kubernetes <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy" rel="nofollow noreferrer">update strategies</a>.</p>
<pre><code>kubectl rollout restart $(kubectl get deploy -o name)
</code></pre>
<p>With the default update strategy, this will lead to new pods being created first and making sure they are ready before terminating the old ones.</p>
<pre><code>$ kubectl rollout restart $(kubectl get deploy -o name)
NAME                        READY   STATUS              RESTARTS   AGE
pod/app1-56f87fc665-mf9th   0/1     ContainerCreating   0          2s
pod/app1-5cbc776547-fh96w   1/1     Running             0          2m9s
pod/app2-7b9779f767-48kpd   0/1     ContainerCreating   0          2s
pod/app2-8d6454757-xj4zc    1/1     Running             0          2m9s
</code></pre>
<p>This also works with deamonsets.</p>
<pre class="lang-sh prettyprint-override"><code>$ kubectl rollout restart -h
Restart a resource.

     Resource rollout will be restarted.

Examples:
  # Restart a deployment
  kubectl rollout restart deployment/nginx
  
  # Restart a daemon set
  kubectl rollout restart daemonset/abc
</code></pre>
