docker热重启,临时解决docker内存泄漏问题
#!/bin/bash #####################################自定义变量区 #内存阈值 host_mem_limit=60 #主机内存占用阈值,单位%(百分比) max_mem_gb=5 ##dockerd内存占用阈值,单位GB ###########################业务方法区#################################### hotRestartDockerd(){ echo "hotRestartDockerd" DOCKERD_CONF='/etc/docker/daemon.json' [ ! -f "$DOCKERD_CONF" ] && echo "error, failed to find $DOCKERD_CONF " && exit 1 [ ! -s "$DOCKERD_CONF" ] && echo "error, $DOCKERD_CONF is empty" && exit 2 DOCKERD_PID=$(systemctl status docker | grep "Main PID" | awk '{print $3}') [ -z "$DOCKERD_PID" ] && echo "error, dockerd is not running" && exit 3 # enable Live Restore CHANGED="" if !( docker info | grep -i "Live Restore Enabled" | grep -i "true" > /dev/null ) ; then echo "enable Live Restore " cp -f $DOCKERD_CONF $DOCKERD_CONF-backup sed -i '/live-restore/ d' $DOCKERD_CONF sed -i -E 's/^\{$/\{\n "live-restore": true , /' $DOCKERD_CONF CHANGED="1" kill -SIGHUP $DOCKERD_PID sleep 5 if !( docker info | grep -i "Live Restore Enabled" | grep -i "true" > /dev/null ) ; then echo "error, failed to enable Live Restore " exit 4 fi fi systemctl restart docker echo "restarting docker " OK="" for((i=0;i<10;i++)) ; do sleep 4 ( systemctl status docker | grep "Active: active (running)" &> /dev/null ) \ && OK="1" && break done [ -z "$OK" ] && echo "error, failed to restart docker" && exit 5 if [ -n "$CHANGED" ] ; then sed -i '/live-restore/ d' $DOCKERD_CONF sed -i -E 's/^\{$/\{\n "live-restore": false , /' $DOCKERD_CONF kill -SIGHUP $(systemctl status docker | grep "Main PID" | awk '{print $3}') rm -f $DOCKERD_CONF mv $DOCKERD_CONF-backup $DOCKERD_CONF sleep 5 fi echo "finished restarting dockerd" } restartSpecialCon(){ echo "restart related contariners which wants to communicate with " LIST=` docker inspect $(docker ps -q)|grep 'Source.*docker.sock\|Name": "/'|grep sock -B1|grep Name | awk -F'"' '{print $4}' | sed 's/^\///' ` [ -z "$LIST" ] && echo "no container needed to restart , finish" && return 0 for NAME in $LIST ; do docker restart $NAME done } #判断docker的文件系统是否为xfs,非xfs如果daemon.json设置了overlay2.size会导致docker重启异常 checkFileSystem(){ local daemonPath="/etc/docker/daemon.json" backing_fs=$(docker info | grep "Backing Filesystem" | awk '{print $3}') if [ "${backing_fs}" = "extfs" ]; then # 检查/etc/docker/daemon.json文件中是否配置了overlay2.size if grep -q "overlay2.size" ${daemonPath}; then sed -i '/"storage-opts": \[/,/]/d' ${daemonPath} fi fi # 检查倒数第二行是否以逗号结尾 second_last_line=$(tail -n 2 "${daemonPath}" | head -n 1) if [[ ${second_last_line} =~ ,$ ]]; then # 删除倒数第二行的逗号 sed -i '$!N;$s/,\n/\n/;P;D' "${daemonPath}" echo "已删除倒数第二行的逗号" else echo "倒数第二行不以逗号结尾,无需删除" fi } ##############################执行逻辑区######################### mem_used=$(free | awk '/^Mem/ {print $3/$2 * 100.0}') mem_used=${mem_used%.*} if [ ${mem_used} -gt ${host_mem_limit} ]; then # 获取进程内存占用值(单位为 GB) dockerd_mem_gb=$(ps -p $(systemctl status docker | grep "Main PID" | awk '{print $3}') -o rss= | awk '{ printf "%.2f", $1/1024/1024 }') echo -e "${dockerd_mem_gb%.*} ${max_mem_gb}" if [ ${dockerd_mem_gb%.*} -ge ${max_mem_gb} ]; then echo -e "$(date +"%Y-%m-%d %H:%M:%S") $(hostname) 主机内存占用率超过:${limit}% dockerd 进程内存占用超过 ${max_mem_gb} GB,执行热重启" #执行热重启前先校验docker文件系统,若非xfs需要修改daemon.json文件避免热重启失败 checkFileSystem # 执行dockerd热重启 hotRestartDockerd restartSpecialCon echo -e "$(date +"%Y-%m-%d %H:%M:%S") $(hostname) finished" else echo -e "$(date +"%Y-%m-%d %H:%M:%S") $(hostname) 主机内存使用量超出${host_mem_limit}%的限制范围,dockerd服务内存占用在${max_mem_gb} GB范围内,当前占用为${dockerd_mem_gb} GB." fi else echo -e "$(date +"%Y-%m-%d %H:%M:%S") $(hostname) 内存使用量在${host_mem_limit}%的限制范围内." fi
本文系作者 @Mr.Lee 原创发布在 维简网。未经许可,禁止转载。