<p>I have read about the various ways to run tasks periodically in a K8s cluster, but none of them seem to work well for this specific case. I have a deployment &quot;my-depl&quot; that can run an arbitrary number of pods and the task needs to execute periodically inside each pod (basically a shell command that &quot;nudges&quot; the main application once a week or so).</p>
<p>The Kubernetes Cronjob functionality starts a task in its own container. This K8s task does not know how many pods are currently running for &quot;my-depl&quot; and cannot run anything in those pods. Conceivably, I could run kubectl within this K8s Cronjob, but that seems incredibly hacky and dangerous.</p>
<p>The second alternative would be to have crond (or an alternative tool like <a href="https://github.com/dshearer/jobber" rel="nofollow noreferrer">Jobber</a> or <a href="https://github.com/ess/cronenberg" rel="nofollow noreferrer">Cronenberg</a>) run as part of the pod. But that would mean that two processes are running and the container might not die, if only the cron process dies.</p>
<p>The third option is to run a multi-process container via a special init process like <a href="https://github.com/just-containers/s6-overlay" rel="nofollow noreferrer">s6-overlay</a>. This can be made to die if one of the child processes dies, but it seems fairly involved and hardly a first-class feature.</p>
<p>The fourth option I could think of was &quot;don't do this, it's stupid. Redesign your application so it doesn't need to be 'nudged' once a week&quot;. That's a sound suggestion, but a lot of work and I need at least a temporary solution in the meantime.</p>
<p>So, does anyone have a better idea than those detailed here?</p>

<p>I think the simplest solution is to run <code>crond</code> (or an alternative of your choice) in a sidecar container (that is, another container in the same pod). Recall that all containers in a pod share the same network namespace, so <code>localhost</code> is the same thing for all containers.</p>
<p>This means your cron container can happily run a <code>curl</code> or <code>wget</code> command (or whatever else is necessary) to ping your API over the local port.</p>
<p>For example, something like this, in which our cron task simply runs <code>wget</code> against the web server running in the <code>api</code> container:</p>
<pre><code>apiVersion: v1
data:
  root: |
    * * * * * wget -O /tmp/testfile http://127.0.0.1:8080 2&gt; /tmp/testfile.err
kind: ConfigMap
metadata:
  labels:
    app: cron-example
  name: crontabs-ghm86fgddg
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: cron-example
  name: cron-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cron-example
  template:
    metadata:
      labels:
        app: cron-example
    spec:
      containers:
      - image: docker.io/alpinelinux/darkhttpd:latest
        name: api
      - command:
        - /bin/sh
        - -c
        - |
          crontab /data/crontabs/root
          exec crond -f -d0
        image: docker.io/alpine:latest
        name: cron
        volumeMounts:
        - mountPath: /data/crontabs
          name: crontabs
      volumes:
      - configMap:
          name: crontabs-ghm86fgddg
        name: crontabs
</code></pre>
