点击上方蓝字关注“汪宇杰博客”
导语
微软 Azure 平台的 VM 可以做到定时自动关机,然而只有 DevTest Lab 服务中的 VM 能够定时开机,普通用途的 VM 还没有上线这个功能。但是没关系,我们可以曲线救国,通过最新版的 Azure Function V3 及 PowerShell Core,分分钟让 VM 定时开机。
思路
6年前,我曾经在博客里分享过如何使用 PowerShell 定时开关机 VM,方法是额外新建一台 VM,在上面用计划任务定时跑开关机的脚本去操作目标 VM。这个方法虽然可行,但需要耗费额外的 VM 资源,并且很 996。
https://edi.wang/post/2014/8/25/start-stop-azure-vm-on-schedule
而如今,Azure 已经发生了翻天覆地的变化,Serverless 的 Azure Function 是如今最地道的玩法。Azure Function 可以通过多种 Trigger 触发自定义的代码逻辑,其中有一种就是 Timer,于是通过骚操作,Azure Function 也能够做到定时开关机 VM。
创建 Function App
点击 Create a resource,选择 Function App。起一个好听的名字,比如 start996。
Runtime stack 的意思是该 Function 想用哪种语言编写。Azure Function 提供了主流语言或平台的支持。其中 .NET 据说工资低所以不考虑,Java 又容易脱发,也不考虑,Node.js 和 Python 由于年过 30 学不动了,于是我只能选择 Powershell Core,听说它是跨平台的,现在我们只能选到 6,实际上最新版已经是 7.1 了,不知为何微软还不给自家平台部署最新版。
接下来我们得创建或选择一个存储账户(Storage Account),这是最新版 Azure Function V3 强制规定的,不许拒绝。
Plan type 选择 Consumption (Serverless),这个 Plan 可以根据你的使用量情况动态计费,从而在用量小的时候帮助省钱。
然而我惊喜地发现,说好跨平台的 PowerShell Core,怎么只能选 Windows 呢?还好我是个 Windows 粉,用就用吧。
Application Insights 可以用来监控 Function 的运行健康状况,也能在编写 Function 的时候用作控制台输出的捕获,开不开都行,不开省钱,开了省头发。
创建完成后,我们需要给这个 Function App 配置访问 VM 的权限。
在 Identity 菜单下,打开 System assigned 开关。这种授权方式可以点点鼠标就让 Azure 资源之间互相授权,而不用自己写代码对接各种 Key 什么的导致996。
然后转到需要被操作的 VM 页面,在 Access control (IAM) 中选择 Add a role assignment
在 Assign access to 选项中选择 Function App,然后找到刚才创建的 Function App,添加为 Owner。但需要注意的是,Owner 由于权限最大,并不是最佳实践,真正企业场景里请根据公司安全规范选择合适的权限,以免被人改Function 代码删 VM 跑路。
编写 Function 逻辑
在 Function App 创建完成后,点击进入 Functions,然后点击 Add,创建一个 Function,用于执行定时开机的逻辑。
选择 Timer Trigger
输入 Function 的名字,比如 FubaoTrigger,然后在 Schedule 中输入定时逻辑的表达式。
这个表达式使用 CRON 格式,拿 996 为例,周一到周六,每天早上9点的 CRON 为:0 0 9 * * 1-6
但要注意,这个时间为 UTC 时间。如果你需要更改时区,需要在 Function App 的 Configuration 中添加一个 WEBSITE_TIME_ZONE 的值,如中国大陆时区可配置为 China Standard Time,具体做法请查考文末微软文档链接。
创建完成后,进入 Code + Test,把里面的代码删掉跑路,替换为:
# Input bindings are passed in via param block.
param($Timer)
$subscriptionId = "你的订阅ID"
$tenantId = "你AAD的租户ID"
$rsgName = "目标VM的资源组名称"
$vmName = "目标VM的名称"
Select-AzSubscription -SubscriptionID $subscriptionId -TenantID $tenantId
Start-AzVM -ResourceGroupName $rsgName -Name $vmName
其中 tenantId 可到 Azure Active Directoy 里找到。
脚本中的 param($Timer) 虽然代码逻辑里用不到,但不能删除,这是 Timer Trigger 必须的参数,一删就爆。
Select-AzSubscription 及 Start-AzVM 并不是 PowerShell 自带的模块,而是 Azure PowerShell 的模块,由于 Function 的 Host 上已经安装了 Azure PowerShell,所以此处才能直接使用。
保存代码后,点击 Test / Run,测试一下 Function 是否正常工作。
如果不出问题,我们就能看到目标 VM 从关机状态自动启动。
至此,这个 Azure Function 就可以在周一到周六,每天早上 9 点,准时启动 VM 了!至于定时关机,由于太简单不多介绍了,直接在 VM 的管理菜单里能找到。
参考:
https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=csharp
汪宇杰博客
.NET | Azure | 微软MVP
长按二维码获取我的最新技术分享
喜欢本篇内容请点个在看