康威,资深工程师,SDN 和大规模数据中心网络专家

在Azure中,原生的IaaS服务在虚拟机计算服务模块主要提供两种服务,一种是原生的操作系统虚拟计算实例(如CentOS/Ubuntu Linux,Windows),一种是Azure与Ecosystem合作在应用市场上发布的Day1装载好相关应用的虚拟计算实例(如Wordpress)。

对于大部分用户在批量创建系统时,通常会有定制化虚拟实例的需求,通常客户会在虚拟机算实例的操作系统上进行自定义的环境参数定义以及相关应用的安装配置部署。在公有云中一个经典的应用场景就是弹性扩展,在应对突发访问虚拟计算实例自动弹性水平扩展,整个自动扩展部署达成计算实例上线后环境参数以及应用都部署完毕ready to go是最理想的,这个过程如果再去涉及手工流程是无法满足要求的。

那么有什么办法可以达成这个目标呢?总结起来在Azure上我们可以通过两种方式来做,一种是基于Azure原生的计算实例的部署开放接口在创建实例后自动通过脚本配置环境参数及应用;一种是自定义计算实例镜像,在虚拟化中所有虚拟计算实例其实都是通过镜像模板来创建的,我们也可以来自己定义模板把预配参数及应用集成到自定义镜像模板中,后续我们通过该模板创建实例时候就可以获得一个Ready to Go的计算实例。接下来将为大家介绍如何简单快速的创建自定义计算镜像模板。

目前在Azure Portal上我们还不支持通过GUI的方式来创建自定义镜像模板,需要通过Azure CLI方式来进行相关操作整个易用度上不是特别好。今天给大家介绍一款开源小工具Packer来帮助大家简单快捷的创建自定义镜像模板。通常我们在Azure做自定义镜像模板的方法可分为以下几个步骤:

  1. 通过平台计算标准镜像创建计算实例;
  2. 登陆实例配置预期环境参数并安装应用;
  3. 将计算实例通用化摘除个性化信息;
  4. 关闭虚拟机并解除分配将磁盘转换为镜像。

整个过程涉及大量手工操作,Packer是一款开源的镜像自动化创建工具,其支持各大主流虚拟化平台及公有云平台的镜像创建(如Azure,AWS都在支持列表中),可以帮助多云客户做到跨平台的镜像创建管理。Packer通过Json描述文件来定义镜像创建的信息(如指定标准镜像模板,指定自定义脚本等)。通过Packer可以帮助大家简单快捷的创建自定义模板,将上述手工干预的创建过程通过自动化方式完成。下面通过一个Packer的示例给大家演示一下如何来自动完成Azure自定义镜像的创建,示例中目标创建一个预配Apache环境的镜像模板。操作如下:

  1. 安装Packer:

参阅:https://www.packer.io/docs/install/index.html,Windows及Linux均有支持

  1. 创建Packer Json模板创建描述文件,其主要包含三部分variable,Builder,provisoner,其中varible部分定义json模板变量(可在模板中直接调用,参数值定义为默认值,可通过命令行将变量传递),builder部分定义镜像模板基础信息(如描述云平台类型,平台访问基础参数等),provisioners部分定义自定义配置及部署信息(如定义预装应用,预配操作系统环境变量等):

{
 “variables”: {
},
 “builders”: [{

}],

 “provisioners”: [{

}]

}

=============================================================================================================

示例:

{
“variables”: {
“client_id”: “”, #在“”填入您的环境信息
“client_secret”: “”, #在“”填入您的环境信息
“resource_group”: “”, #在“”填入您的环境信息
“storage_account”: “”, #在“”填入您的环境信息
“subscription_id”: “” #在“”填入您的环境信息
},
“builders”: [{
“type”: “azure-arm”,  #指定在Azure上创建自定义镜像
“cloud_environment_name”:”China”, #指定Azure China

“client_id”: “{{user `client_id`}}”, #云平台访问client_id
“client_secret”: “{{user `client_secret`}}”, #云平台访问密钥
“resource_group_name”: “{{user `resource_group`}}”, #自定义镜像存储资源组名称
“storage_account”: “{{user `storage_account`}}”, #自定义镜像存储账号
“subscription_id”: “{{user `subscription_id`}}”,  #云平台账subscription_id

“temp_compute_name”:”packer”,  #镜像创建临时虚拟机名称,创建过程其实是在Azure上通过标准镜像创建一个虚拟机然后在上面做自定义后转换成自定义模板
“temp_resource_group_name”:”packer”, #镜像创建临时资源组,在创建镜像时在Azure上创建的资源都会放在该资源组中
“capture_container_name”: “images”, #镜像抓取后的存储Container名称
“capture_name_prefix”: “packer”, #抓取镜像存储命名前缀

“os_type”: “Linux”, #标准镜像操作系统类型
“image_publisher”: “Canonical”, #标准镜像发布商
“image_offer”: “UbuntuServer”, #标准镜像操作系统
“image_sku”: “14.04.4-LTS”, #标准镜像操作系统版本信息
“location”: “China North”, #指定资源创建所在Azure Region
“vm_size”: “Standard_A2” #指定资源创建的虚拟机规格
}],
“provisioners”: [

 

#定义自定义定制化脚本,安装ansible,然后通过ansible部署apache;

{
“execute_command”: “chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh ‘{{ .Path }}'”,
“inline”: [
“apt-get install software-properties-common -y”,
“apt-add-repository ppa:ansible/ansible”,
“apt-get update”,
“apt-get install ansible -y”,
“apt-get install git -y”,
“echo ‘127.0.0.1 ansible_connection=local’ >> /etc/ansible/hosts”,
“ansible-pull -U git://github.com/nonokangwei/ansible-playbooks.git -d /root/playbooks apache.yml”

],
“inline_shebang”: “/bin/sh -x”,
“type”: “shell”
},

#卸载azure waagent,将镜像通用化

{
“execute_command”: “chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh ‘{{ .Path }}'”,
“inline”: [
“/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync”
],
“inline_shebang”: “/bin/sh -x”,
“type”: “shell”
}
]

}

  1. 执行模板创建, 在创建过程中可以在stdout中看到整个过程的日志,如果在linux下可到/tmp目录下查看:

/#packer build xxx.json

过程在tmp目录下会产生两个文件

-rw——- 1 root root 55089 6月 15 15:30 packer-log124381723
-rw——- 1 root root 324 6月 15 15:30 packer-shell930494707

其中log文件为整个创建过程的日志,shell文件是创建过程中packer自动创建的定制化脚本,当在Azure中基础虚拟机创建完毕后会ssh到该机器上执行脚本完成定制化要求。

执行完毕后,会看到屏幕上有类似输出

==> Builds finished. The artifacts of successful builds are:
–> azure-arm: Azure.ResourceManagement.VMImage:

StorageAccountLocation: chinanorth
OSDiskUri: https://tspkw.blob.core.chinacloudapi.cn/system/Microsoft.Compute/Images/images/packer-osDisk.f5cff93a-7d1c-433a-bb8e-097513a66385.vhd
OSDiskUriReadOnlySas: https://tspkw.blob.core.chinacloudapi.cn/system/Microsoft.Compute/Images/images/packer-osDisk.f5cff93a-7d1c-433a-bb8e-097513a66385.vhd?se=2017-07-15T07:41:48Z&sig=5QAzzrOQo+G0WjVPNz7B8E4Y7QJ/cPC0aMxbH33z/as=&sp=r&sr=b&sv=2015-02-21
TemplateUri: https://tspkw.blob.core.chinacloudapi.cn/system/Microsoft.Compute/Images/images/packer-vmTemplate.f5cff93a-7d1c-433a-bb8e-097513a66385.json
TemplateUriReadOnlySas: https://tspkw.blob.core.chinacloudapi.cn/system/Microsoft.Compute/Images/images/packer-vmTemplate.f5cff93a-7d1c-433a-bb8e-097513a66385.json?se=2017-07-15T07:41:48Z&sig=zmaM7840b+ylVYhzz6qcFDtSEVNPJDN5f2fLvkY2to0=&sp=r&sr=b&sv=2015-02-21

创建完成后给出了镜像文件的azure blob的存储路径,同时还自动生成了一个azure resource template部署json文件,可以帮助快速通过自定义镜像创建虚拟机。

最后给大家补充一下资源,帮助大家快速上路:

  1. packer Azure环境配置,比如如何准备client_id, 密钥等,可以访问如下地址:https://www.packer.io/docs/builders/azure-setup.html, 很重要呦硬要看,不然跑不通的。
  2. packer provisioner,除去脚本模块外,packer中还内置了很多模块,可以做轻松写意的进行自定义:https://www.packer.io/docs/provisioners/index.html
  3. packer template格式白皮书:https://www.packer.io/docs/templates/index.html