Execute a Script in a Container on Startup in OpenShift

  1. Edit the pod or deployment YAML. For example:
    oc edit deployment deployment1
  2. Add a lifecycle.postStart.exec.command element to the target container(s) that executes a diagnostic script. For example, the following sleeps 5 seconds and then gathers javacores 30 seconds apart forever (change PID as required):
    spec:
      containers:
      - name: [...]
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "cd /tmp/; echo -e '#!/bin/sh \n sleep 5; PID=1; while true; do kill -3 ${PID}; sleep 30; done' > diag.sh; chmod +x diag.sh; ./diag.sh &"]
  3. Save the YAML and the pods will restart.

Notes:

  1. The script must be run in the background (&) because Kubernetes won't set the container to RUNNING until the postStart script "completes", though nohup isn't needed as there's no console attached that could get SIGHUP.
  2. Other common use cases:
    1. Loop for a certain number of times and then end the script:
      command: ["/bin/sh", "-c", "cd /tmp/; echo -e '#!/bin/sh \n sleep 5; PID=1; i=0; while [ $i -le 5 ]; do kill -3 ${PID}; sleep 30; i=$(( i + 1 )); done' > diag.sh; chmod +x diag.sh; ./diag.sh &"]
    2. Print out some information to a file periodically:
      command: ["/bin/sh", "-c", "cd /tmp/; echo -e '#!/bin/sh \n sleep 5; OUTPUTFILE=\"output_diag_${HOSTNAME}_$(date +\"%Y%m%d_%H%M%S\").txt\"; while true; do echo $(date) >> ${OUTPUTFILE}; cat /sys/fs/cgroup/memory.stat >> ${OUTPUTFILE}; sleep 10; done' > diag.sh; chmod +x diag.sh; ./diag.sh &"]
    3. Print container memory information to a file periodically:
      command: ["/bin/sh", "-c", "cd /tmp/; echo -e '#!/bin/sh \n SLEEPTIMESECONDS=600; OUTPUTFILE=\"stdout_memorystat_${HOSTNAME}_$(date +\"%Y%m%d_%H%M%S\").txt\"; sleep 5; echo \"[$(date)] Started $(basename \"${0}\") in background (PID $$)\" >> ${OUTPUTFILE}; while true; do echo \"[$(date)] Performing iteration\" >> ${OUTPUTFILE}; for FILE in $(ls /proc/meminfo /sys/fs/cgroup/memory* /sys/fs/cgroup/*/*/memory* /proc/[0-9]*/smaps*); do echo \"[$(date)] Gathering ${FILE}\" >> ${OUTPUTFILE}; cat ${FILE} >> ${OUTPUTFILE}; done; echo \"[$(date)] Sleeping for ${SLEEPTIMESECONDS} seconds...\" >> ${OUTPUTFILE}; sleep ${SLEEPTIMESECONDS}; done' > memorystat.sh; chmod +x memorystat.sh; ./memorystat.sh &> stderr_memorystat.txt &"]
    4. Execute some other script that's already available in the container:
      command: ["/bin/sh", "-c", "cd /pvc/; ./diag.sh &"]