Executing a Script using a Cronjob Kubernetes Cluster

10/22/2021

I have a 3 node K8 v1.21 cluster in AWS and looking for SOLID config to run a script using a cronjob. I have seen many documents on here and Google using cronjob and hostPath to Persistent Volumes/Claims to using ConfigMaps, the list goes one.

I keep getting "Back-off restarting failed container/CrashLoopBackOff" errors.

Any help is much appreciated.

cronjob.yaml

The script I am trying to run is basic for testing only

#! /bin/<br/>
kubectl create deployment nginx --image=nginx

Still getting the same error.

kubectl describe pod/xxxx

This hostPath in AWS cluster created using eksctl works.

apiVersion: v1
kind: Pod
metadata:
  name: redis-hostpath
spec:
  containers:
  - image: redis
    name: redis-container
    volumeMounts:
    - mountPath: /test-mnt
      name: test-vol
  volumes:
  - name: test-vol
    hostPath:
      path: /test-vol

UPDATE

Tried running your config in GCP on a fresh cluster. Only thing I changed was the /home/script.sh to /home/admin/script.sh

Did you test this on your cluster?

Warning  FailedPostStartHook  5m27s  kubelet            Exec lifecycle hook ([/home/mchung/script.sh]) for Container "busybox" in Pod "dumb-job-1635012900-qphqr_default(305c4ed4-08d1-4585-83e0-37a2bc008487)" failed - error: rpc error: code = Unknown desc = failed to exec in container: failed to create exec "0f9f72ccc6279542f18ebe77f497e8c2a8fd52f8dfad118c723a1ba025b05771": cannot exec in a deleted state: unknown, message: ""
  Normal   Killing              5m27s  kubelet            FailedPostStartHook
-- Skyhawk Para92
kubernetes
kubernetes-cronjob

1 Answer

10/22/2021

Assuming you're running it in a remote multi-node cluster (since you mentioned AWS in your question), hostPath is NOT an option there for volume mount. Your best choice would be to use a ConfigMap and use it as volume mount.

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-script
data:
  script.sh: |
    # write down your script here

And then:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: redis-job
spec:
  schedule: '*/5 * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: redis-container
              image: redis
              args:
                - /bin/sh
                - -c
                - /home/user/script.sh
              volumeMounts:
                - name: redis-data
                  mountPath: /home/user/script.sh
                  subPath: script.sh
          volumes:
            - name: redis-data
              configMap:
                name: redis-script

Hope this helps. Let me know if you face any difficulties.

Update:

I think you're doing something wrong. kubectl isn't something you should run from another container / pod. Because it requires the necessary binary to be existed into that container and an appropriate context set. I'm putting a working manifest below for you to understand the whole concept of running a script as a part of cron job:

apiVersion: v1
kind: ConfigMap
metadata:
  name: script-config
data:
  script.sh: |-
    name=StackOverflow
    echo "I love $name <3"
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: dumb-job
spec:
  schedule: '*/1 * * * *' # every minute
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: busybox
              image: busybox:stable
              lifecycle:
                postStart:
                  exec:
                    command:
                      - /home/script.sh
              volumeMounts:
                - name: some-volume
                  mountPath: /home/script.sh
          volumes:
            - name: some-volume
              configMap:
                name: script-config
          restartPolicy: OnFailure

What it'll do is it'll print some texts in the STDOUT in every minute. Please note that I have put only the commands that container is capable to execute, and kubectl is certainly not one of them which exists in that container out-of-the-box. I hope that is enough to answer your question.

-- msrumon
Source: StackOverflow