【问题标题】:Windows Azure Virtual Machine with Startup Task具有启动任务的 Windows Azure 虚拟机
【发布时间】:2014-03-12 23:55:39
【问题描述】:

有没有办法通过 API 将(参数化的)启动任务添加到 Windows Azure 虚拟机?我需要在机器启动后执行一个 cmdlet,并且代码取决于两个参数,这两个参数对于每台机器都是不同的。我知道这对于 Web/Worker 角色很容易实现,但是对于虚拟机也可以做到吗?

【问题讨论】:

    标签: windows powershell azure azure-virtual-machine


    【解决方案1】:

    对于首次运行 VM,您可以通过 CustomData 注入启动任务。这适用于 Linux 和 Windows VM。您只需要根据 REST API 文档正确地对您的文件(无论是文本还是二进制文件)进行 base-64 编码。

    CustomData 被放入特定位置的文件中,您可以使用代码查找该文件,并根据需要采取某种类型的启动操作:

    • 窗口:%SYSTEMDRIVE%\AzureData\CustomData.bin
    • Linux:/var/lib/waagent/CustomData

    注意:这也将被添加到 CLI 中(拉取请求已经可用 - 不确定它是否在最新版本中。

    编辑是的,customdata 现在是 Azure CLI 的一部分,作为 azure vm create 的参数,因此无需自己搞乱 base-64 编码:

    【讨论】:

    • “CustomData 被放入特定位置的文件中,您可以使用代码查找此文件,并根据需要采取某种类型的启动操作”您能详细说明一下吗?这段代码应该去哪里?是不是和上一篇文章的思路一样,启动代码在Registry里面?或者有没有办法在不从其他地方调用它的情况下执行该 CustomData 文件?谢谢。
    • CustomData 只是一个文件。您需要一些代码来查找它的存在并对其进行处理。 Windows 和 Linux 操作系统都可以通过脚本、操作系统设置等方式添加要在启动时运行的进程。您可以运行控制台式应用程序,该应用程序在目录中查找、找到文件、采取特定操作,然后删除文件。如果应用程序检查时文件不存在,它可以简单地退出,甚至可以修改 VM 的启动顺序以停止运行。
    • @DavidMakogon 这个自定义数据文件会被执行吗?用 cmd 还是 powershell?
    【解决方案2】:

    没有。目前没有提供开箱即用的此类功能。

    但是,鉴于您无论如何都会处理 VM,您可以创建自己的映像。您可以在RunOnce registry key 中注册“启动任务”。并使用此设置对操作系统进行 sysprep。

    这样你基本上会有一个启动任务,它会在你的机器第一次启动时执行,而不会在随后的 VM 重新启动时执行。

    将参数带入 VM 的代码对于 Web/Worker 角色来说并不容易。对于任何你想要的东西,你必须直接查询 Azure 管理 API。您可以从 Azure VM 上运行的代码中获得的唯一属性基本上是正常的操作系统属性 - 即主机名、主机 IP 地址。您甚至不知道您的云服务名称,也不知道您的虚拟 IP 地址(这可以通过 whatismyip.net 或类似服务发现)。所以我的方法是将参数放入 Azure 表存储并使用机器名称作为 rowKey。因此,我可以根据 VM 名称存储任何特定于 VM 的值。我的“启动”任务将查询表存储,提供我的主机名作为 rowKey(以及分区键的一些常见模式),因此它可以获得所有必需的设置。

    【讨论】:

    • 太好了,非常感谢您的回答!关于参数 - 我可以使用 CreateDeployment 方法的 CustomData 参数吗? (msdn.microsoft.com/en-us/library/windowsazure/jj157194.aspx) 据说创建了一个 %SYSTEMDRIVE%\AzureData\CustomData.bin 我可能可以从代码中读取?还是这发生得太晚了(在我的启动任务执行之后)?
    • hm,实际上你在 RunOnce 中执行的代码可能能够读取它,但我从未测试过这种场景。
    【解决方案3】:

    使用IaaS Management Studio,您可以设置一个启动脚本,该脚本将在您的 VM 启动时运行。 总之,它会在检测到 powershell 端口打开时激活远程 powershell 并远程运行您的脚本。

    我是这个工具的开发者,但我不明白你所说的“参数化”是什么意思,换句话说,你希望你的脚本能够访问虚拟机信息?

    【讨论】:

    • 是的,我的意思是我希望它能够从 VM 上的文件(或外部源 - 例如存储帐户或 GitHub)中读取参数。这个工具看起来不错,但我需要它通过代码来实现(以便它可以是自动的)。
    • 遗憾的是,Azure 中没有内置功能可以做到这一点。 :(