首页 > 代码库 > Azure Stack技术深入浅出系列4: Azure Stack自定义虚拟机镜像和Gallery Item

Azure Stack技术深入浅出系列4: Azure Stack自定义虚拟机镜像和Gallery Item

Azure Stack环境中服务的提供者或运营者从微软变成了Azure Stack集成环境的运营者,通过Azure Stack的MarketPlace,我们可以根据用户的特定需求,提供一些定制化的应用,获得与公有云不一样的用户体验。本文将主要介绍如何在Azure Stack的MarketPlace中如何添加一个自定义的虚拟机进行并定制满足需求的Gallery Item,同时通过自服务的模式提供给业务的消费者。


这一篇,我们将探讨以下几个问题:

  • 如何制作自定义镜像

  • 从自定义镜像创建虚拟机的几种方式

  • 如何创建自定义的Gallery Item

1、制作自定义镜像

Azure Stack的镜像分为 generalized 和specialized两种不同的形式。

Generalized镜像中已经删除了所有个人账户信息及一些其它数据,可以作为模板来创建一个或者多个虚拟机。微软对Windows和Linux镜像都提供了相应的工具,Windows下可以采用Sysgrep,Linux下可以安装Azure Linux Agent,执行sudo waagent –deprovision来实现。

Specialized镜像中保留了原始虚拟机中的用户账户、应用程序和其它状态数据,可以作为模板创建一台虚拟机。Specialized镜像可以看作是原始虚拟机在某个时间的snapshot。

镜像既可以从Azure Stack或者Azure上运行的虚拟机来制作,比如捕获或者克隆虚拟机,也可以将在本地基于Hyper-V Manager启动的虚拟机导出作为镜像。几种不同的自定义镜像的详细制作过程请参考下面链接:

  • 捕获Azure Stack上运行的虚拟机

  • 创建在Azure Stack或者Azure上运行的虚拟机的副本

  • 从本地VM创建虚拟机镜像

2、从自定义镜像创建虚拟机

在获得虚拟机镜像之后,如何在Azure Stack中根据镜像创建虚拟机?

这部分介绍如何将本地VHD镜像上传到Azure Stack中,并且创建虚拟机。Azure Stack中需要通过Portal、PowerShell,ARM Template等方式来进行相应的操作,这些操作包括2步:

  • 第一步:上传本地VHD镜像到Azure Stack上(见 2.1)

  • 第二步:创建虚拟机(见 2.2)

2.1通过Portal新建存储账户并上传本地镜像

  • 登陆Azure Stack

    技术分享

  • 新建存储账户

    技术分享

  • 新建Blob Container,名字为vhds

    技术分享

  • 将本地VHD文件以PageBlob的类型上传到新建的Container中

    技术分享

2.2通过ARM Template从镜像创建新的虚拟机

镜像上传后,就可以开始创建虚拟机了。从VHD创建虚拟机有两种模式:AttachFrom-Image

Attach模式下,VHD文件是直接附加到新建的虚拟机上。因此采用Attach模式,一个VHD文件只能创建一台虚拟机。而From-Image模式,首先会将VHD文件复制一份到指定的Blob Container中,然后将VHD的副本附加到虚拟机上,因此可以从一个generalized VHD创建多台虚拟机

采用ARM Template来创建虚拟机, ARM Template的使用方式及创建虚拟机的完整Template可以在AzureStack-QuickStart-Templates上获得,这里仅提供两种模式下差异部分来进行对比分析:

-> Attach模式

"storageProfile": {        "osDisk": {          "name": "[concat(parameters(‘vmName‘))]",          "osType": "[parameters(‘osType‘)]",          "caching": "ReadWrite",          "vhd": {            "uri": "[parameters(‘osDiskVhdUri‘)]"
          },          "createOption": "Attach"
        }
      },

Attach 模式下只需要提供VHD的URI,createOption采用“Attach”
这里parameters(‘osDiskVhdUri‘)为前面通过Portal上传的VHD文件的URL:

https://liugestore.blob.local.azurestack.external/vhds/CentOS7-AzureStack-WithAgent.vhd

下图为Attach模式流程:

技术分享

-> From-Image模式

        "storageProfile": {          "osDisk": {            "name": "[concat(variables(‘vmName‘),‘-osDisk‘)]",            "osType": "[parameters(‘osType‘)]",            "caching": "ReadWrite",            "image":{              "uri": "[variables(‘userImageUri‘)]"
            },            "vhd": {              "uri": "[variables(‘osDiskVhdUri‘)]"
            },            "createOption": "FromImage"

          }
        },

From-Image模式下需要提供Image的URI和VHD的URI, createOption采用 FromImage
variables(‘userImageUri‘)为前面用Portal上传的VHD文件的URL

https://liugestore.blob.local.azurestack.external/vhds/CentOS7-AzureStack-WithAgent.vhd

variables(‘osDiskVhdUri‘)

https://liugestore.blob.local.azurestack.external/vhds/testVM.vhd

是用户指定的新的虚拟机绑定的VHD文件,实际上是CentOS7-AzureStack-WithAgent.vhd的副本。

注:这里为了方便,将 CentOS7-AzureStack-WithAgent.vhd和 testVM.vhd放在了同一个Blob Container中。实际上,副本VHD可以放在其他的存储账户中,并且名字也可以根据需要在设置。

From-Image模式流程:

技术分享

3、Azure Stack 镜像库

上一节中介绍了如何上传镜像及通过ARM Template从镜像创建虚拟机。VHD镜像上传到我们自己新建的存储账号中。创建虚拟机的时候直接通过Blob的URL来定位镜像文件。

那么除了用户自己维护镜像的存储,Azure Stack有没有提供一个统一的镜像库来方便的存储镜像呢?除了用URL来标识和定位镜像,有没有其它方式来唯一指定镜像呢?

答案是有。本节讨论Azure Stack的镜像库,主要介绍下面几个问题:

  • 自定义镜像上传到镜像库(见 3.1)

  • 镜像库中镜像的标识(见 3.2)

  • 从镜像库中的镜像创建虚拟机(见 3.3)

3.1 通过Admin Portal上传自定义镜像到镜像库

Azure Stack的镜像库在Resource Provider的Compute当中,需要admin权限才能进行操作。

  • 从admin portal用admin账号登陆Azure Stack
    技术分享

admin portal地址:

https://adminportal.local.azurestack.external/
  • 点击Resource Providers–点击Compute–VM images
    技术分享

可以看到目前已经上传到镜像库中的所有镜像。

  • 点击Add,填写镜像的相应标识信息,然后点击Create
    技术分享

其中OS Disk Blob URI:就是我们上一小节中上传的VHD镜像的Blob URL,也即:

https://liugestore.blob.local.azurestack.external/vhds/CentOS7-AzureStack-WithAgent.vhd
  • 成功后,即将镜像上传到了镜像库中
    技术分享

3.2 镜像库中镜像的标识

在上传镜像的过程中,我们需要填写一些相关信息,如PUBLISHER, OFFER, SKU, VERSION, OSTYPE, OS DISK BLOB URI,那么这些信息到底有什么用呢?在点击了Create后,发生了什么过程呢?

实际上主要发生了两步:

第一步- 将OS DISK BLOB URI指定的vhd文件复制到VM Images库中

技术分享

在我们的POC测试环境中,镜像库位于
C:\ClusterStorage\Volume1\Shares\SU1_Infrastructure_1\CRP\PlatformImages中,可以看到有两个文件夹,对应着我们在镜像库中的两个镜像。
技术分享

第二步- 生成该镜像的对应的Manifest文件,用来标识该镜像。

技术分享
进入刚刚上传的镜像对应的文件夹中可以看到,除了存在着一个复制过来的VHD文件外还有一个Manifest文件。

Manifest文件的内容如下:

{"Offer":"CentOS","Sku":"7.0-withagent","Version":"1.0.0","PlatformImage":
  {    "Publisher":"Inesa",    "Offer":"CentOS",    "Sku":"7.0-withagent",    "Version":"1.0.0",    "OsDisk":{       "OsType":"Linux",       "Filename":"CentOS7-AzureStack-WithAgent.vhd",       "FullPath":"\\\\SU1FileServer\\SU1_Infrastructure_1\\CRP\\PlatformImages\\3ee92630-cf36-454a-8a4f-123a7ad7b9a5",       "Uri":"https://liugestore.blob.local.azurestack.external/temp/CentOS7-AzureStack-WithAgent.vhd"
    }

  },"Publisher":"Inesa"}

Manifest文件中包含了前面填写的PUBLISHER, OFFER, SKU, VERSION, OSTYPE信息,也包含了镜像文件在镜像库中的存储位置以及镜像是从哪里复制过来的。其中PUBLISHER, OFFER, SKU, VERSION, OSTYPE 唯一标识了当前的镜像。通过这些标识信息,就可以指定用改镜像创建虚拟机

3.3 从镜像库中的镜像创建虚拟机

有了镜像的唯一标识信息,就可以创建虚拟机,前面小节介绍了如何通过ARM Template来创建虚拟机,这里则通过PowerShell来创建。

# Define a credential object$cred = Get-Credential# Create a virtual machine configuration$vmConfig = New-AzureRmVMConfig -VMName myVM -VMSize Standard_DS2 | `
    Set-AzureRmVMOperatingSystem -Linux -ComputerName myVM -Credential $cred | `
    Set-AzureRmVMSourceImage -PublisherName Inesa -Offer CentOS `
    -Skus 7.0-withagent -Version latest | Add-AzureRmVMNetworkInterface -Id $nic.Id# create new vm    New-AzureRmVM -ResourceGroupName liuge -Location local -VM $vmConfig

在vmConfig中通过标识信息来指定用我们刚刚上传的镜像来创建新的虚拟机。

4、自定义Gallery Item

前面的几个小节介绍了从自定义镜像创建虚拟机的几个方式,无论是采用PowerShell还是ARM Template,都需要一定的编程基础,那么有没有一种方式,可以在Portal上通过点击操作来创建自定义的虚拟机呢?本节就介绍如何为自定义镜像在Portal上创建图标,也就是Gallery Item。

4.1 什么是Gallery Item

简单的理解:

在Azure中我们可以通过如下方式创建虚拟机:

技术分享

如图点击对应的图标,就可以弹出创建虚拟机的界面:
技术分享

不需要配置任何的开发环境,不需要一定的编程基础,只要点击,填写相关项,就可以快速的创建一台虚拟机。

在Azure Stack中同样可以实现!

4.2 利用Azure Stack Tools 创建Gallery Item

在Azure Stack深入浅出系列的上一篇中介绍了Azure Stack运维工具Azure Stack Tools的使用,Azure Stack Tools提供了Add-AzsVMImage方法来实现:

$ImagePath = "<Path to VHD>"Add-AzsVMImage -publisher "Inesa" -offer "CentOS" -sku "7.0-withagent" -version "1.0.0" -osType Linux`  
-osDiskLocalPath $ImagePath -tenantID $TenantId -EnvironmentName "AzureStackAdmin"

执行上面的指令后就可以实现与Azure 类似的通过Portal来创建虚拟机

技术分享

更多Azure Stack Tools的内容请参考:Azure Stack Tools

4.3 深入理解自定义Gallery Item的流程

利用Azure Stack Tools 的Add-AzsVMImage可快速的实现自定义Gallery Item。那么Add-AzsVMImage到底封装了什么操作?自定义Gallery Item需要经过哪些过程呢?
Add-AzsVMImage主要做了2个工作:

  • 将本地VHD文件上传到Azure Stack的镜像库(见 4.31)

  • 为镜像库中的镜像创建Gallery Item(见 4.32)

4.31 将本地VHD文件上传到Azure Stack的镜像库

将镜像上传到镜像库的过程前面已经介绍过了,Add-AzsVMImage所进行的操作与前面介绍的相同,流程如下:

技术分享

  • 在Azure Stack中创建新的临时资源组,存储账号,Blob Container

  • 将本地VHD文件上传到新建的Container中

  • 将临时存储账户中的VHD文件的BLob URL 作为 OS DISK BLOB URI的值,Add-AzsVMImage指令中的参数publisher, offer, sku, version, osType的值作为PUBLISHER, OFFER, SKU, VERSION, OSTYPE的值,在镜像库中添加新的镜像

  • 删除创建的临时资源组,包括其中的存储账号、Container以及临时的VHD文件

4.32 为镜像库中的镜像创建Gallery Item

为了解自定义Gallery Item的流程,这部分将介绍如何自己通过PowerShell的指令来实现。主要分为以下几步:

  • 填写相应的Json描述文件

  • 生成azkpg包

  • 生成Gallery Item

Step 1.首先创建下面的目录结构及文件:

技术分享

其中DeploymentTmeplates、Icons、strings为文件夹的名字。Icons下面存放的是图标文件,可以选择自己需要的png文件进行替换。

Step 2.编辑Manifest文件:

技术分享

Manifest文件包含了一些对图标的描述,包括名字,发布者,版本,图标样式等信息。也就是对下图中CentOS 7.2的一些描述.

技术分享

Step 3.编辑UIDefinition.json

技术分享

UIDefinition定义了在创建新的虚机时UI显示的步骤和内容,有两种类型:

  • 一种是Azure的默认类型CreateVMWizardBlade,如下图共 四步,一般都采用这种类型。

技术分享

  • 另一种是 DeployFromTemplateBlade 类型,这种需要在 DeploymentTemplates文件夹下,填写需要显示的内容,感兴趣的读者可以深入研究一下。

Step 4.编辑DeplymentTemplates\CreateUIDefinition.json

技术分享

ImageReference中可以设置下面的属性来表示采用的镜像:

技术分享

Step 5.编辑Strings\resources.resjon

里面主要是Manifest.json中用到的几个变量的详细信息

{  "summary": "Create a CentOS 7.2 VM",  "longSummary": "Create a CentOS 7.2 VM. Publisher: Inesa, Offer: CentosServer, Sku:7.0-WithAgent, Version:1.0.0",  "description": "Create a CentOS 7.2 VM. Publisher: Inesa, Offer: CentosServer, Sku:7.0-WithAgent 
}

Step 6.生成azkpg包
->使用工具AzureGalleryPackager,下载地址:http://www.aka.ms/azurestackmarketplaceitem
->解压,进入目录
->执行powershell指令:

.\AzureGalleryPackageGenerator\AzureGalleryPackager.exe -m C: \CentOS.72\Manifest.json -o C:\InesaMarketPlaceItems

->执行成功后会在InesaMarketPlaceItems文件夹下生成相应的azkpg文件Inesa.CentOS72.2.0.0.azpkg 。

Step 7.上传azkpg文件到Blob中
技术分享

Step 8.根据azkpg文件生成Gallery Item

$subscriptionid = (Get-AzureRmSubscription -SubscriptionName ‘Default Provider Subscription‘).SubscriptionId

Add-AzureRMGalleryItem -SubscriptionId $subscriptionId -GalleryItemUri "https://liugestore.blob.local.azurestack.external/templates/Inesa.CentOS72.1.0.0.azpkg" -ApiVersion "2015-04-01"

其中https://liugestore.blob.local.azurestack.external/templates/Inesa.CentOS72.1.0.0.azpkg 是上传的文件的URI

经过上面的8步,已经可以实现创建Gallery Item的功能,实际上,Add-AzsVMImage中也是根据这个过程来实现的。

4.4 利用Publishing Tool来添加 Gallery Item

在前面小节中,需要执行PowerShell指令来添加Gallery Item。随着Azure Stack GA,微软提供了一个Publishing Tool来实现可视化的添加Gallery Item。界面如下图:

技术分享

Publishing Tool的详细使用教程:

  • Add marketplace items using publishing tool

5、总结

通过本文,我们了解了如何创建自定义的虚拟机镜像,并且通过自定义镜像来创建虚拟机,为自定义镜像创建Gallery Item等。从较简单的例子入手,逐步深入,来介绍Azure Stack Tools中 Add-AzsVMImage所做的工作,希望能够对读者有一定的启发。

作者:刘建志



如果对文章内容感兴趣请联系: 
仪电(集团)有限公司Azure Stack技术支持团队( gaoc@rc.inesa.com / niuhx@rc.inesa.com)
转载请注明:转载自Azure Stack Notes博客(http://a-stack.com)



Azure Stack技术深入浅出系列4: Azure Stack自定义虚拟机镜像和Gallery Item