本文目录
背景和方案选型
我们在《Azure云上SAP-灾备站点部署和配置 》一文中,演示了如何通过Linux内置的crontab来定时执行rsync脚本达到备份文件夹的目的。但是如果某个客户系统中有多个虚拟机需要定时执行脚本,通过Linux的内置crontab显然不合适。因此有一个能够集中化管理Job,查看Job运行历史的工具显得尤为重要,在微软的Azure云平台上,Azure Automation Runbook是不二之选。而且在Azure Automation Runbook 中,我们还可以对Azure资源进行管理,比如在运行Job前,开启虚拟机,在运行Job后关闭虚拟机,为客户节省成本,本文后续会演示到。
管理Job的平台有了,如何在Job中远程执行Bash脚本呢?要通过SSH吗,显然不行,因为假如我们选择SSH,那么就需要我们系统的每台机器都要具备一个公网IP,这样无疑把整个系统暴露在公网上,非常危险。所以经过诸多权衡后,我们选择了Azure VM Extension,考量如下:
- Azure VM Extension可以用Azure PowerShell或者Azure CLI来调用,刚好Azure Automation Runbook中支持Azure PowerShell。
- Azure VM Extension 最终是通过Azure 虚拟机中内置的Azure Agent调用的,所以我们不用关心每台机器的用户名是什么,密码是什么,什么时候过期。即:用户凭据无关性。
- 而且Azure VM Extension的部署先天支持把要运行的脚本或者依赖的资源存放在Azure存储账号中,同样也可以对我们要执行的的脚本进行集中化管理,而不是分散在每一台Linux机器内部。
部署和配置
下文将演示如何借助于Azure VM Extension和Azure Automation Runbook来定时在Azure虚拟机中执行Bash脚本。
存储账号的配置
通过Azure的门户创建一个存储账户,添加一个Blob容器,并上传我们的Bash脚本文件。我使用的测试脚本正是《Azure云上SAP-灾备站点部署和配置 》一文中的Bash脚本:/rsync/ascs_sync.sh。
自动化账户的配置
创建自动化账户
Azure 自动化账户的创建可以参考官方文档:《创建Automation Runbook》,不是本文重点。
添加自动化凭据
自动化账号创建完成后,在对应的资源组中双击打开该账号,添加用户凭据。注意了,这里的用户凭据不是虚拟机的用户名密码,而是我们存放Bash脚本的存储账户的账户名称和账户秘钥,形如:
部署PowerShell Runbook
选择自动化账户的【流程自动化】->【Runbook】-> 【添加Runbook】:
选择【创建新的Runbook】,【Runbook类型】选择【PowerShell】
点击【创建】按钮创建完毕后,会自动弹出PowerShell脚本编辑框,请依次输入下文中所有脚本片段:
PowerShell Runbook 脚本编写
PowerShell Runbook 脚本的编写,这是本文的重点。
登陆Azure账户
AzureRunAsConnection是创建Azure自动化账户时会自动创建出来的默认Service Principal 账户,我们可以直接拿来使用,在PowerShell中完成Azure账户登陆,无需配置其他额外账号。
############################ # Login in Azure Account ############################ function Login-azure-account { # Login in with automation connection. try { $servicePrincipalConnection = Get-AutomationConnection -Name 'AzureRunAsConnection' Write-Output "Logging in to Azure by automation connection [AzureRunAsConnection] ..." Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint ` -EnvironmentName AzureChinaCloud } catch { if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $connectionName not found." throw $ErrorMessage } else { Write-Error -Message $_.Exception throw $_.Exception } } }
开机和关机
开启或者关闭Azure虚拟机我们可以使用Start-AzureRmVM和Stop-AzureRmVM命令,我这里做了一个简易的函数,里面封装了点日志输出:
############################ # Start VM ############################ function Set-VM-Online { Write-Output "Start VM $VMName ..." Start-AzureRmVM -ResourceGroupName $RG -Name $VMName Write-Output "Start VM $VMName done." } ############################ # Stop VM ############################ function Set-VM-Offline { Write-Output "Stop VM $VMName ..." Stop-AzureRmVM -ResourceGroupName $RG -Name $VMName -Force $vm = Get-AzureRmVM -ResourceGroupName $RG -Name $VMName -Status Write-Output "Current VM Status = $($vm.Statuses[1].DisplayStatus)" Write-Output "Stop VM $VMName done." }
执行虚拟机扩展脚本
- 变量$Settings中定义了我们Bash脚本在存储账户中的绝对地址;
- 存储账户的名称和秘钥我们没有硬编码在脚本中,而是从上文已创建的Azure自动化账户的用户凭据中读取;
- $protectedSettings中的commandToExecute用来调用Bash脚本,并把脚本输出重定向到机器日志目录。
############################ # Invoke VM extension script ############################ function Invoke-VM-Extension-Script { # Run Script $Settings = @{ "fileUris" = @("https://sh2vmbackup.blob.core.chinacloudapi.cn/rsync-script-hub/ascs-rsync.sh") ; }; # Get storage key from automation credential $storage = Get-AutomationPSCredential -Name 'RsyncScriptStorageCredential' $storageAccount = $storage.UserName $storageKey = $storage.GetNetworkCredential().Password # Define protected settings for vm extension $protectedSettings = @{ "storageAccountName" = $storageAccount ; "storageAccountKey" = $storageKey ; "commandToExecute" = "sh ascs-rsync.sh >> /var/log/ascs_sync.log" } # run vm extension script Write-Output "Run VM Extension script..." Set-AzureRmVMExtension ` -ResourceGroupName $RG ` -VMName $VMName ` -Location 'chinaeast2' ` -Name 'rysnc-backup' ` -Publisher "Microsoft.Azure.Extensions" ` -ExtensionType 'CustomScript' ` -TypeHandlerVersion '2.0' ` -Settings $Settings ` -ProtectedSettings $protectedSettings Write-Output "Run VM Extension script done." }
脚本调用
############################ # Main process ############################ $VMName = "{虚拟机名称}" $RG = '{资源组名称}' Login-azure-account Set-VM-Online sleep -Seconds 60 Invoke-VM-Extension-Script Set-VM-Offline
Runbook 脚本测试
在上文图中展示的脚本编辑框中,点击【测试窗格】,再点击【开始】按钮执行Runbook,下面是执行的截图
Runbook 脚本部署定时执行计划
关闭上图中的测试窗口,回到编辑窗口,点击【发布】
发布后,回到了该Runbook的属性页面,点击【计划】
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!