Execute a Script in a Container on Startup in OpenShift
- Edit the pod or deployment YAML. For example:
oc edit deployment deployment1 - Add a
lifecycle.postStart.exec.commandelement 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 (changePIDas 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 &"] - Save the YAML and the pods will restart.
Notes:
- The script must be run in the background (
&) because Kubernetes won't set the container toRUNNINGuntil the postStart script "completes", thoughnohupisn't needed as there's no console attached that could getSIGHUP. - Other common use cases:
- 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 &"] - 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 &"] - 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 &"] - Execute some other script that's already available in the container:
command: ["/bin/sh", "-c", "cd /pvc/; ./diag.sh &"]
- Loop for a certain number of times and then end the script: