来自与领先专业服务提供商的 DevOps Hackfest 的经验教训





0/5 (0投票)
本文描述了此次活动的结果,以及“DevOps 双人组”如何成为该专业服务提供商 (PSP) 的新常态。
提供商
当一家领先的跨国专业服务提供商寻求改进其开发流程的方法时,他们与微软会面讨论DevOps如何提供帮助。他们共同举办了一次DevOps Hackfest,以实施DevOps实践,重点是自动化测试和发布管理。本文描述了结果以及“DevOps 双人组”如何成为该专业服务提供商(PSP)的新常态。DevOps 双人组概念汇集了两名工程师——一名来自开发团队,一名来自部署团队——他们共同负责给定应用程序的生命周期。
客户简介
该客户是全球多个行业领先的专业服务提供商。他们的IT部门管理着庞大的代码库和许多应用程序,有大有小。大部分代码库是在当前实践之前编写的,并且作者可能已经离开了公司。这被称为“遗留代码”,因为它不符合当前开发实践的标准。我们(微软)与该PSP会面,讨论DevOps如何帮助他们加速软件开发并将更多想法推向用户。当时,他们已经开始改变工作方式并实施了一些良好的DevOps实践。基于这些讨论,我们决定与他们合作攻克这些挑战。联合黑客团队于2016年4月花了三天时间研究解决方案。联合团队由来自PSP的五名贡献者以及以下微软技术布道师组成:
- 亚历山大·乔尔杰维奇
- 安东·博伊科
- 克莱门斯·肖特
- 拉斯穆斯·哈尔德
问题陈述
我们很快得出结论,需要进行价值流映射练习,以帮助PSP识别开发过程中浪费时间的地方。价值流映射是一个4到6小时的研讨会,旨在描绘参与应用程序开发和交付的团队如何工作,从功能构思到投入生产和使用。
下图显示了该PSP价值流映射练习的结果;红色注释是识别出的改进领域。通过这项练习,我们了解到该组织在测试和发布流程方面存在挑战。
测试存在以下几个挑战:
- 这是一项手动任务。
- 它有过所有权变更。
- 有时会完全跳过。
- 在编写代码时,没有通用实践或要求来实施自动化测试。
因此,PSP在将应用程序部署到生产环境之前,需要花费大量时间进行广泛的手动测试,以确保应用程序的质量。
在发布管理方面,PSP将每个应用程序部署到六个不同的预发布环境:
- 开发人员自己的PC
- 共享开发环境
- 迭代环境
- 测试环境
- 预发布环境
- 生产环境
尽管所有这些环境都通过一个全面的脚本系统自动部署,但所有部署都是手动执行的,没有中央方法知道哪些更改部署到了哪个环境。
解决方案、步骤和交付
团队分为两个轨道,一个专注于自动化测试,另一个专注于发布管理。
自动化测试
自动化测试是价值流映射练习中发现的一个核心改进点。团队概述了自动化软件的基础知识,并就将自动化测试作为软件交付的一部分实施的策略达成了一致。
测试策略
- 所有测试必须自动执行。
- 编写单元测试必须简单。
- 开发工程师将作为功能开发的一部分编写测试。
- 任务估算和计划将包括测试编写。
- 测试必须在发布准备就绪之前集成并通过。
- 每个开发任务必须包括测试编写。
因此,开发冲刺可能会交付较少的功能,但质量会更高。从长远来看,这意味着修复 bug 的时间更少。
测试类型
- 单元测试。一种测试源代码中函数的方法。
- 集成测试。类似于单元测试,但测试的是源代码中不同模块之间的集成。
- UI测试。测试应用程序图形用户界面的过程。
黑客团队专注于自动化单元测试并将其集成到现有代码库中。此过程需要时间来访问现有代码并理解其功能。只有这样才能开始编写测试。
下面是一个用Microsoft Visual Studio编写的单元测试的简单示例(为保护IP,删除了真实代码)。
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void OrderingItems_NegativeNumbers()
{
Assert.AreEqual(1, 1);
}
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(1, 1);
}
以下是开发人员工作站上实际测试执行的示例
然后,测试作为源代码的一部分提交到代码库,并发送到中央仓库。对于Hackfest,团队使用Visual Studio Team Services (VSTS) 在构建过程中运行测试。在DevOps世界中,这被称为持续集成。
云中即时持续集成
当涉及到更频繁的交付时,具备自动化测试是关键。在当今世界,存在出色的工具来支持不同类型的测试,并且团队构建系统来运行这些测试,以确保他们交付的代码质量。
但是,构建和维护应用程序测试的基础设施是一项昂贵而繁琐的任务。要进行真实的测试,需要构建一个与生产环境完全相同的测试系统,只是它永远不会服务于真实用户。它将仅用于测试新代码。
随着云的成熟,我们现在可以利用云计算的弹性,在需要时构建测试系统,并在完成后将其移除。
在该 PSP,代码质量的核心在于我们能够模拟一个接近真实世界的系统,其中包括前端服务器和基于 Microsoft SQL Server 的后端服务器。我们没有购买一套新的物理服务器,而是选择使用 Microsoft Azure 作为运行自动化测试的基础设施,在执行测试之前创建所需的环境,然后在 6 分钟后再次删除该基础设施。
团队选择了 Visual Studio Team Services 来实施一个解决方案,该解决方案可以运行整个持续集成过程,包括构建、基础设施部署和移除、自动化测试和报告,并交付一组可部署的工件。在此解决方案中,从构建服务器到数据库基础设施的一切都将托管在 Microsoft Azure 中。
持续集成过程
第一步是下载源代码和所有必要的依赖项
Visual Studio Build(又名 MSBuild)。使用 MSBuild 引擎编译代码,并将其打包成可部署单元以供后续使用。
Azure 资源组部署。构建 Azure SQL Server 和附加数据库。
PowerShell。用于将虚拟数据导入数据库进行测试。
Visual Studio Test。运行一系列长的自动单元测试和 UI 测试。
发布测试结果。生成包含测试结果和详细日志记录的报告。
Azure 资源组部署。移除 SQL Server 和所有数据,并清理之前创建的整个部署。
其余的构建任务随后清理环境并将构建工件发布到 Visual Studio Team Services(供以后部署)。
使用云托管构建系统的结果是,通过在每次测试执行时预配新的构建和测试基础设施,所有测试都在尽可能卫生的环境中运行。(这也被称为干净部署,其中没有旧代码或依赖项可以驻留在早期构建或测试中。)
在此案例中,自动化测试运行6-7分钟,而Azure中的SQL Server使用大约5分钟。
这是用于创建 Azure SQL 实例的 Azure Resource Manager 部署模板的示例
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "testingdbAdminLogin": { "type": "string", "minLength": 1 }, "testingdbAdminLoginPassword": { "type": "securestring" }, "unittestdbName": { "type": "string", "minLength": 1 }, "unittestdbCollation": { "type": "string", "minLength": 1, "defaultValue": "SQL_Latin1_General_CP1_CI_AS" }, "unittestdbEdition": { "type": "string", "defaultValue": "Basic", "allowedValues": [ "Basic", "Standard", "Premium" ] }, "unittestdbRequestedServiceObjectiveName": { "type": "string", "defaultValue": "Basic", "allowedValues": [ "Basic", "S0", "S1", "S2", "P1", "P2", "P3" ], "metadata": { "description": "Describes the performance level for Edition" } } }, "variables": { "testingdbName": "[concat('testingdb', uniqueString(resourceGroup().id))]" }, "resources": [ { "name": "[variables('testingdbName')]", "type": "Microsoft.Sql/servers", "location": "[resourceGroup().location]", "apiVersion": "2014-04-01-preview", "dependsOn": [ ], "tags": { "displayName": "testingdb" }, "properties": { "administratorLogin": "[parameters('testingdbAdminLogin')]", "administratorLoginPassword": "[parameters('testingdbAdminLoginPassword')]" }, "resources": [ { "name": "AllowAllWindowsAzureIps", "type": "firewallrules", "location": "[resourceGroup().location]", "apiVersion": "2014-04-01-preview", "dependsOn": [ "[concat('Microsoft.Sql/servers/', variables('testingdbName'))]" ], "properties": { "startIpAddress": "0.0.0.0", "endIpAddress": "0.0.0.0" } }, { "name": "[parameters('unittestdbName')]", "type": "databases", "location": "[resourceGroup().location]", "apiVersion": "2014-04-01-preview", "dependsOn": [ "[variables('testingdbName')]" ], "tags": { "displayName": "unittestdb" }, "properties": { "collation": "[parameters('unittestdbCollation')]", "edition": "[parameters('unittestdbEdition')]", "maxSizeBytes": "1073741824", "requestedServiceObjectiveName": "[parameters('unittestdbRequestedServiceObjectiveName')]" } } ] } ], "outputs": { } }
发布管理
该PSP拥有一个完全自动化的部署模型,但正如价值流映射练习所示,每次交付仍然需要手动处理,并且与正在部署的功能及其在交付过程中的状态没有任何关联。黑客团队决定展示Visual Studio Team Services(VSTS)中的发布管理功能,该功能将简单地将所有内容连接起来,并更好地展示交付状态。
通过实施发布管理解决方案,团队能够利用现有的基于PowerShell的部署模型自动化部署任务的执行。这是通过将部署脚本添加到应用程序源代码中,并让VSTS使用特定于环境的参数执行脚本,并对部署周期中的每个环境重复该任务,并使用一组不同的脚本参数来完成的。
这将为PSP提供一个自动化部署模型,无需手动运行任何脚本。它具有内置的审批流程,规定了何时可以将给定版本部署到下一个环境,并且每次审批都记录下来以供将来参考。
该解决方案还通过链接来自 Visual Studio 工作管理系统的工作项,清晰地显示了当前部署到每个环境中的版本(和功能)。这使产品负责人能够了解功能何时交付到生产环境。下面是应用程序发布的示例,以及给定版本在部署管道中的进度视图。
通过这个模型,PSP正在利用基于云的构建、测试和发布管理工具,并部署到本地托管环境。这意味着所有客户数据都托管在他们自己的基础设施上,而无需接触云端。我们通过利用 Visual Studio Team Services 中的构建代理系统,并将代理部署到本地服务器来实现这一点,该服务器将作为部署服务器并将新版本推送到环境中。
如果他们以后选择将应用程序部署到云托管环境,他们可以通过将构建代理更改为可以部署到云提供商的代理来轻松实现。
结论
该PSP拥有成熟的开发周期和一些健康的实践。通过引入DevOps,他们学习了新的实践,并将现有流程更好地整合在一起。在考虑DevOps之前,部署和开发团队在交互方面遇到了困难;现在团队已经开始更好地协同工作。
该组织的经理们迅速支持了DevOps倡议,他们实施的第一件事就是DevOps双人组计划,该计划将开发团队的一名工程师与部署团队的一名工程师配对。DevOps双人组是应用程序的主要联系人,负责管理从规划新功能到处理事件的一切。每个应用程序都有一个DevOps双人组,他们被授权做出决策并将任务委派给其他工程师。
自动化测试增强了对质量的信心,并将使团队能够以相同的工程师数量推动更多更改。目标是到2016年底,对于任何新功能或应用程序,测试编写将与编码同步进行,并且自动化测试将成为持续交付的完全集成部分。
更新现有代码库需要时间。然而,他们明白,为了使其符合标准,解决遗留代码库并将其更新到当前的最佳实践是必要的。自动化测试将大大缩短新功能的交付时间,最终用户(客户)将获得更高的质量。
发布管理解决方案将帮助组织处理重复性任务。他们有一句格言:“凡可自动化,皆须自动化”,而发布管理正是缺失的环节。实施后,它将提高透明度,让更多人了解正在发生什么以及什么在哪里运行。
它还将更好地分离职责,提高安全性,因为需要访问运行应用程序的环境的人数会减少。
新的发布管理工作流是自文档化的。在实施此解决方案之前,更改请求是在票务系统中创建的,关于实际发布的信息通过电子邮件在开发和运维之间传输。通过发布管理,工作项(更改)与实际发布以及处理给定更改的人员相关联。
Hackfest 的成果将作为案例展示,以启发其他团队如何进行部署。