PCEVA,PC绝对领域,探寻真正的电脑知识
打印 上一主题 下一主题
开启左侧

普通UPS控制多台主机正常关机达成~

[复制链接]
跳转到指定楼层
1#
leavelost 发表于 2017-1-22 22:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
点击数:12381|回复数:21
本帖最后由 leavelost 于 2017-1-23 00:12 编辑

【写在前面】
因为是求助帖,所以全篇无图,都是纯手工码字。
记录自己的折腾过程,也希望大家提出不同的意见思路,
更希望论坛大神能够解答小弟的疑惑~先行谢过!



【背景】
本人非挨踢从业人员,更别提编程能力了,以下内容全部来自谷哥、度娘,在此感谢辛勤付出的原作者们~!


【目前方案】
  • N54L装的是黑裙,7*24小时开机。
  • Homeserver装的是Freenas,只在备份N54L数据时才开机。
  • UPS,型号是APC-BX650,同时为N54L及Homeserver提供电力,但是只有一个usb通讯口,所以接在了24小时开机的N54L上面。


【替代方案】
因为Homeserver的配置比N54L高了好多,只做存储有点于心不忍,所以准备调换一下2台机器的角色。
  • N54L装Freenas9.10.2-U1,只在备份Homeserver数据时才开机。
  • Homeserver用U盘装Esxi6.0,挂一个480G的SSD,里面装黑裙(挂载主板Lsi芯片直通的机械硬盘),再装一些尝鲜的系统,7*24开机
  • UPS只有一个通讯口,所以必须接在7*24的机器上,也就是ESXI上面。
但是APC官方没有提供这款UPS对ESXI的支持(其实普通的UPS都不带这种支持),所以才有了这篇文章。。。

【方案改进】
  • 原理:通过搜索,找到了三种能够1台UPS控制多台主机的软件方案,APCUPSD,Winpower,NUT(network ups tool),基本原理很简单,所有电脑的电源都接在UPS上,然后分别在主机(与UPS通讯的机器)和客户机上安装上述软件中的一款,当没有市电的时候,UPS转用内部电池,并通过通讯接口向主机发送信号,主机接收到UPS的信号后,通知客户机关机,等所有的客户机关机后,主机最后执行关闭本机和关闭UPS的操作,整个断电关机过程完毕。而且当客户机是ESXI时,只要ESXI中的VM安装了VMtool,就可以做到安全关闭VM——安全关闭ESXI——通知主机。
  • 选择:由于Freenas内置了NUT,而NUT对其他两种软件的兼容不好(虽然有APCUPSD-controlled devices这个驱动,但是撸主我不会设置。。。),所以追求完美的我,果断放弃了前2种软件,专攻NUT的“研究”。
  • 研究:原理说了整套方案以一台主机为核心,主机可以是安装了任意操作系统的“电脑”,所以也就包括了Homeserver上ESXI里的VM,但是因为Esxi系统里VM的嵌套,开关机顺序的问题,需要比较复杂的脚本才能做到:直通VM1的UPS断电——UPS通知VM1——VM1通知ESXI——ESXI依次关闭所有VM——UPS断电关闭,所以机智的我选择用一个低功耗的树莓派来充当UPS主机。
  • 结果:UPS通讯接口连接树莓派,UPS提供电源给N54L,Homeserver,树莓派,交换机(如果断网主机就没办法通知和接收客户机信号了)

         
撸主很顺利的完成了链接1的内容,断电后树莓派立刻通知Freenas关机,但是NUT默认设置是等到UPS发出低电量警告后,再通知
主机关机、UPS关闭,所以撸主等了整整15分钟,树莓派才关机并关闭了UPS。


【问题疑惑】
  • 根据链接2、3的教程,撸主没能成功关闭ESXI,希望感兴趣的坛友能尝试一下~
       想到能在ESXI里添加脚本,来达到树莓派远程通知ESXI依次关闭VM,最后关闭ESXI自己的功能,
       第一步,因为ESXI安装目录下不能存放非ESXI文件,所以将连接中的脚本powerdown-esxi6.sh保
                     存在SSD上(ESXI装在U盘里的)
测通过Xshell连上ESXI,执行powerdown-esxi6.sh,
                     可以安全做到依次关闭VM,最后ESXI关机。
  1. #!/bin/ash
  2. # title: powerdown-esxi6.sh
  3. # version: 0.5
  4. # date: october 09, 2011
  5. # author: herwarth heitmann
  6. # edit by: massimo vannucci

  7. #variables
  8. PATH=/bin:/sbin:/usr/bin:/usr/sbin
  9. VIMSH_WRAPPER=vim-cmd
  10. VM_FILE=vm_list
  11. INTERVAL=60
  12. MAXLOOP=3
  13. #DATE=`date "+%Y-%m-%d   %H:%M:%S"`
  14. # To enable logging, set the following variable to 1
  15. LOG_ENABLED=1
  16. LOG_FILE=/vmfs/volumes/sandisk480g/powerdown-esxi6.log
  17. # Remember that >> after echo, redirect and append to file

  18. # Set the log file
  19. if [ $LOG_ENABLED -eq 1 ]; then
  20.   echo -e "\n\n\n"`date "+%Y-%m-%d   %H:%M:%S"` "\t\tExecuting powerdown-esxi5.sh" >> $LOG_FILE
  21. fi

  22. #check if parameter given
  23. case "$1" in
  24.     "") LASTACTION=shutdown
  25.         ;;
  26. reboot) LASTACTION=reboot
  27.         ;;
  28. vmonly) LASTACTION=vmonly
  29.         ;;
  30.      *) echo "usage $0 <|vmonly|reboot>"
  31.         exit 1
  32.         ;;
  33. esac

  34. #retrieve all VmId for VM(s) registered under ESXi host
  35. ${VIMSH_WRAPPER} vmsvc/getallvms >> $LOG_FILE
  36. ${VIMSH_WRAPPER} vmsvc/getallvms | awk '{print $1}' | grep -v 'Annotation' | grep -v 'Vmid' > $VM_FILE

  37. #first time initialisation
  38. ERROR=0
  39. FIRSTRUN=1
  40. LOOP=0

  41. #we want to run the loop at least 1 time! and loop until no more errors occur
  42. while [ $ERROR -ne 0 -o $FIRSTRUN -eq 1 ]; do
  43.   LOOP=$(($LOOP+1))
  44.   if [ $FIRSTRUN -eq 0 ]; then
  45.     if [ $LOG_ENABLED -eq 1 ]; then
  46.       echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tGive virtual machines time to shutdown..." >> $LOG_FILE
  47.     else
  48.       echo "Give virtual machines time to shutdown..."
  49.     fi
  50.     sleep $INTERVAL
  51.   fi
  52.   #exit loop if $LOOP gets bigger than $MAXLOOP
  53.   if [ $LOOP -gt $MAXLOOP ]; then
  54.     echo "Maximum loops reached!"
  55.     break
  56.   fi

  57.   FIRSTRUN=0
  58.   ERROR=0
  59.   for VM_LINE in $(cat ${VM_FILE}); do
  60.     STATE=$(${VIMSH_WRAPPER} vmsvc/power.getstate ${VM_LINE} | grep -v 'runtime')
  61.     if [ "$STATE" = "Powered off" -o "$STATE" = "Suspended" ]; then
  62.       if [ $LOG_ENABLED -eq 1 ]; then
  63.         echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tVM with ID: ${VM_LINE} is: $STATE, skipping..." >> $LOG_FILE
  64.       else
  65.         echo "VM with ID: ${VM_LINE} is: $STATE, skipping..."
  66.       fi
  67.     else
  68.       #try to do proper shutdown if VMware Tools are installed
  69.       if [ $LOG_ENABLED -eq 1 ]; then
  70.         echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tVM with ID: ${VM_LINE:} is: $STATE, trying guest shutdown..." >> $LOG_FILE
  71.       else
  72.         echo "VM with ID: ${VM_LINE} is: $STATE, trying guest shutdown..."
  73.       fi
  74.       ${VIMSH_WRAPPER} vmsvc/power.shutdown "${VM_LINE}" > /dev/null 2>&1
  75.       #if it fails to shutdown, we know there are no VMware Tools installed
  76.       if [ $? -eq 1 ]; then
  77.         #hard power off
  78.         if [ $LOG_ENABLED -eq 1 ]; then
  79.           echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tGuest shutdown not working, hard powering off" >> $LOG_FILE
  80.         else
  81.           echo -e "\tGuest shutdown not working, hard powering off"
  82.         fi
  83.         ${VIMSH_WRAPPER} vmsvc/power.off "${VM_LINE}" > /dev/null 2>&1
  84.       else
  85.         if [ $LOG_ENABLED -eq 1 ]; then
  86.           echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tSuccessfully initiated shutdown of ${VM_LINE}" >> $LOG_FILE
  87.         else
  88.           echo -e "\t\tSuccessfully initiated shutdown of ${VM_LINE}"
  89.         fi
  90.       fi
  91.       ERROR=$(($ERROR+1))
  92.     fi
  93.   done
  94. done

  95. # clean up temporary file
  96. rm -f $VM_FILE

  97. #execute last action
  98. case "$LASTACTION" in
  99. shutdown) #shutdown ESXi host
  100.           if [ $LOG_ENABLED -eq 1 ]; then
  101.             echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tShutting down ESXi host..." >> $LOG_FILE
  102.           fi
  103.           /sbin/poweroff
  104.           ;;
  105.   reboot) #reboot ESXi host
  106.           if [ $LOG_ENABLED -eq 1 ]; then
  107.             echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tRebooting ESXi host..." >> $LOG_FILE
  108.           fi
  109.           /sbin/reboot
  110.           ;;
  111.   vmonly) #do nothing! only VMs needed to be shutdown
  112.           if [ $LOG_ENABLED -eq 1 ]; then
  113.             echo -e `date "+%Y-%m-%d   %H:%M:%S"` "\t\tDo nothing with ESXi host..." >> $LOG_FILE
  114.           fi
  115.           ;;
  116. esac
  117. exit 0
复制代码
       第二步,现在来到树莓派上,参考:https://gist.github.com/gschora/a10f0692e6e691aa1af8
                     
建立一个新文件notifyme,赋予可执行属性,内容如下:
  1. #! /bin/bash
  2. WALL=wall

  3. #在树莓派命令行中显示“123abc”,已确认此脚本被正确执行
  4. echo "123abc" | ${WALL}

  5. #通过ssh连接ESXI,并执行之前已经在SSD中建立的ESXI关机脚本
  6. ssh root@192.168.2.50 "nohup /vmfs/volumes/sandisk480g/powerdown-esxi6.sh > /dev/null 2>&1 &"
复制代码
                    因为之前已经将ESXI和树莓派的密钥配对了,所以在树莓派上执行notifyme后,树莓派中命令行显示
                   “
123abc”,后台远程登陆ESXI(自动登陆,无需输入ESXI账号密码),
                     并执行ESXI上ssd中的powerdown-esxi6.sh,

                     ESXI开始依次关闭VM,然后关闭自己,到目前为止一些顺利~
       第三步,根据NUT的文档:http://networkupstools.org/docs/user-manual.chunked/ar01s07.html
                     可以设置当UPS使用内置电池供电时,即ONBATT这个状态,调用执行在upsmon.conf中预先设的命令,
                     而我调用的就是刚才建立的notfiyme命令,现在实验一下,断开UPS的市电,树莓派上显示on battery
                     接着显示“123abc”(表明已经正确调用notifyme了),但是。。。远程的ESXI并没有树莓派登陆的日志
                     更不用提执行ssd中的关机脚本了。。。
       更新第三步,原来linux的权限太规范了~,NUT在执行脚本的时候是用nut这个用户,而nut用户默认没有bin的权限,我也没有将nut用户的公钥传到esxi主机上,现 在完成以上2个操作后,当树莓派上的ups没有市电进入时,esxi也可以顺利的完全关机了~下一阶段试着改变NUT的默认设置,让它可以在ups供电几分钟后关闭ups,而不是等到电池快耗尽了才关闭

再次感谢@helhades @xudaiqing 两位~




2#
xffsfy 发表于 2017-1-22 22:22 | 只看该作者
本帖最后由 xffsfy 于 2017-1-22 22:24 编辑

这一堆字....
CHH有个傻瓜脚本,每隔一段时间ping网关路由/主NAS,连续N次ping不通关机。
3#
leavelost  楼主| 发表于 2017-1-22 22:30 | 只看该作者
xffsfy 发表于 2017-1-22 22:22
这一堆字....
CHH有个傻瓜脚本,每隔一段时间ping网关路由/主NAS,连续N次ping不通关机。
...

感谢回复~

因为是门外汉,所以表述的比较啰嗦,不过又喜欢各种折腾。。。

如果UPS上有多台设备连接,光用ping的话,所有机器是关了,

但UPS自己没办法提前自动关闭,只能等电量快用光了才自动关闭

4#
xudaiqing 发表于 2017-1-22 22:31 | 只看该作者
按照你写的bash脚本,123abc只代表脚本被执行,不代表ssh命令执行成功。
NUT执行脚本是用的应该是nut的账号,你在你的账号下配的密匙对是没有用的。
如果安全不是特别重要,建议直接把密码明文写在脚本里。
5#
helhades 发表于 2017-1-22 22:31 | 只看该作者
我没细看你的帖子 就问一句 你是否设置了无密码登录 也就是放置了你的公钥到esxi上
6#
leavelost  楼主| 发表于 2017-1-22 22:35 | 只看该作者
xudaiqing 发表于 2017-1-22 22:31
按照你写的bash脚本,123abc只代表脚本被执行,不代表ssh命令执行成功。
NUT执行脚本是用的应该是nut的账号 ...

感谢回复,如果直接在树莓派命令行执行这个notifyme脚本,是可以远程关闭vm及esxi的
现在放到nut的脚本里,虽然nut执行了notifyme脚本,并显示了echo部分,可余下的ssh没有执行

7#
leavelost  楼主| 发表于 2017-1-22 22:37 | 只看该作者
helhades 发表于 2017-1-22 22:31
我没细看你的帖子 就问一句 你是否设置了无密码登录 也就是放置了你的公钥到esxi上 ...

感谢回复,
树莓派的pi用户及root用户的公钥都放到esxi里了
目前直接在树莓派的命令行执行notifyme,可以远程关闭vm及esxi本体
但是放到nut里调用执行的话,只有echo部分有效,shh部分没有执行~
8#
helhades 发表于 2017-1-22 22:41 | 只看该作者
leavelost 发表于 2017-1-22 22:37
感谢回复,
树莓派的pi用户及root用户的公钥都放到esxi里了
目前直接在树莓派的命令行执行notifyme,可以 ...

你确定你的无密码登录时有效么
9#
leavelost  楼主| 发表于 2017-1-22 22:49 | 只看该作者
helhades 发表于 2017-1-22 22:41
你确定你的无密码登录时有效么

我在命令行下用普通用户pi,还有root都试过notifyme,可以执行并关闭远程vm和esxi

刚才楼上有位说NUT执行是用nut用户,我不知道和这个是不是有关,
10#
leavelost  楼主| 发表于 2017-1-22 22:50 | 只看该作者
本帖最后由 leavelost 于 2017-1-22 22:55 编辑
xudaiqing 发表于 2017-1-22 22:31
按照你写的bash脚本,123abc只代表脚本被执行,不代表ssh命令执行成功。
NUT执行脚本是用的应该是nut的账号 ...

你的意思是我在命令行执行时因为是pi或root,而且已经和esxi配对公钥了,所以ssh命令被执行了,但是NUT执行脚本用的是nut用户,没有权利执行ssh?


11#
Mufasa 发表于 2017-1-22 22:56 | 只看该作者
说点题外话:

我会用折腾软件的时间和精力,购置一台长延时UPS,并且配置足够大的电池。
电池容量至少做到无人值守的情况下一天一夜不关机。
NAS功耗很低,其实电池不会大得离谱。。。。
然后,放心用吧。
12#
leavelost  楼主| 发表于 2017-1-22 22:59 | 只看该作者
感谢回复

因为是家庭用户,所以我更希望用花时间折腾软件来代替花钱折腾硬件~
13#
helhades 发表于 2017-1-22 23:26 | 只看该作者
leavelost 发表于 2017-1-22 22:49
我在命令行下用普通用户pi,还有root都试过notifyme,可以执行并关闭远程vm和esxi

刚才楼上有位说NUT执 ...

我的意思是 你在pi下执行ssh root@你的esxi 是否能直接登录进你的esxi主机
而无须输入密码
14#
nighttob 发表于 2017-1-22 23:35 | 只看该作者
本帖最后由 nighttob 于 2017-1-22 23:40 编辑

你就按2楼说的,弄一个ping脚本
UPS就来一个最低端的后备式就行,反正后备式的策略基本都是最长放电5分钟,然后自己关机

或者多花点钱弄带网络管理卡的APC,能通知整个LAN内的机器
我想你也应该看到知道了

基础设施这部分,要么省钱省到底,要么能花1快钱解决的花10块,不然最后肯定是痛苦
15#
nighttob 发表于 2017-1-22 23:36 | 只看该作者
还有一点,我不喜欢只要跟存储沾边的就开存储区
这帖子跟存储其实没啥关系,应该算整机方案
不过我要懒的话就不丢了
16#
leavelost  楼主| 发表于 2017-1-22 23:38 | 只看该作者
helhades 发表于 2017-1-22 23:26
我的意思是 你在pi下执行ssh root@你的esxi 是否能直接登录进你的esxi主机
而无须输入密码
...

感谢回复

我在pi和root下都可以直接ssh root@esxi的IP 无需密码登陆

我现在尝试将nut用户的公钥加到esxi里去

nut没有bin和sudo的权限

正在学习如何操作~
17#
leavelost  楼主| 发表于 2017-1-22 23:39 | 只看该作者
nighttob 发表于 2017-1-22 23:36
还有一点,我不喜欢只要跟存储沾边的就开存储区
这帖子跟存储其实没啥关系,应该算整机方案
不过我要懒的话 ...

大大,我错了,因为着急,也没想着发那个区比较合适~
18#
leavelost  楼主| 发表于 2017-1-22 23:51 | 只看该作者
@helhades @xudaiqing
非常感谢2位的提点
NUT执行脚本时,果然是用nut用户,
我现在把nut用户的公钥传到esxi后,断电关机脚本顺利执行了~!
再次感谢两位的帮助!
19#
leavelost  楼主| 发表于 2017-1-22 23:57 | 只看该作者
下一阶段试着改变NUT的默认设置,让它可以提早到ups供电X分钟后就关闭ups,而不是等到电池快耗尽了才关闭
20#
中华田园犬 发表于 2017-1-23 14:14 | 只看该作者
文字很多看着感觉比较高级但也很枯燥没看完
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部