如何根据CPU使用情况自动终止空闲GCE实例?

时间:2015-05-31 11:35:20

标签: google-compute-engine

我在实例组中的某些实例上运行了一些稍微不可靠的软件。该软件由启动脚本安装和运行,并且大部分时间都可以正常运行,但是由于软件中存在某种类型的内存泄漏,大约约10%的新实例会因内存耗尽而崩溃。我自己无法修复这个漏洞,所以在此期间,我每隔几个小时检查一次实例并查杀显示空闲CPU的任何内容(该软件正常消耗所有可用的CPU电源)。

但是,我使用了可抢占的实例,它们可以随时被杀死并重新启动,只要我没有主动监视它们就会使死机运行。经过一天无人看管后,我通常会在仪表板中看到约80-85%的CPU使用率,其余部分都被浪费了。

有没有任何自动化的方法可以杀死这些死亡的实例?重新启动它们已由实例组处理。

4 个答案:

答案 0 :(得分:6)

以下对我有用。它是一个bash脚本,它使用uptime UNIX命令检查CPU上的15分钟平均负载是否低于阈值,并在连续十次检查时自动关闭系统。您需要在VM实例中运行它。

信用,更详细的解释:Rohit Rawat's blog

#!/bin/bash
threshold=0.4

count=0
while true
do

  load=$(uptime | sed -e 's/.*load average: //g' | awk '{ print $3 }')
  res=$(echo $load'<'$threshold | bc -l)
  if (( $res ))
  then
    echo "Idling.."
    ((count+=1))
  fi
  echo "Idle minutes count = $count"

  if (( count>10 ))
  then
    echo Shutting down
    # wait a little bit more before actually pulling the plug
    sleep 300
    sudo poweroff
  fi

  sleep 60

done

答案 1 :(得分:1)

这个问题似乎有两个部分:

  1. 识别死亡实例。
  2. 解除这些情况。
  3. 在识别死实例方面,一种方法是使用一个单独的管理实例,该实例不运行此软件并密切关注其他实例。例如,它可以通过定期向各种实例发送运行状况请求并将报告过高CPU使用率的非响应实例或实例标记为不健康来实现此目的。

    一旦您的管理实例识别出需要重置的不健康实例,您应该能够使用API​​重置其他实例(我猜测reset命令)或执行相同的操作使用gcloud命令行工具进行操作。

答案 2 :(得分:0)

使用viswajithiii的答案和以下信息,无需使用BC(不适用于GCP容器操作系统),该方法即可工作: How can I replace 'bc' tool in my bash script?

它还会在关闭电源之前将历史记录列表追加到文件中。我将阈值设置得很低,但是即使通过cli编辑文件,负载也显示为0.00。如果实例承受重负载,则可能会更好地工作。

#!/bin/bash
threshold=10

count=0
while true
do

  load=$(uptime | sed -e 's/.*load average: //g' | awk '{ print $3 }')
  load2=$(awk -v a="$load" 'BEGIN {print a*100}')
  echo $load2
  if [ $load2 -lt $threshold ]
  then
    echo "Idling.."
    ((count+=1))
  fi
  echo "Idle minutes count = $count"

  if (( count>10 ))
  then
    echo Shutting down
    # wait a little bit more before actually pulling the plug
    sleep 300
    history -a
    sudo poweroff
  fi

  sleep 60

done

这不适用于我的CPU较低的情况,但这似乎也是:

#!/bin/bash
threshold=1

count=0
while true
do

  load=$(awk '{u=$2+$4; t=$2+$4+$5; if (NR==1){u1=u; t1=t;} else print ($2+$4-u1) * 1000 / (t-t1); }' <(grep 'cpu ' /proc/stat) <(sleep 1;grep 'cpu ' /proc/stat))
  load2=$(printf "%.0f\n" $load)  
  echo $load
  echo $load2
  if [[ $load2 -lt $threshold ]]
  then
    echo "Idling.."
    ((count+=1))
  fi
  echo "Idle minutes count = $count"

  if (( count>10 ))
  then
    echo Shutting down
    # wait a little bit more before actually pulling the plug
    sleep 300
    history -a
    sudo poweroff
  fi

  sleep 60

done

由于某种原因,它仅适用于两种回波负载。

积分:

How to get overall CPU usage (e.g. 57%) on Linux https://unix.stackexchange.com/questions/89712/how-to-convert-floating-point-number-to-integer

仅供参考:根据此说明,GCP监视代理不适用于N个类型的实例:Google Cloud Platform: how to monitor memory usage of VM instances

将其放在/etc/my_init.d中的启动脚本中,并使其可执行:

sudo mkdir /etc/my_init.d
sudo mv autooff.sh /etc/my_init.d/autooff.sh
sudo chmod 755 /etc/my_init.d/autooff.sh

实际上,这已被删除。而是在实例的“编辑”中添加到“自定义元数据”:startup-script#! /bin/bash \n~./autooff.sh

答案 3 :(得分:0)

我希望我能将此作为评论添加到 viswajithiii answer,但我只是羞于发表评论所需的声誉。

当我使用具有可变 CPU 数量的云虚拟机时,我发现静态 threshold 变量是不合适的,因为 uptime 的输出随 CPU 的数量而变化,如 here 所述。

我更新的脚本在 threshold 赋值下方添加了两行,以按 cpu 的数量缩放 threshold。这允许我设置一个百分比 cpu 利用率,该百分比将适用于具有不同 CPU 数量的 VM。

否则,脚本与 viswajithiii 的相同。

#!/bin/bash

threshold=0.4
n_cpu=$( grep 'model name' /proc/cpuinfo | wc -l )
threshold=$( echo $n_cpu*$threshold | bc )

count=0
while true
do

  load=$(uptime | sed -e 's/.*load average: //g' | awk '{ print $3 }')
  res=$(echo $load'<'$threshold | bc -l)
  if (( $res ))
  then
    echo "Idling.."
    ((count+=1))
  fi
  echo "Idle minutes count = $count"

  if (( count>10 ))
  then
    echo Shutting down
    # wait a little bit more before actually pulling the plug
    sleep 300
    sudo poweroff
  fi

  sleep 60

done