不知何时 Azure 为虚机提供了自动关机的功能。这是一个很棒的功能,可以帮助我们定时关闭虚机并释放掉资源以节省开支。如果某台虚机在夜间不需要提供服务,我们就可以把它配置为晚上的某个时间点自动关机:
接下来让人郁闷的事情来了!在配置自动关机的时候我们没有发现定时开机的相关配置!不仅如此,笔者在新建虚机的时候发现默认的设置中居然打开了定时关机的功能:
到此为止笔者好像有些明白了,这一定又是套路!肯定是为了推广某个服务而采取的不友好表现。
没办法,接下来只能靠自己了。最直接的方法就是写一个 PowerShell 脚本,在脚本中登录 Azure,然后执行开机的命令。如果要每天定时开机,可以创建一个计划任务定时执行 PowerShell 脚本就可以了。
具体的实现请参考《Azure 基础:用 PowerShell 自动登录》一文(只要把 demo 中重启虚机的命令改为启动命令就可以了)。但是这种方式有一个缺点:我们保存在文件中的登录信息会过期。也就是说每隔一段时间都需要重新登录一遍并导出新的登录信息到文件中。
既然不掏钱的方法有缺点,就让我们看看 MS 推荐的解决方案(要收费的)。
MS 在云端提供了自动化运维的服务:Automation。所以我们可以通过 Automation 中提供的服务来实现定时开机的功能。
创建 Automation Account
要使用 Automation 进行自动化的工作,需要先新建一个 Automation 类型的服务,其实就是创建一个 Automation Account:
Automation Account 会管理很多的资源,其中最重要的是一些执行各种自动化任务的 runbook:
Azure 提供了多种类型的 runbook,用户可以选择自己喜欢的方式。这里我们新建一个 PowerShell 类型的 runbook:
编辑重启虚机的脚本
创建了 PowerShell 类型的 runbook 后就可以编辑真正干活的脚本了,在 runbook 的编辑器中输入下面的代码:
$connectionName = "AzureRunAsConnection"$rusultMessage = "The virtual machine started successfully."try{ # Get the connection "AzureRunAsConnection" $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint Start-AzureRmVM -Name 'vm name' -ResourceGroupName 'resource group name'}catch { $rusultMessage = "The virtual machine failed to start." if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $connectionName not found." throw $ErrorMessage } else{ Write-Error -Message $_.Exception throw $_.Exception }}finally { $Username ="sendgrid user name" $Password = ConvertTo-SecureString "your password" -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential $Username, $Password $SMTPServer = "smtp.sendgrid.net" $EmailFrom = "No-reply@cmteam.com" [string[]]$EmailTo = "Nick <nick@xxxx.com>" $Subject = "start vm" $Body = $rusultMessage Send-MailMessage -smtpServer $SMTPServer ` -Credential $credential ` -Usessl ` -Port 587 ` -from $EmailFrom ` -to $EmailTo ` -subject $Subject ` -Body $Body ` -BodyAsHtml Write-Output "Email sent succesfully."}
首先,最好是通过异常处理结构处理脚本执行中的异常。这里只是简单的把异常重新抛出,最后它们会被显示到执行的日志中。
接下来的一个很重要的概念是 AutomationConnection。我们可以认为它包含了一些信息可以用来连接需要操作的目标资源并提供相应的认证信息。脚本中使用的 AutomationConnection 名字为 AzureRunAsConnection,它是随着 Automation Account 一起创建的。如果 AzureRunAsConnection 不能满足需求,我们可以创建自定义的 AutomationConnection。
然后通过 Add-AzureRmAccount 命令使用 AzureRunAsConnection 提供的信息进行登录从而获得操作资源的权限。
最后由 Start-AzureRmVM 命令执行启动虚机的操作。
发送邮件
为了 demo 的完整性,笔者通过 finally 结构强制在脚本结束前给管理员发送通知邮件。邮件通过 sendgrid 的服务器进行发送,报告启动虚机的过程是否成功:
$Username ="azure_sendgrid user name@azure.com"$Password = ConvertTo-SecureString "your password" -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential $Username, $Password$SMTPServer = "smtp.sendgrid.net"$EmailFrom = "No-reply@cmteam.com"[string[]]$EmailTo = "Nick <nick@xxxx.com>"$Subject = "start vm"$Body = $rusultMessageSend-MailMessage -smtpServer $SMTPServer ` -Credential $credential ` -Usessl ` -Port 587 ` -from $EmailFrom ` -to $EmailTo ` -subject $Subject ` -Body $Body ` -BodyAsHtmlWrite-Output "Email sent succesfully."
测试脚本的执行情况
在完成脚本的编辑后点击 "Test pane" 进入脚本测试界面,然后点击 "Start" 开始测试:
这个过程会执行你的脚本,并输出执行的日志信息。通过这种方式我们可以检查脚本的执行情况并对脚本进行调整。
配置计划任务
完成脚本的测试后,在编辑界面点击 "Publish" 结束脚本的编辑。然后为 runbook 添加一个计划任务:
上面的配置会在每天早上 6 点钟触发脚本的执行,也就是启动我们指定的虚拟机。
总结
这就 OK 了!是的,看起来还是比较繁琐的。由于内部是通过 Azure 的认证机制完成权限认证的,所以它能够完美的解决我们在其它方案中碰到的登录认证问题。
另外,既然 Automation 服务是专门在云端提供自动化功能的,那它自然应该具有很多拿的出手的能力,笔者后续会对 Azure Automation 做专门的介绍。