crontab 定时执行docker exec命令
- 监控docker及docker内程序的运行情况,可以用crontab来实现。在宿主机上设置定时执行任务(每分钟执行一次):
$ crontab -e
# m h dom mon dow command
*/1 * * * * bash /root/check-detect.sh
- 脚本 check-detect.sh:
#!/bin/bash -xv
default_containername=detect1.0
default_homepath=$(dirname $(realpath $0))
containername=$1
if [ "$containername" == "" ]; then containername=${default_containername}; fi
imagename=${containername}:latest
homepath=$2
if [ "$homepath" == "" ]; then homepath=${default_homepath}; fi
logd=${homepath}/log
mkdir -p ${logd}/
logfile=${logd}/log.$(basename $0).$(date +%Y%m%d)
#exec >> ${logfile}
#echo "${logfile} &> /dev/null
#exec 2> ${logfile}
dump() {
echo "$(date +'%Y-%m-%d %H:%M:%S') [log]: $1" >> ${logfile}
}
ERROR_EXIT(){
dump $1
exit 1
}
# start
dump "${HOSTNAME} $(basename $0) start $(date +%Y%m%d%H%M%S) pid:$$"
# check docker
dump "check docker"
if [ `systemctl status docker |grep Active |grep inactive |wc -l` -gt 0 ]; then
dump "starting docker"
systemctl start docker
dump "docker started"
sleep 5
fi
# check docker container
dump "check exists ${containername}"
if [ `docker ps -a |grep ${containername} |wc -l` -lt 1 ]; then
dump "begin to run docker container: ${containername}"
docker run -itd --name ${containername} --privileged=true \
-v ${homepath}/data:/data \
--restart always \
-p 80:80 \
${imagename} /usr/sbin/init
[ $? -ne 0 ] && ERROR_EXIT
dump "${containername} running"
fi
dump "check running ${containername}"
if [ `docker ps |grep ${containername} |wc -l` -lt 1 ]; then
dump "starting ${containername}"
docker start ${containername}
[ $? -ne 0 ] && ERROR_EXIT
dump "${containername} started"
fi
dump "docker exec -it ${containername} bash -c \"bash /quick-start.sh\""
docker exec -it ${containername} bash -c "bash /quick-start.sh"
[ $? -ne 0 ] && ERROR_EXIT "docker-exec-${containername}-error"
# end
dump "${HOSTNAME} $(basename $0) end $(date +%Y%m%d%H%M%S)"
exit 0
设置好后,监控log,发现 docker exec
时总是失败,最后百度+谷歌,找到了原因:
http://www.89cool.com/821.html
Your docker exec command says it needs "pseudo terminal and runs in interactive mode" (-it flags) while cron doesn't attach to any TTYs.
大致意思 exec 加了 -it 参数就开启了一个终端,计划任务是无法进入任何终端的。
把 docker exec
的参数 -it
去掉后问题解决了。
docker exec -it 参数详解:
https://docs.docker.com/engine/reference/commandline/exec/
--interactive , -i Keep STDIN open even if not attached
--tty , -t Allocate a pseudo-TTY
关于tty:
https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/