Linux的正常关机

Azure 上的 IaaS 虚拟机可使用多种方式关闭,例如通过 Azure 管理门户、Azure Powershell cmdlet 或 CLI 工具,甚至还可以由交互式登录的用户关闭。Azure 平台本身甚至也能关闭虚拟机以执行平台维护。运行在本地裸机中的 Linux 系统的关闭流程很好理解,但是这一切到了云上如何运行呢?

在 Azure 上启动正常关机

在 Azure 中关闭 Linux 虚拟机的流程与本地模式基本一样。当用户登录并运行“/sbin/shutdown now”后,正常结果是系统将立即开始停止任何正在运行的服务,并最终关闭整个系统。当然,具体机制在一定程度上取决于使用的Linux 版本和 Init 系统(通常是 SysV、Upstart 或 Systemd),但结果是一样的。

然而从门户网站或 Azure 平台启动关机时又会发生什么呢?简单来说,答案会是,会发生几乎相同的事情。在这些情况下,Azure 将会与主机通信,启动对来宾 Linux 系统的正常关机。在 Hyper-V 和 Azure 环境下,执行正常关机的信号来自于虚拟化管理程序,由 hv_utils 驱动程序处理。该驱动程序是我们包含在 Linux 内核中的 Linux 集成服务的一部分。该功能称为集成关机

收到虚拟化管理程序的信号后,hv_utils 驱动器将启动 Linux 来宾操作系统的正常关机,所启动机制与用户手动运行“/sbin/shutdown now”基本相同。在 hv_utils 收到虚拟化管理程序发出的信号后,将向日志(通常是 /var/log/messages 或 Ubuntu 系统中的 /var/log/syslog)发送以下信息,表明 Linux 系统已由虚拟化管理程序关闭:

需要注意的是,正常关机过程开始后,Azure 平台不会一直等下去。此平台会留出 5 分钟时间,等待虚拟机正常关机。如果 5 分钟过后虚拟机仍在运行,此平台将强制关闭虚拟机。这一点非常重要,一定要确保您的 VM 运行的所有脚本都能在既定时间内完成随后彻底关机。

管理关机流程

Azure 中 Linux 用户的一个共同要求是,当 Azure 启动 VM 正常关机时,他们的应用程序能够正常关闭。现在我们已了解手动关机和虚拟化应用程序启动关机使用相同的机制,我们只需使用现有 Linux init 系统就能确保应用程序正常关闭。

大多数情况下,现有 SysV、Systemd 或 Upstart 脚本将足以正常关闭应用程序。但是在这些脚本尚不足以正常关闭应用程序或需要运行额外流程来“清理”应用程序时,可以执行以下操作:

  • 当然,最简单的方法就是直接编辑应用程序 init 脚本并添加额外的任务。这种做法存在一些弊端:除编辑脚本时可能出现的明显拼写错误和其他错误以外,由于这些脚本通常由 RPM 或 Deb 包管理,编辑脚本还可能导致此脚本无法升级。不过这种方式的一个优势是因为集成关机是Hyper-V自带的功能,您可以在部署至 Azure 之前在 Hyper-V 上对全部脚本进行本地测试。
  • 另一个方案是创建自己的 init 脚本。目前有很多不同的 init 系统可供 Linux 系统使用,所以创建 init 脚本也会有很多方式。大多数系统都至少拥有 SysV 与本机 init 系统的兼容性,所以最简单的做法就是编写 SysV 兼容性脚本,确保它以运行级别 0 运行。
  • 这个方法可能稍微复杂一点。这是我最近在 Azure 库中使用我们的 CentOS 镜像进行测试时使用的一个方法。对于创建自己的 init 脚本执行所需预关机操作而言,此脚本可能是一个很好的起点。但是,别忘了在我们的 VM 关闭电源前,我们还有 5 分钟的时间进行清理。

不过就像 Linux 本身一样,这里可能不会有一个适合所有版本和工作负荷的万全之策。重点在于,尽管有很多的解决方法,要在 Hyper-V 或 Azure 上彻底关闭我们的 VM,我们需要采取的做法并无特别之处。我们仍然能够使用特定 Linux 版本上的常规程序和机制,同时还能享受将这些系统托管至 Azure 的优势。

 本文翻译自:

https://azure.microsoft.com/blog/2014/05/06/linux-and-graceful-shutdowns-2/