在Azure 虚拟机规模集(VMSS) 的持续发布 (CD)
能屈能伸,是将应用部署在云上的一大优势,最大限度的将负载的实际需求和提供服务的资源匹配起来,减少浪费。在Azure上,弹性伸缩最好的选择当然是PaaS或AKS, 但如果应用还没容器化和不适用于PaaS的时候,可以使用虚拟规模集VMSS(VM ScaleSet), 定义好虚机的镜像,或初始化脚本,就可以建VMSS并设定好灵活的伸缩策略。具体可以参考: https://azure.microsoft.com/zh-cn/services/virtual-machine-scale-sets/ 。
那么问题来了,在VMSS部署好的应用需要更新,怎么做?按官方的建议方法有两种:
- 更新虚机的镜像 - 相对比较重,个人一般不建议轻易用这种方式,除非有重大更新。
- 使用DSC ( Desired State Configuration) - 就是设定想要虚机变成的最终状态,可以使用脚本,应用小版本更新建议用这种方法,可以结合CI/CD的平台一起使用,如Azure Devops.
DSC是Azure的通用机制,可以用Azure CLI或Runbook等将DSC应用到单台或多台VM,或者VMSS等。但应用到VMSS具体应该如何做,效果如何?这里就详细探讨一下。
一、环境准备
测试的应用在 https://github.com/radezheng/nodetest , 已经打好了tag, v1 和 v2 。
做好虚机镜像,如安装好必要的环境依赖,参考: https://docs.microsoft.com/zh-cn/azure/virtual-machines/linux/capture-image
建好资源组(vmsstest),nsg, vnet后,建VMSS,为了省成本,我用了Spot VM, 但因Spot VM没SLA, 生产环境不建议。命令如下:
az vmss create \ --resource-group vmsstest \ --name myScaleSet \ --image /subscriptions/xxxx/resourceGroups/vmsstest/providers/Microsoft.Compute/images/vmsstest-image \ --upgrade-policy-mode automatic \ --single-placement-group false \ --admin-username myuser \ --admin-password xxxx \ --vm-sku Standard_D2s_v3 \ --lb-sku Standard \ --nsg nfs-nsg \ --vnet-name vnet-southeastasia \ --priority Spot \ --max-price -1
待VMSS建完,确认Load Banlancer的健康检查,负载均衡规则满足应用的需要, NSG的应用端口,ssh端口开放。 然后确认应用运行正常,如:
测试应用会在网页的 Title 和 Body 里显示 版本 和 VM 实例名字,就可以确认是哪台VM实例的哪个版本的应用在响应。
二、设定升级策略
VMSS默认的升级策略为自动,即所有实例一起升级,如果升级不顺利,有可能造成应用中断。所以要做CD,建议将升级策略设定为滚动升级,可以按比例和顺序来升级实例。在设定前需要先加上“运行状况" 检测,可以自定义,或者重用LB的健康检查:
再设定滚动升级策略, 为测试方便,我将比例设到50%, 建议用20%:
为测试方便,将实例数手动设定为4:
三、开始升级
确认VMSS现在没有在进行滚动更新。有时对设置修改也会触发。
az vmss rolling-upgrade get-latest -g vmsstest -n myScaleSet -o json
准备DSC脚本,并放到可以通过url访问的存储上,如下,该DSC接受版本号作为参数,放在Azure blob上,
https://rade.blob.core.windows.net/dsc/nodetest-dsc.sh
pkill node cd /root rm -fR nodetest git clone --branch $1 https://github.com/radezheng/nodetest cd nodetest npm install export HOSTNAME=`hostname` nohup npm start &
通过客户端模拟监测脚本自动隔一步执行一次curl来访问VMSS,确认所有实例上应用的版本为v1。
调用DSC 发布v2 代码到VMSS:
az vmss extension set \ --publisher Microsoft.Azure.Extensions \ --name CustomScript \ --version 2.0 \ --settings '{"fileUris": ["https://rade.blob.core.windows.net/dsc/nodetest-dsc.sh"], "commandToExecute":"./nodetest-dsc.sh v2 "}'\ --vmss-name myScaleSet \ --resource-group vmsstest --no-wait
因为DSC是应用到整个VMSS上的,所以现有的和之后新扩的实例都会自动执行该DSC。
更新过程中在Azure Portal可以看到各实例的更新情况,确定是滚动的, 如下图,按策略,先更新50%的实例,也就是2台:
另外,也可以通过命令来查看VMSS更新情况:
az vmss rolling-upgrade get-latest -g vmsstest -n myScaleSet -o json
#在出错的时候,可以取消即暂停更新:
az vmss rolling-upgrade cancel -g vmsstest -n myScaleSet -o json
观察客户端模拟监测脚本,确认版本更新过程:
可以看到后面全部4台都转成v2, 中间会偶尔会出现短暂的中断,因为该DSC脚本使用了kill, 如果能加上grace的停止应用会好一点,否则不建议在访问的高峰来升级,客户端设好重试机制。
四、总结
至此,VMSS应用的更新完成,关键是设定好更新策略,去执行DSC,该DSC可以重复执行,来进行版本的设换。所以只需把应用DSC的命令放到CD的平台,就可以实现持续发布了。
最后,如果是整个虚机镜像的更新,可以跑如下命令:
az vmss update \ --resource-group vmsstest \ --name myScaleSet --no-wait \ --set virtualMachineProfile.storageProfile.imageReference.id=/subscriptions/xxxx/resourceGroups/vmsstest/providers/Microsoft.Compute/images/vmsstest-image-v2