DevOps-训练营-全-

DevOps 训练营(全)

原文:annas-archive.org/md5/70950072db1fd27b3fe141e8f2d7681d

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

DevOps 不是工具、技术、过程或框架;DevOps 是一种文化。文化是特定于组织的,它随着人、过程和工具的结合而演变,推动持续改进和创新。

一直重复做同样事情的代价远远高于改变的代价。改变对组织文化没有威胁,颠覆性的创新只会改善文化。改进就是朝着正确方向的变化,而完美就是通过从错误或经验中学习,常常朝着正确方向变化。而为了娱乐一下……“改变是不可避免的——如今甚至是从自动售货机开始的。”

DevOps 不是到达一个目的地后享受它的美丽并结束旅行。它是一个永无止境的持续改进过程,我们在其中创新事物并计划通过享受旅程或过程达到相同的目标。每次改进和创新时,这个过程可能会有所不同,但我们的目标不变!目标是通过最有效的资源利用,以最具成本效益的方式,在最快的时间内进入市场,并实现最高的客户满意度。

本书不仅强调技术,还强调 DevOps 文化应包含的不同实践。DevOps 仍处于初期阶段。决定不做什么在组织进行改进和创新时非常重要。当我们发现某项工作是重复性的,就应该决定不去做手工操作。

在本书中,我们将涵盖 DevOps 的所有关键实践,如持续集成、使用容器和云计算进行资源配置——IaaS(Amazon EC2 和 Microsoft Azure 虚拟机),以及 PaaS(Azure 应用服务或 Azure Web 应用和 Amazon Elastic Beanstalk)、持续交付、持续测试和持续部署;如何自动化构建集成并在云环境中配置资源;将 Web 应用部署到 Amazon Elastic Beanstalk、Microsoft Azure Web 应用/应用服务环境;在 AWS 和 Microsoft Azure 公有云中的应用监控;以及在 VSTS 和 Apache JMeter 中的负载测试。

主要目标是管理应用生命周期。通过自动化重复的手动过程,我们将应用生命周期的管理标准化,避免错误。同时,我们通过在 Jenkins 和 VSTS 中提供基于批准的应用部署到不同环境来为应用生命周期管理提供治理,无论是使用插件还是开箱即用的功能。

对于持续集成和持续发布(持续交付和持续部署),我们使用了 Jenkins 和 Visual Studio Team Services(VSTS)。端到端自动化和基于批准的工作流编排由 Jenkins 和 VSTS 管理。

进步不可能在没有思维方式变化的情况下实现,而要改变任何事物,我们需要先进行可视化。在本书中,我们将尝试聚焦于 DevOps 文化之旅,使用人(开发团队、QA 团队、运维团队、云团队、构建工程师、基础设施团队等)、流程(持续集成、自动化资源配置、持续交付、持续测试、持续部署、持续监控、持续改进和持续创新)和工具(开源工具和 Microsoft 技术栈)。

使用开源和 Microsoft 技术栈展示流程或实践的主要原因是培养一种意识:这不仅仅是工具的问题;而是思维方式的问题!我们可以使用任何自动化工具执行几乎相同的操作。

本书内容概述

第一章,DevOps 概念与评估框架,包含了如何从 10,000 英尺的高度快速了解 DevOps 以及如何准备改变文化的细节。它为构建 DevOps 概念的基础提供了基础,通过讨论我们的目标以及如何获得组织管理层的支持。

第二章,持续集成,解释了如何安装 Jenkins 持续集成服务器并执行与编译、单元测试执行、代码分析和创建包文件相关的各种任务。本章还介绍了使用 Microsoft 技术栈的持续集成。这里的目标是尽可能多地了解持续集成,因为它是自动化的基础。

第三章,容器,解释了如何使用容器作为开发或 QA 环境来提高资源利用率。内容包括如何创建一个 Tomcat 容器,以便将应用程序部署到其中。

第四章,云计算与配置管理,重点介绍如何在云中创建和配置应用程序部署环境。它将涵盖使用基础设施即服务(IaaS)和配置管理工具 Chef 来创建平台,以便我们后续在书中使用自动化来部署应用程序。

第五章,持续交付,解释了在平台准备好时,如何以不同的方式部署一个 Web 应用程序。这里将涉及 AWS 和 Microsoft Azure IaaS 等平台,以及 AWS Elastic Beanstalk 和 Microsoft Azure App Services 等 PaaS 服务。我们还将涵盖基于脚本的部署和 Jenkins 插件基础的部署。

第六章,自动化测试(功能性测试和负载测试),解释了部署应用到非生产环境后可以执行的各种测试类型。它讲解了如何利用自动化测试技术提升应用质量,包括使用开源工具进行功能性测试和负载测试。

第七章,编排 —— 端到端自动化,包含了使用编排自动化应用生命周期管理的多种方式。构建流水线用于编排持续集成、持续交付和持续测试。构建和发布定义配置成流水线,从而实现了端到端的自动化,并且采用基于批准机制的方式。

第八章,安全与监控,讨论了基于角色的安全性,只有特定的利益相关者才能管理配置和构建。我们将探讨各种工具,以自动化应用生命周期管理、监控,并在成功与失败的基础上进行通知,以便利益相关者可以采取必要的措施进行修复。

本书所需的工具

本书假设你至少熟悉 Java 编程语言。如果你想从本书中获得更深入的见解,掌握核心 Java 和 JEE 知识是必不可少的。对于 Web 应用程序的部署,了解如何在 Tomcat 等应用服务器中部署应用将帮助你快速理解流程。然而,我们也已经快速提供了相关概述。由于应用开发生命周期通常涉及许多工具,了解代码仓库、IDE 工具(如 Eclipse)以及构建工具(如 Ant 和 Maven)等知识是必需的。

掌握代码分析工具将使你在配置和集成过程中更为轻松;然而,进行本书中的练习并非必须依赖这些工具。大多数配置步骤都已清晰地列出,逐步指导,并通过截图提供了清晰的可视化。

本书将带领你完成熟悉 Jenkins、VSTS、Microsoft Azure Web Apps 和 AWS Elastic Beanstalk 所需的步骤。对于 Microsoft Azure,你可以使用一个月的免费试用期。VSTS 也提供试用账户,且有一些限制。AWS 也有一年的试用期,但有具体的限制条件。

本书适合谁阅读

本书面向 IT 开发人员、运维人员以及管理员,适合那些希望快速学习并在组织中实施 DevOps 文化的人。本书特别适合开发人员、技术负责人、测试人员和运维专业人员,他们是目标读者,想要快速启动容器、Chef 配置管理工具、Microsoft Azure PaaS,以及诸如应用服务和 SQL 数据库等提供托管应用程序的平台。读者通常意识到开发和运维团队面临的问题,因为他们是应用生命周期管理过程中利益相关者。启动 Jenkins 自动化服务器、Microsoft Azure PaaS 和 VSTS 的目的是为了理解它们在持续集成、自动化测试用例执行和持续交付中的重要性,从而实现有效的应用生命周期管理。

了解一些持续集成、云计算、持续交付和持续部署的基础知识是很有帮助的。无论你是新手,还是已经熟悉 Jenkins 等持续集成工具的经验者,本书都会涉及到基于 Java Spring 的应用程序的持续集成、云计算、持续交付和持续部署。主要目标是实现端到端的自动化,并在此书的基础上实施可扩展的开源和 Microsoft 技术栈。

约定

本书中包含多种文本样式,用于区分不同类型的信息。以下是这些样式的一些示例以及它们的含义解释。

文本中的代码字、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 用户名显示如下:“将下载的WebStorm-10*.dmg磁盘镜像文件作为另一个磁盘挂载到系统中。”

一段代码块如下所示:

html, body, #map {

height: 100%;

margin: 0;

padding: 0

}

任何命令行输入或输出如下所示:

$ mkdir css****$ cd css

新术语重要词汇 用粗体显示。你在屏幕上看到的词语,例如在菜单或对话框中,文本中会像这样显示:“本书中的快捷键基于Mac OS X 10.5+方案。”

警告或重要说明以这样的框显示。

提示和技巧以这种方式显示。

对于本书,我们列出了 Mac OS X 平台的快捷键,如果你使用的是 Windows 版本,可以在 WebStorm 帮助页面找到相关的快捷键 www.jetbrains.com/webstorm/help/keyboard-shortcuts-by-category.html

读者反馈

我们始终欢迎读者的反馈。请告诉我们你对本书的看法——你喜欢什么,或者不喜欢什么。读者的反馈对我们来说非常重要,因为它帮助我们开发出你真正能从中受益的书籍。

若要向我们提供一般反馈,只需发送电子邮件至feedback@packtpub.com,并在邮件主题中注明书名。

如果您在某个领域有专业知识,并且有兴趣写书或为书籍贡献内容,请参阅我们的作者指南:www.packtpub.com/authors

客户支持

现在,您已经是一本 Packt 书籍的自豪拥有者,我们为您提供了许多工具,帮助您充分利用您的购买。

下载示例代码

您可以从您的账户中下载本书的示例代码文件,网址为www.packtpub.com。如果您是在其他地方购买的本书,您可以访问www.packtpub.com/support并注册,以便文件直接通过电子邮件发送给您。

您可以按照以下步骤下载代码文件:

  1. 使用您的电子邮件地址和密码登录或注册我们的网站。

  2. 将鼠标指针悬停在顶部的“支持”标签上。

  3. 点击“代码下载与勘误”。

  4. 在搜索框中输入书名。

  5. 选择您要下载代码文件的书籍。

  6. 从下拉菜单中选择您购买本书的地点。

  7. 点击“代码下载”。

下载文件后,请确保使用最新版本的以下工具解压或提取文件夹:

  • Windows 用的 WinRAR / 7-Zip

  • Mac 用的 Zipeg / iZip / UnRarX

  • Linux 下的 7-Zip / PeaZip

本书的代码包也托管在 GitHub 上,网址为github.com/PacktPublishing/DevOps-Bootcamp。我们还在github.com/PacktPublishing/提供了来自我们丰富的书籍和视频目录中的其他代码包。快来看看吧!

下载本书的彩色图像

我们还为您提供了一个包含本书中使用的截图/图表的彩色图像的 PDF 文件。彩色图像将帮助您更好地理解输出中的变化。您可以从www.packtpub.com/sites/default/files/downloads/DevOpsBootcamp_ColorImages.pdf下载该文件。

勘误

尽管我们已经尽力确保内容的准确性,但错误有时会发生。如果您在我们的书籍中发现错误——可能是文本或代码的错误——我们将非常感激您能向我们报告。通过这样做,您可以帮助其他读者避免困扰,并帮助我们改进后续版本的书籍。如果您发现任何勘误,请访问www.packtpub.com/submit-errata报告,选择您的书籍,点击勘误提交表单链接,填写勘误的详细信息。一旦您的勘误经过验证,您的提交将被接受,勘误将上传到我们的网站或添加到该书籍的勘误列表中。

要查看以前提交的勘误表,请访问 www.packtpub.com/books/content/support 并在搜索框中输入书名。所需信息将在“勘误表”部分显示。

盗版

互联网上的版权材料盗版问题是一个持续存在的问题,影响着所有媒体。在 Packt,我们非常重视保护我们的版权和许可证。如果您在互联网上发现任何形式的非法复制作品,请立即提供位置地址或网站名称,以便我们采取相应措施。

请通过 copyright@packtpub.com 与我们联系,并提供涉嫌盗版材料的链接。

感谢您帮助保护我们的作者和我们为您提供有价值内容的能力。

问题

如果您在本书的任何部分遇到问题,可以通过 questions@packtpub.com 与我们联系,我们将尽力解决问题。

第一章:DevOps 概念与评估框架

一旦你拥有创新文化,即使是那些不是科学家或工程师的人——诗人、演员、记者——他们作为一个群体也能理解科学素养的意义。他们接受创新文化的概念,并以支持它的方式投票。他们不会反对科学,也不会反对技术。

  • 尼尔·德格拉斯·泰森

本章中,我们将讨论如何从 1 万英尺的高度快速理解 DevOps,并讨论如何准备改变文化的最佳实践。这将帮助我们通过讨论目标并获得组织管理层的支持,来构建 DevOps 概念的基础。基本上,我们将尝试介绍能够使应用生命周期管理变得简单和高效的 DevOps 实践。

很重要的一点是要理解,DevOps 不是一个框架、工具或技术,它更多的是一个组织的文化。它也是人们在组织中通过定义的流程和利用自动化工具来使日常工作更加高效、减少手动操作的一种工作方式。

为了理解 DevOps 的基本重要性,本章将涵盖以下主题:

  • DevOps 的需求

  • DevOps 文化如何发展

  • PPT 的重要性——人、流程与技术

  • 为什么 DevOps 不仅仅是关于工具

  • DevOps 评估问题

DevOps 的需求

有一句哈丽雅特·塔布曼的名言,你可以在(harriettubmanbiography.com)找到。她说:

每个伟大的梦想都始于一个梦想者。永远记住,你拥有内在的力量、耐心和激情,去追寻星辰,改变世界。

变化是生活的法则,这同样适用于组织。如果任何组织或个人只关注过去或现在的模式、文化或做法,那么他们肯定会错失未来的最佳实践。在动态变化的 IT 世界中,我们需要跟上技术的发展步伐。

我们可以联系到乔治·伯纳德·肖的这句话:

没有变化就没有进步,那些不能改变自己想法的人无法改变任何事情。

在这里,我们专注于改变我们管理应用生命周期的方式。

重要的问题是我们真的需要这种变化吗?我们真的需要经历这种变化带来的痛苦吗?

答案是肯定的。

有人可能会说,这种商业或文化中的变化不应该是强制的。

同意。

让我们通过下面的图示,了解现代世界中组织在应用生命周期管理中面临的痛点:

考虑到商业中变化的模式和竞争环境,改善应用生命周期管理已经成为当务之急。

是否有一些现代的因素可以帮助我们改善应用生命周期管理?

是的,云计算改变了游戏规则。它为许多突破性的解决方案和创新打开了大门。让我们了解云计算到底意味着什么,以及像 DevOps 和自动化这样的术语在企业公司中扮演的重要角色。

云计算概览

云计算是计算演变中的下一个逻辑步骤。从传统的数据中心和虚拟化,到混合环境、私有云、公有云和混合云服务,云计算是一种提供多租户或专用计算资源(如计算、存储和网络)的计算类型,这些资源按需交付给云消费者。它有不同的形式,包括云部署模型云服务模型。最重要的是其定价模型的运作方式,即按需付费。

云部署模型描述了云资源的部署方式:

  1. 私有云:私有云由位于防火墙后并专门为特定组织提供的云资源组成。

  2. 公有云:公有云由所有组织和个人可以使用的云资源组成。

  3. 混合云:混合云由一组特定组织共享的云资源组成,这些组织具有相似的利益或需求。

  4. 社区云:社区云由结合两种或更多部署模型的云资源组成。

云服务模型描述了云资源如何提供给各类客户,从个人和小型组织到大型企业。

它可以是纯基础设施的形式,在这种情况下,虚拟机可由云消费者或最终用户访问和控制,也就是基础设施即服务IaaS);或者是提供运行时环境的平台,安装和配置运行应用所需的所有软件已由云服务提供商管理并可用,也就是平台即服务PaaS);或者是软件即服务SaaS),在这种模式下,整个应用程序由云服务提供商提供,基础设施和平台的责任仍然由云服务提供商承担。

在过去几年里,出现了许多服务模型,但 IaaS、PaaS 和 SaaS 基于国家标准与技术研究院NIST)的定义:

云计算具有一些显著的特点,比如多租户、按需付费(类似于电力或天然气连接)、按需自服务、资源池化以更好地利用计算、存储和网络资源、快速弹性(根据需求自动扩展或缩减资源),以及计量服务用于计费。

多年来,不同云部署模型的使用也根据用例有所变化。最初,公共云用于那些被认为是非关键性的应用,而私有云则用于那些安全性要求较高的关键应用。

混合云和公共云的使用随着时间的推移不断发展,基于对云服务提供商提供的服务的经验和信任。类似地,基于用例和灵活性的不同,云服务模型的使用也有所不同。IaaS 在早期是最流行的,但随着企业能力的不断提升,PaaS 在成熟度和易用性方面逐渐追赶上来,包括自动扩展、支持多种编程语言以及支持端到端应用生命周期管理工具等功能。

DevOps 概述

DevOps 关乎组织的文化、流程和技术,通过促进开发与 IT 运维团队之间的沟通与协作,以比传统方式更有效地管理应用生命周期。我们常常基于模式工作,从类似的问题或挑战中找到可复用的解决方案。

多年来,成就与失败的实验、最佳实践、自动化脚本、配置管理工具以及方法论已成为 DevOps 文化的核心部分。

它有助于定义一套实践方法,包括设计方式、开发方式、测试方式、资源配置方式、环境管理方式、配置管理方式、应用部署方式、反馈收集方式、代码改进方式以及创新方式。

以下是通过实施 DevOps 实践可以实现的一些显著好处。

DevOps 文化被视为一种创新的方式,旨在有效地整合开发(Dev)和运维(Ops)团队,包含如持续构建集成、持续测试、云资源配置、持续交付、持续部署、持续监控、持续反馈、持续改进和持续创新等组成部分,以便根据敏捷方法论的需求加快应用交付。培养文化并非一蹴而就的过程,通常需要很长时间。然而,关于 DevOps 的定义仍然存在困惑,因此,很多时候,只有持续集成或配置管理实践才被视为 DevOps 实践的实施。这种情况类似于“大象与五个盲人”的故事,每个人摸到大象的某个部位,就认为那就是大象的全部。

然而,参与其中的并不仅仅是开发和运维团队。测试团队、业务分析师、构建工程师、自动化团队、云团队以及其他许多利益相关者都参与了这一推动现有文化演变的过程。

DevOps 文化与组织文化没有太大区别,组织文化有共同的价值观和行为规范。它需要在思维方式和流程上进行调整,以便与新技术和工具对接。

开发和运维团队面临的挑战

之所以出现这种情况,有一些挑战存在,这也是为什么 DevOps 正在不断发展,并成为所有信息技术相关讨论中的热议话题。

开发团队面临的挑战

开发人员热衷于采用新技术和方法来解决问题。然而,他们面临许多挑战,包括以下内容:

  • 竞争激烈的市场对准时交付施加了压力

  • 他们需要负责生产就绪代码管理和新特性实现

  • 发布周期通常较长,因此开发团队必须在最终进行应用部署之前做出假设。在这种情况下,修复在预发布或生产环境中部署过程中出现的问题需要更多时间

运维团队面临的挑战

运维团队在更改资源或使用任何新技术或新方法时总是非常小心,因为他们追求稳定性。然而,他们面临许多挑战,包括以下内容:

  • 资源争夺:很难应对日益增长的资源需求

  • 重新设计或调整:这是在生产环境中运行应用程序所需要的

  • 诊断与修正:他们需要在应用程序部署后对问题进行诊断和修复

IT 团队面临的挑战

IT 团队为各个团队提供资源,以支持运维工作:

  • 基础设施配置:为资源提供基础设施和运行时环境,并正确安装软件包

  • 配置管理:根据工具或技术中可用的更新来升级现有的基础设施或软件包

鉴于开发和运维团队所面临的所有挑战,我们如何改进现有流程,利用自动化工具提高流程效率,并改变人们的思维方式?让我们在下一节中讨论如何在组织中演变 DevOps 文化并提高效率和效果。

DevOps 文化如何演变?

低效的估算、较长的市场推出时间和其他问题导致了瀑布模型的变化,从而转向了敏捷模型。文化的演变不是一个有时间限制或一蹴而就的过程。它可以是一个逐步进行的过程,可以在没有依赖其他阶段的情况下实现。

我们可以在没有云资源配置的情况下实现持续集成。我们可以在没有云资源配置的情况下实现配置管理。我们可以在没有其他 DevOps 实践的情况下实现持续测试。以下是实现 DevOps 实践的不同阶段:

敏捷开发

敏捷开发或基于敏捷的方法论有助于通过赋权个人并鼓励互动来构建应用程序,重视工作软件、客户合作——利用反馈在后续步骤中进行改进——并以高效的方式应对变化。

敏捷开发的一个最具吸引力的优势是在短时间内进行持续交付,或者用敏捷术语来说,就是迭代周期(sprints)。因此,应用开发的敏捷方法、技术的进步以及颠覆性创新和方法,造成了开发团队和运维团队之间的差距。

DevOps

DevOps 通过在开发和运维团队之间建立合作伙伴关系,尝试填补这些差距。DevOps 运动强调软件开发人员和 IT 运维之间的沟通、协作和集成。

DevOps 促进协作,而协作通过自动化和编排来推动,以改善流程。换句话说,DevOps 本质上将敏捷运动的持续开发目标扩展到持续集成和发布。

DevOps 是敏捷实践和流程的结合,利用云解决方案的优势。敏捷开发和测试方法帮助我们实现持续集成、开发、构建、部署、测试和发布应用程序的目标。

构建自动化

自动化构建帮助我们使用构建自动化工具(如 Gradle、Apache Ant 和 Apache Maven)创建应用程序构建。

自动化构建过程包括编译源代码成类文件或二进制文件、提供第三方库文件的引用、提供配置文件路径、将类文件或二进制文件打包成包文件、执行自动化测试用例、在本地或远程机器上部署包文件,并减少创建包文件时的人工工作。

持续集成

简单来说,持续集成(CI)是一种软件工程实践,每次开发人员提交的代码都会通过以下方式之一进行验证:

  • 拉取机制:在预定时间执行自动化构建

  • 推送机制:在更改保存到仓库时执行自动化构建

接下来的步骤是对源代码仓库中的最新更改执行单元测试。持续集成是一种流行的 DevOps 实践,要求开发人员每天多次将代码集成到 Git 和 SVN 等代码仓库中,以验证代码的完整性。

每次提交都会通过自动化构建进行验证,允许团队尽早发现问题。

CI,甚至 CD,是公司实现 DevOps 的基础。如果没有良好的 CI 和 CD 实施,组织是无法进行 DevOps 的。

云资源配置

我们在本章之前已经介绍了云计算的基础知识。云资源配置使得将基础设施即代码IAC)成为可能,这使整个过程变得非常高效和有效,因为我们正在自动化一个曾经需要大量人工干预的过程。

按需付费的计费模型使得所需资源对大型组织、以及中小型组织和个人都变得更加负担得起。

它有助于推动改进和创新,因为以前资源限制阻碍了组织因为成本和维护问题而走得更远。一旦基础设施资源具有灵活性,我们就可以考虑自动化安装和配置运行应用程序所需的包。

配置管理

配置管理CM)管理系统中的变更,或者更具体地说,服务器运行时环境中的变更。市场上有许多工具可以帮助我们实现配置管理。常见的工具包括 Chef、Puppet、Ansible、Salt 等。

假设我们需要管理多个具有相同配置的服务器。

例如,我们需要在每个服务器上安装 Tomcat。如果我们需要更改所有服务器上的端口、更新某些包或为某些用户提供权限呢?在这种情况下的任何修改都是手动的,并且容易出错。由于相同的配置被用于所有服务器,自动化在这里是非常有用的。

持续交付

持续交付和持续部署常常可以互换使用。然而,它们之间有一个小的区别。

持续交付是以自动化方式将应用程序部署到任何环境中,并提供持续反馈以改进其质量的过程。

自动化方法在持续交付和持续部署中可能不会发生变化。批准过程和一些其他小的事项可能会有所不同。

持续测试和部署

持续测试是端到端应用生命周期管理过程中的非常重要的阶段。它包括功能测试、性能测试、安全性测试等。

Selenium、Appium、Apache JMeter 以及许多其他工具都可以用于此目的。

另一方面,持续部署是指将带有最新更改的应用程序部署到生产环境中。

持续监控

持续监控是端到端交付管道的支柱,而开源监控工具则像是冰淇淋上的配料。

在几乎每个阶段进行监控是理想的,以便对所有过程保持透明,正如以下图表所示。这也帮助我们快速排查故障。监控应该是经过深思熟虑的计划实施。

让我们尝试在以下图表中将整个过程呈现为持续的方法:

我们需要在这里理解,变革是一个阶段性的方法,并且并不需要一次性自动化每个阶段的所有内容。一次集中实施一个 DevOps 实践,先实现它并感受到其效益,再实施下一个,会更加有效。

通过这种方式,我们可以安全地评估组织文化变革带来的改进,并消除应用生命周期管理中的手工操作。

PPT 的重要性——人员、流程与技术

PPT 是任何组织中一个重要的词。等一下!我们这里不是在说 Powerpoint 演示文稿。这里,我们关注的是人员、流程和工具/技术。让我们理解为什么它们在改变任何组织文化中的重要性。

人员

根据 Jack Canfield 的名言:

成功的人无论周围发生什么,他们都会保持积极的生活态度。他们专注于过去的成功,而不是过去的失败,并专注于下一步的行动,以便将自己带到更接近目标实现的地方,而不是生活中所有的其他干扰。

一个值得思考的问题是,为什么人员如此重要?如果我们要用一句话回答,那就是:因为我们在试图改变文化。

那么呢?

人员是任何文化的重要组成部分,只有人才能推动变革,或是改变自己去适应新流程,或是定义新流程并学习新的工具或技术。

让我们通过变革公式来理解其中的原理和原因。

David Gleicher 在 1960 年代初创建了变革公式,根据维基百科中的资料。Kathie Dannemiller 于 1980 年进行了改进。这个公式为评估影响组织变革成功的相对因素提供了一个模型。

Gleicher(原版)公式: C = (ABD) > X,*其中:C = 变革,A = 对现状的不满,B = 渴望的清晰目标,D = 实现目标的实际步骤,X = 变革的成本。*

Dannemiller 版公式: D x V x F > R; 其中 D、V 和 F 必须同时存在,才能促成组织变革,其中:D = 对现状的不满,V = 对可能的愿景,F = 实现愿景的第一步。若这三者的乘积大于 R = 抵制力,则变革是可能的。

本质上,这意味着必须对现有的事物或流程有强烈的不满,对新趋势、技术和创新在市场场景中的潜力有明确的愿景,并能够采取具体的步骤朝着实现这一愿景的方向努力。

若想了解更多关于变革公式的内容,您可以访问这个维基页面:en.wikipedia.org/wiki/Formula_for_change#cite_note-myth-1

如果要分享经验,我认为训练人们采纳新文化非常重要。这是一个耐心的游戏。我们无法在一夜之间改变人们的思维方式,我们需要先理解,再去改变文化。

在行业中,经常会看到带有 DevOps 知识或 DevOps 工程师职位的招聘广告,但理想情况下,这些职位不应该是外部引进的,而是应该通过逐步改变现有环境来培训现有人员,以便有效管理抗拒。我们不需要一个专门的 DevOps 团队;我们需要开发人员、测试团队、自动化促进者和云或基础设施团队之间更多的沟通与协作。

了解彼此的痛点至关重要。在我工作过的组织中,我们曾经设有卓越中心COE),用来管理新技术、创新或文化。作为自动化促进者和 DevOps 团队的一部分,我们应该仅作为促进者工作,而不是孤立的一部分。

流程

这里有一句来自汤姆·彼得斯的名言,原文是:

几乎所有的质量改进都来自于设计、制造、布局、流程和程序的简化。

在推动文化演变的过程中,质量至关重要。我们需要制定流程和政策,以规范且标准化的方式进行工作,从而确保操作顺序、约束条件、规则等得到明确定义,以衡量成功。

我们需要为以下内容设定流程:

  • 敏捷规划

  • 资源规划和配置

  • 配置管理

  • 基于角色的访问控制,适用于云资源和自动化中使用的其他工具

  • 静态代码分析——编程语言的规则

  • 测试方法和工具

  • 发布管理

这些流程对于衡量在推动 DevOps 文化演变过程中的成功也至关重要。

技术

这里有一句来自史蒂夫·乔布斯的名言,原文是:

技术并不重要。重要的是你对人们有信心,相信他们本质上是善良且聪明的,给他们工具,他们会用这些工具做出令人惊叹的事情。

技术帮助个人和组织在改变文化的过程中带来创造力和创新。如果没有技术,难以在日常和例行的自动化操作中实现速度和效果。云计算、配置管理工具和构建流水线等工具,在资源配置、运行环境安装和编排方面非常有用。从本质上讲,它有助于加速应用生命周期管理的各个方面。

为什么 DevOps 并不完全是工具的问题

是的,工具并不重要。它们在改变任何组织文化中并不是那么重要的因素。原因很简单。无论我们使用什么技术,我们都会执行持续集成、云资源配置、配置管理、持续交付、持续部署、持续监控等操作。

按类别,您可以使用不同的工具集,但它们执行的操作相似。只是工具执行某项操作的方式不同,其他方面的结果是相同的。以下是基于类别的一些工具:

类别 工具
构建自动化 Nant, MSBuild, Maven, Ant 和 Gradle
代码库 Git 和 SVN
静态代码分析 Sonar 和 PMD
持续集成 Jenkins, Atlassian Bamboo, 和 VSTS
配置管理 Chef, Puppet, Ansible, 和 Salt
云平台 AWS 和 Microsoft Azure
云管理工具 RightScale
应用部署 Shell 脚本和插件
功能测试 Selenium 和 Appium
负载测试 Apache Jmeter
代码仓库 Artifactory, Nexus, 和 Fabric

让我们看看不同的工具如何在不同的阶段、不同的操作中发挥作用。这可能会根据环境的数量或我们在不同组织中遵循的 DevOps 实践的数量而有所变化:

如果我们需要根据不同的 DevOps 最佳实践对工具进行分类,可以根据开源和商业类别进行分类。以下只是一些示例:

组件 开源 IBM Urban Code Electric-Cloud
构建工具 Ant 或 Maven 或 MS Build Ant 或 Maven 或 MS Build Ant 或 Maven 或 MS Build
代码仓库 Git 或 Subversion Git 或 Atlassian Stash 或 Subversion 或 StarTeam Git 或 Subversion 或 StarTeam
代码分析工具 Sonar Sonar Sonar
持续集成 Jenkins Jenkins 或 Atlassian Bamboo Jenkins 或 ElectricAccelerator
持续交付 Chef Artifactory 和 IBM UrbanCode Deploy ElectricFlow

在本书中,我们将尝试聚焦于开源类别和商业工具。我们将使用 Jenkins 和 Visual Studio Team Services 来执行所有主要的自动化和编排相关活动。

DevOps 评估问题

DevOps 是一种文化,我们非常清楚这一点。然而,在实施自动化、制定流程和发展文化之前,我们需要了解组织当前的文化状态,以及是否需要引入新的流程或自动化工具。

我们需要非常清楚的是,我们需要使现有文化更加高效,而不是引入新的文化。适应一个评估框架是困难的,但我们将尽力提供一些问题和提示,基于这些内容,创建评估框架会更加容易。

创建我们希望提问并为特定应用获取反馈的类别。

以下是一些示例问题:

  1. 您是否遵循敏捷原则?

  2. 您是否在使用任何源代码仓库?

  3. 您是否在使用任何静态代码分析工具?

  4. 您是否在使用任何构建自动化工具?

  5. 您是使用本地基础设施还是云基础设施?

  6. 您是否使用任何配置管理工具或脚本来安装应用程序包或运行时环境?

  7. 您是否使用任何自动化脚本来部署应用程序到生产环境和非生产环境?

  8. 您是否使用任何编排工具或脚本来进行应用生命周期管理?

  9. 您是否使用任何自动化工具进行功能测试、负载测试、安全测试和移动测试?

  10. 您是否使用任何工具来进行应用程序和基础设施监控?

一旦问题准备好,准备响应,并根据这些响应,为每个前述问题的回答决定评分。

使框架具有灵活性,这样即使我们更改某一类别中的问题,也能自动管理。

一旦给出评级,就通过引入不同的条件和智能到框架中,捕捉响应并计算总体评分。

创建按类别划分的最终评级,并从最终评级中创建不同类型的图表,以提高其阅读价值。这里需要注意的重要事项是组织在每个应用生命周期管理领域的专业知识的重要性。这将为评估框架赋予新的维度,加入智能,使其更有效。

总结

在本章中,我们已经设定了整个书籍要实现的多个目标。我们涵盖了持续集成、云环境中的资源配置、配置管理、持续交付、持续部署和持续监控。

设定目标是将无形转化为有形的第一步。

-托尼·罗宾斯(Tony Robbins)

我们已经看到了云计算如何改变以前对创新的看法,以及现在它变得多么可行。我们还简要介绍了 DevOps 及其所有不同的实践。在这个过程中,人、流程和技术也非常重要,这关系到改变一个组织的现有文化。我们试图探讨它们为何重要。工具很重要,但不是决定性因素;任何工具集都可以使用,改变文化不需要特定的工具集。我们也简要讨论了 DevOps 评估框架,它将帮助你走上改变文化的道路。

信仰就是即使看不到整个楼梯,也要迈出第一步。

-马丁·路德·金(Martin Luther King, Jr.)

在下一章中,我们将迈出朝向持续集成的旅程的第一步。我们将使用 Jenkins 和 Microsoft Visual Studio Team Services 来实现持续集成,并验证如何在不同的工具中实现 CI,而不会遇到重大挑战。

第二章:持续集成

持续的努力——不是力量或智力——是解锁我们潜力的关键

  • 温斯顿·丘吉尔

在本章中,我们将介绍如何安装持续集成服务器 Jenkins,并执行与编译、单元测试执行、代码分析和创建包文件相关的各种任务。我们还将讨论使用微软技术栈进行的持续集成。目标是尽可能多地了解持续集成,因为它是其他自动化的基础。以下是我们将涉及的主题要点:

  • 安装 Jenkins 2

  • 配置基于 Maven 的 JEE Web 应用程序

  • 集成 Jenkins 和 SonarQube

  • 从 Jenkins 执行命令行操作

  • 使用 VSTS 进行持续集成

首先让我们了解一下 Jenkins——现在的持续集成服务器或自动化服务器,尤其是在 Jenkins 2.0 之后。

安装 Jenkins 2

以下是我们可以遵循的一些安装 Jenkins 的步骤:

  1. 安装 Java 开发工具包 8,并将JAVA_HOME设置为环境变量。在命令提示符或终端中,执行java –versionjavacjava命令,以验证 Java 是否正确安装。 从 Jenkins 官网下载安装jenkins.war文件。

  2. 要运行 Jenkins,执行java –jar jenkins.war。 等待 Jenkins 完全启动并运行。

  3. Jenkins 完全启动并运行后,打开浏览器并访问http://<localhost/IP_ADDRESS>:8080

  4. 我们需要首先解锁 Jenkins,才能继续进行配置。从给定的文件位置复制密码,或者从我们执行 Java 命令的控制台/终端中复制密码。

  5. 输入管理员密码并点击继续。

  6. 安装推荐的插件或选择要安装的插件。

如果我们处于防火墙后面,它将要求我们设置代理设置,以便下载所需的插件。如果我们熟悉 Jenkins,可以完全跳过插件安装,并在需要时稍后安装它们。这会使配置过程更快。如果在代理后面,我们在下载某些插件时可能会遇到问题。在这种情况下,最好先识别这些插件,并使用“选择插件安装”选项,以避免无休止的等待或配置失败。

  1. 完成插件安装过程后,或跳过该过程后,我们需要创建第一个管理员用户。Jenkins 2 之后,插件安装和安全配置成为初始设置的一部分,这使得工具更加成熟。

  2. 提供所需的用户详细信息并点击保存并完成。现在,Jenkins 已经准备就绪,Jenkins 的设置也已完成。我们可以开始使用 Jenkins 了。这时,我们将首次遇到 Jenkins 仪表板。

我们可以管理与 Jenkins 相关的配置,如工具配置、安全配置、创建构建任务、管理插件和管理代理。

以下截图展示了 Jenkins 仪表板:

我们将在自动化目标中使用 Java/JEE 示例应用程序。首先,我们需要告诉 Jenkins 安装文件的位置,因为这些文件是执行某些任务所必需的。由于该应用程序使用 Maven 构建工具,我们还需要一个 Maven 安装文件夹。下载 Apache Maven。进入 Jenkins 仪表板中的“管理 Jenkins”,点击“全局工具配置”。点击“添加 JDK”。我们已经安装了 JDK,因此可以提供 JAVA_HOME 的路径,我们的 Java 配置也已经完成。

Jenkins 中的全局工具配置

在本节中,我们将配置在创建构建作业时需要使用的各种工具,例如 Java、Ant、Maven 等。

我们也可以从 Jenkins 仪表板中安装这些工具。如果我们有两个不同的应用程序,其中一个需要使用 JDK 1.7 编译,另一个需要使用 JDK 1.8 编译怎么办?我们可以添加多个 JDK,并在创建构建作业时指定要为该构建作业执行所使用的 JDK。

配置完 Java 后,我们的下一个任务是配置 Maven:

现在,我们已经在 Jenkins 中配置了不同的工具,接下来我们将在 Jenkins 仪表板中创建一个新作业或项目,以便为基于 JEE 的应用程序配置持续集成。

创建和配置基于 Maven 的 JEE Web 应用程序

在本节中,我们将创建一个基于 Maven 的 Jenkins 构建作业,该作业将执行 pom.xml 文件的编译、单元测试执行并创建包文件。让我们开始吧!

在 Jenkins 仪表板上点击“新建项目”:

由于这是一个基于 Maven 的项目,我们将选择“Maven 项目”模板。如果是基于 Ant 的应用程序或其他自动化任务,则可以选择“自由风格项目”模板来创建构建作业。选择 Maven 项目并点击“确定”。这将打开构建作业配置页面,如下图所示:

在源代码管理中,提供 GitHub URL、SVN URL(首先安装 Subversion 插件)或任何仓库 URL。我们还可以访问文件系统中的代码:

在构建部分,选择我们在“全局工具配置”部分配置的 Maven 版本。提供要在 pom.xml 上执行的 Maven 目标。有关 Maven 目标的更多详细信息,请访问 Apache Maven 网站。package 目标将编译源代码,执行单元测试,并在 Java 环境中创建包或 war 文件:

在作业配置页面点击“应用”并保存。点击仪表板上的“立即构建”链接。验证同一页面上的构建历史。第一次构建将会开始。

点击进度条,直接跳转到 Jenkins 仪表板上的控制台输出。

它将开始从代码库中获取代码并将其放入本地工作空间。如果成功获取代码,则可以在项目或构建仪表板上检查工作空间。

等待 Maven 包目标在 Jenkins 中执行。它将编译所有源文件,执行用 JUnit 编写的单元测试用例,并生成需要在 Web 服务器(如 Tomcat 或 JBoss)上部署的 WAR 文件:

一旦构建成功,我们的第一个目标就达成了,那就是持续集成。如果由于 Maven 下载问题失败,则检查 Maven 相关设置。如果 Jenkins 安装在代理后面,则在 Apache Maven 的配置文件中提供代理详细信息,这样它就可以访问 Maven 仓库并下载所需的文件。

Jenkins 中的单元测试用例结果

要检查单元测试的执行情况,进入项目并验证已成功执行的构建。点击测试结果(无失败):

它会根据包的情况给出测试结果列表。要获取更多详细信息,转到具体的包并验证结果:

Jenkins 中的主代理架构

假设有一个场景,我们需要的特定工具位于另一台服务器上,而这些工具是应用生命周期管理中重要阶段的一部分。

在这种情况下,我们可以将 Jenkins 服务器作为主节点,将具有特定工具的服务器作为代理。这样,主 Jenkins 就可以访问其他服务器上的资源来执行特定操作。

转到“管理 Jenkins”,然后点击“管理节点”。我们可以看到安装了 Jenkins 的主节点。要添加一个新的节点(可能有不同的操作系统和工具集),我们需要点击“新建节点”:

输入节点名称,并选择其为“永久代理”。点击“确定”。输入名称、标签和远程根目录。远程根目录是存储代理上执行所有详细信息的目录。它类似于代理节点上 JENKINS_HOME 的工作空间目录:

点击“保存”;然后转到安全配置并启用从属代理端口——JNLP 代理的 TCP 端口(保持为随机端口,而非禁用状态):

转到主 Jenkins 中的代理配置。复制从代理命令行运行的命令:

在代理机器上下载 slave.jar 文件,并按以下截图中的命令执行:

一旦代理在控制台连接成功,也请在主 Jenkins 中验证该连接:

当我们将代理连接到主节点后,就可以将构建任务分配给该代理执行。在执行构建任务之前,我们需要确保所有执行所需的工具也在主 Jenkins 中进行了配置,以便主节点能够使用这些可安装工具进行执行。

在任务配置中,我们可以选择勾选“限制此项目可运行的位置”复选框,并为代理提供标签表达式:

在代理节点页面中,我们可以提供工具位置:

我们可以使用这些代理进行静态代码分析或测试执行,在这些代理上可以安装不同的工具,然后将代理分配给执行任务。接下来我们将介绍 SonarQube。

集成 Jenkins 和 SonarQube

首先,让我们看看如何将 SonarQube 配置到 Jenkins 中,这样我们就可以通过触发 Jenkins 来执行静态代码分析。

转到管理 Jenkins,点击管理插件,然后点击可用选项卡。找到 SonarQube 插件并安装它。

转到管理 Jenkins,然后点击配置系统。找到 SonarQube 服务器部分,点击添加 SonarQube 服务器。提供服务器 URL 和凭据。从 SonarQube 获取服务器身份验证令牌(管理 | 安全 | 用户),并在 Jenkins 中提供该令牌:

转到管理 Jenkins 中的全局工具配置,并配置 SonarQube 扫描器自动安装:

在 Jenkins 中创建一个新的自由风格任务。配置 SonarQube 安装的代理的 JDK 路径。

还需要安装 质量门 插件。通过配置 质量门 插件,我们可以在 SonarQube 分析失败时使 Jenkins 构建任务失败。

配置项目的仓库 URL。转到任务配置,在构建步骤中添加执行 SonarQube 扫描器。选择 JDK,并输入 sonar-project.properties 的路径或提供分析属性:

在构建后操作中,选择质量门。

输入我们在分析属性或 sonar-project.properties 中提供的项目密钥:

点击立即构建并验证 Jenkins 中构建执行的结果。

转到 SonarQube 服务器,验证仪表板中是否有代码分析:

这就是如何将 SonarQube 集成到 Jenkins 中的方式。接下来,让我们看看如何从 Jenkins 发送电子邮件通知。

Jenkins 中的电子邮件通知

让我们看看如何配置电子邮件通知,将任务执行的状态发送给特定的利益相关者。转到管理 Jenkins,点击配置系统,并配置电子邮件设置,如下图所示:

在构建后操作中,选择电子邮件通知并配置收件人。保存设置:

如果构建不稳定,我们可以发送通知,并向破坏构建的个人发送电子邮件。

在下一部分,我们将看到如何使用 Visual Studio Team Services (VSTS) 进行持续集成。

使用 Visual Studio Team Services 进行持续集成

我们常说 DevOps 和工具无关。所有工具执行相同的操作,只是有些细微的差异或灵活性。我们将看到如何使用 VSTS 进行持续集成。

在 VSTS 中创建一个账户,并创建一个名为PetClinic的项目。

Eclipse 与 VSTS 集成

在本节中,我们将看到如何将 Eclipse 与 VSTS 集成,以便我们可以从本地系统将代码提交到 VSTS。

下载 Eclipse,打开它,然后点击“Help”菜单。选择“Install New Software”。

在 Eclipse 中添加一个站点以安装 TFS 插件,这样我们就可以直接从 Eclipse 提交代码到 VSTS。

选择“Team Explorer Everywhere”,然后点击“Next”:

审核安装详细信息并点击“Next”。

审核许可协议并接受条款,点击“Finish”。

等待安装完成后重新启动 Eclipse。

在 Eclipse 中,转到 Window | Perspective | Open Perspective | Other... | 选择 Team Foundation Server Exploring。

点击“Connect to Team Services or a Team Foundation Server”。我们将连接到团队服务:

在“Team Foundation Server”列表中点击“Add...”并提供我们 VSTS 账户的 URL:

它将尝试连接到 VSTS 账户并请求凭证。

一旦连接成功,我们就可以从 Eclipse 连接到服务器。

点击“Next”:

从列表中选择一个团队项目。

点击“Finish”。

进入浏览器中的 VSTS 账户并验证项目文件夹中的现有数据。

在 Eclipse 中验证 Team Explorer 视图。现在它已连接,我们可以进行操作:

在进行任何其他操作之前,将 PetClinic 代码导入到 Eclipse 中。

右键点击项目并选择“Team”。

选择Share Project

在“Select a repository type plugin”对话框中选择 Team Foundation Server。

点击“Next”:

在“Team Project Selection”对话框中选择我们最初在 VSTS 中创建的团队项目:

选择一个服务器位置以共享项目:

审核共享配置并点击“Finish”。

完成后,转到 Team Explorer 视图,并在提供评论后点击 Check In:

确认 Check In。

在 Eclipse 中验证 Check In,附近文件的图标将会变化,以表示文件自上次 Check In 以来没有更改。

验证 VSTS 中的所有文件:

一旦我们在 VSTS 的代码部分中拥有代码,就可以轻松配置 VSTS 中的持续集成。

VSTS 中的持续集成

本质上,我们将按照开发者可以通过 IDE 在代码库中共享代码的流程进行操作。VSTS 会触发构建定义的执行,并根据配置进行源文件编译、单元测试执行等任务,生成一个包文件:

在 VSTS 中,我们需要为持续集成创建构建定义。请在浏览器中进入 VSTS 账户。

点击 PetClinic 项目:

点击顶部菜单栏中的“Build & Release”,然后选择“Builds”:

目前没有可用的构建定义。创建一个+新建定义:

我们有基于 Maven 的项目,因此我们将选择 Maven 构建定义模板:

选择一个仓库源:

勾选“持续集成(每当此仓库更新时构建)”。点击“创建”:

它将以编辑模式打开构建定义。

在 Maven 构建步骤中,验证pom.xml文件的位置:

点击“触发器”部分,验证持续集成(CI):

点击“保存”按钮并为构建定义命名:

点击“排队新构建...”来执行构建定义:

它将等待可用的代理来执行构建定义:

等待构建执行成功完成:

转到“构建”部分,验证构建结果:

验证构建定义执行的摘要。它在托管代理上执行。所有必需的运行时环境都在托管代理上可用:

验证构建定义执行历史记录,以查看单元测试执行的结果:

转到 VSTS 中的测试计划部分,点击“最近的测试运行”以查看单元测试执行的更多细节:

现在我们完成了。

我们使用 VSTS 实现了一个基于 Spring 的 Java Web 应用程序的持续集成。

在 Jenkins 和 VSTS 中,自动化执行的方式大致相同。因此,理解其中一种工具总是有助于使用任何其他工具完成相同的任务,这证明了我们对“这不在于工具”的信念。它关乎于人、流程、心态和工具。

摘要

有一句来自马塞尔·普鲁斯特的著名名言:

发现的真正旅行不在于寻找新的风景,而在于拥有新的眼光。

我们将改变应用程序包的创建方式。我们可能需要通过相同的过程来创建一个包、WAR 文件、APK 文件或 IPA 文件。因此,我们并不是在寻找新的风景。然而,我们需要找到一种高效的方式来有效地完成这个过程,因此我们需要寻找拥有新的眼光。

在本章中,我们详细描述了如何使用 Jenkins 和 Visual Studio Team Services 进行持续集成。我们查看了单元测试执行的结果,以及在 Jenkins 和 Visual Studio Team Services 中如何创建包。

我们所知道的最重要的事情是,实施持续集成作为一种 DevOps 实践并不依赖于特定的工具。我们可以使用任何工具来实现自动化,并达到相同的目标。关键在于组织中的文化或模式,而不是工具。

一旦我们准备好软件包,我们需要为部署准备或保持一个环境。在下一章中,我们将看到如何使用 Docker 容器来准备环境。

第三章:容器

“任何技术在商业中使用的第一条规则是,自动化应用于高效的操作会放大效率。第二条规则是,自动化应用于低效的操作会放大低效。”

  • 比尔·盖茨

到目前为止,我们已经看到 DevOps 实践和持续集成。然而,最近,容器已经成为一个流行词,大家都希望亲自体验它。主要原因是为了更有效地利用资源。Docker 是一个开源的操作系统虚拟化项目,自动化应用程序在软件容器中的部署。它在开发或质量保证环境中非常有用,可以更好地利用资源。

在本章中,我们将尝试安装和创建一个示例容器。目标是熟悉 Docker 容器,并了解如何利用容器进行应用程序部署。

本章提供了对容器的快速概述。我们将集中讨论本章中的以下主题:

  • Docker 容器概述

  • 理解虚拟机和容器之间的区别

  • 安装和配置 Docker

  • 创建一个 Tomcat 容器

Docker 容器概述

Docker 提供了隔离的用户空间,从而提供基于用户的进程、空间和文件系统。在幕后,它共享 Linux 主机的内核。以下图示说明了 Docker 容器的工作机制:

Docker 有两个主要组件,采用客户端-服务器架构:

  • Docker 主机

  • Docker Hub

让我们更详细地看一下它们:

  • Docker 主机:Docker 主机包含 Docker 守护进程、容器和镜像。Docker 引擎是一个重要组件,提供核心的 Docker 技术。这一核心 Docker 技术使得镜像和容器得以实现。当我们成功安装 Docker 后,只需运行一个简单的命令。在我们的案例中,我们将使用 CentOS 作为容器。要在 CentOS 镜像中运行交互式 Shell,可以使用命令 docker run -i -t <image> /bin/bash

    • -i 标志启动交互式容器

    • -t 标志创建一个伪终端,连接 stdinstdout

    • 镜像是一个 CentOS 镜像

    • /bin/bash 启动一个 Shell

当我们运行此命令时,它会验证 CentOS 镜像是否本地可用。如果不可用,它会从 Docker Hub 下载该镜像。

镜像有文件系统和可在运行时使用的参数,而容器是具有状态的镜像实例。理解容器会发生变化,而镜像不会变化是很简单的。

  • Docker Hub:Docker Hub 是一个 软件即服务SaaS),用于共享和管理 Docker 容器。它是 Docker 提供的一种集中式注册服务。作为用户,我们可以使用它来构建和交付应用程序。它允许我们创建一个管道,集成代码仓库,进行协作、镜像发现和自动化。

理解虚拟机和容器之间的差异

在开始安装 Docker 和创建容器之前,了解容器为什么与虚拟机不同以及它们之间的差异会很有帮助。

让我们了解虚拟机和容器之间的基本区别。

虚拟机

虚拟机 (VM) 中,我们需要安装一个操作系统,并配备适当的设备驱动程序;因此,虚拟机的占用空间非常大。一个正常的虚拟机,安装了 Tomcat 和 Java,可能需要高达 10 GB 的硬盘空间:

存在内存管理和设备驱动程序的开销。虚拟机拥有正常物理机器所具备的所有组件。

在虚拟机中,虚拟化程序抽象了资源。它的包不仅包括应用程序,还包括必要的二进制文件和库,以及整个来宾操作系统,例如 CentOS 6.7 和 Windows 2003。

云服务提供商使用虚拟化程序(hypervisor)为虚拟机提供标准的运行时环境。虚拟化程序分为类型 1 和类型 2。

容器

容器共享主机的操作系统和设备驱动程序。容器是从镜像创建的,对于安装了 Tomcat 的容器,其大小不到 500 MB:

容器体积小,因此提供更快更好的性能。它们将操作系统进行了抽象。

容器以隔离的用户空间运行,进程和文件系统位于主机操作系统的用户空间中,并且与其他容器共享内核。容器的共享和资源利用效率非常高,并且由于开销较少,能够提供更多的资源。它在资源要求非常少的情况下就能正常工作。

Docker 使得跨环境迁移应用变得高效且更容易。

安装和配置 Docker

让我们快速在 Windows 10 上安装 Docker。对于我们来说,是 Windows 家庭版;所以我们需要从 www.docker.com/products/docker-toolbox 安装 Docker Toolbox:

  1. 点击下载按钮:

  1. 它会将您重定向到 github.com/docker/toolbox/releases/tag/v1.12.5 或包含最新版本的页面。

  2. 下载 DockerToolbox。点击 Docker Toolbox 的 exe 文件进行安装:

  1. 在欢迎页面上点击“下一步 >”:

  1. 选择安装 Docker Toolbox 的首选位置:

  1. 保留安装的所有默认组件。

  1. 选择应执行的附加任务,然后点击“下一步 >”:

  1. 点击安装:

  1. Docker Toolbox 安装将同时安装 VirtualBox:

  1. 点击完成:

在开始 Docker 操作之前,我们需要在 Windows 系统中启用虚拟化技术,否则我们将遇到以下错误:

  • 使用C:UsersMitesh.dockermachinecertsca.pem创建 CA

  • 使用C:UsersMitesh.dockermachinecertscert.pem创建客户端证书

  • 运行预创建检查... 预创建检查错误: "此计算机未启用 VT-X/AMD-v。必须在 BIOS 中启用它" 看起来在步骤'检查是否存在默认机器'中出了问题... 按任意键继续...

  • 转到设置并点击高级启动。重启系统。更改 BIOS 设置以启用虚拟化技术:

系统重启后,点击桌面上的 Docker Quickstart Terminal。它将执行预创建检查并下载boot2docker.iso,然后运行虚拟机。

完成所有配置和检查后,Docker 已成功启动:

要获取如何在 CentOS 中安装 Docker 的详细信息,请阅读《DevOps for Web Development》,可以在www.packtpub.com/networking-and-servers/devops-web-development找到。

一旦 Docker 正常运行,我们就可以创建 docker 容器了。请注意默认 docker 机器的 IP 地址:

让我们创建一个示例的 hello world 容器。执行docker run hello-world。如果你看到"Hello from Docker!"消息,那么我们已经成功创建了容器:

因为我们需要部署一个 JEE 应用程序,在接下来的部分我们将创建一个 Tomcat 容器。

创建一个 Tomcat 容器

在本节中,我们将创建一个已安装 Tomcat Web 服务器的容器,以便可以将基于 Java 的 Web 应用程序部署到其中:

  1. 在 Docker hub 上创建一个帐户并登录:

  1. 我们可以从 Docker hub 中搜索不同的镜像:

  1. 你可以在hub.docker.com/_/tomcat/找到 Tomcat 镜像。

  2. 使用 Docker 的pull命令获取 Tomcat 镜像:

 docker pull tomcat 

  1. 一旦 Tomcat 镜像可用,通过执行docker images命令验证它:

  1. 要从镜像中运行 docker 容器,执行docker run -it --rm -p 8888:8080 tomcat:8.0

  2. 在浏览器中使用默认 docker 机器的 IP 地址和端口8888来验证 Tomcat 是否在容器中正常运行:

  1. 要获取虚拟机的 IP 地址,执行docker-machine ls命令。

让我们验证是否可以访问这个容器中的 Tomcat 管理应用程序:

我们在这里要做的是,创建一个带有我们自己tomcat-users.xml的新镜像,在该文件中创建一个拥有manager-script角色的用户来访问 Tomcat 管理应用程序。

创建一个目录。进入该目录并创建一个tomcat-users.xml文件。

在其中添加以下内容:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users  
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0">
<!--
NOTE: The sample user and role entries below are intended for use with the examples web application. They are wrapped in a comment and thus are ignored when reading this file. If you wish to configure these users for use with the examples web application, do not forget to remove the <!....> that surrounds them. You will also need to set the passwords to something appropriate.
-->
<role rolename="manager-script"/>
<user username="admin" password="admin@123" roles="manager-script"/>
</tomcat-users>

在同一目录中创建一个名为 Dockerfile 的新文件,并添加以下内容:

FROM tomcat:8.0 MAINTAINER Mitesh<xxxxxx.xxxxxx@gmail.com> COPY tomcat-users.xml /usr/local/tomcat/conf/tomcat-users.xml

在 Docker Quickstart Terminal 中,进入我们创建的目录。

执行 docker build -t devops_tomcat_sc

镜像成功构建后,使用 docker images 来验证:

执行 docker run -it -p 8888:8080 devops_tomcat_sc:8.0 并使用 docker ps -a 验证容器数量。

我们可以使用 docker stop <container_name> 来停止容器:

要更改容器的名称,请使用 docker run -it -p 9999:8080 --name bootcamp_tomcat devops_tomcat_sc

使用 docker ps -a 验证名称:

使用虚拟机的 IP 地址和 9999 作为端口号访问容器中运行的 Tomcat:

使用以下 URL 使用 manager-script 角色验证管理器访问:

让我们尝试使用 Tomcat 中的 Deploy to Container 插件部署应用程序。如果某个构建任务生成了 WAR 文件,则使用复制构件插件从该构建中复制它:

在构建后操作中,选择将 WAR/ EAR 部署到容器。提供 tomcat-users.xml 中的用户名和密码。提供 Tomcat URL。点击应用/保存:

点击立即构建:

转到控制台输出并验证部署过程:

使用 Tomcat URL 和应用程序上下文验证应用程序的 URL:

现在我们完成了。

如此一来,你可以看到我们已经创建了一个镜像、一个容器,并在 Tomcat 容器中部署了应用程序。

总结

所以我们在本章中看到了如何在 Windows 10 中安装 Docker 容器,以及如何使用 Docker hub 查找公共域中可用的镜像。

我们执行了 hello world 容器以验证 Docker 是否成功安装。一旦验证了 Docker 安装,我们就使用 Docker hub 获取了 Tomcat 镜像,并成功创建了一个 Tomcat 8 容器并通过浏览器访问它。

我们还使用 Jenkins 在 Tomcat 容器中部署了应用程序。我们的目标是利用 Docker 容器进行应用程序部署。

在下一章中,我们将介绍如何利用配置管理工具 Chef 来设置运行时环境,以便在虚拟机中部署基于 Java 的 Web 应用程序。

第四章:云计算与配置管理

“变革之所以困难,是因为人们高估了自己所拥有的价值,而低估了放弃它后可能获得的价值。”

—— James Belasco 和 Ralph Stayer

在上一章中,我们已概述了 Docker 容器。本章将重点讲解如何为云中的应用程序部署创建和配置环境。我们将使用 基础设施即服务IaaS)和配置管理工具 Chef 来创建一个平台,以便后续使用自动化部署应用程序。

Chef 是一种配置管理工具,可用于创建物理机、虚拟化基础设施或公有或私有云基础设施上的应用程序部署运行时环境。

在本章中,我们将讨论以下主题:

  • Chef 配置管理工具概述

  • 安装和配置 Chef 工作站

  • 使用 Chef 工作站合并 Chef 节点

  • 使用社区食谱安装 Tomcat 包

Chef 配置管理工具概述

Chef 是最受欢迎的配置工具之一。它有两种版本:

  • 开源 Chef 服务器

  • 托管 Chef

我们这里打算展示的是如何为应用程序部署准备运行时环境。让我们从应用生命周期管理的角度来理解:

  1. 我们有一个基于 Java 的 Spring 应用程序包,经过持续集成后已经准备好。

  2. 我们需要在 Tomcat Web 服务器中部署应用程序。

  3. Tomcat 服务器可以安装在物理系统、虚拟化环境、Amazon EC2 实例或 Microsoft Azure 虚拟机中。

  4. 我们还需要安装 Java。

在这些内容中,除了第一点外,我们需要手动完成安装和配置活动。为了避免这种重复场景,我们可以使用 Chef 配置管理工具在 AWS 或 Microsoft Azure 中创建虚拟机,然后安装 Tomcat 及其所有依赖项,以便部署基于 Java 的 Spring 应用程序。

然而,让我们先了解 Chef 配置管理工具的基本知识,以便理解 Chef 如何工作以及它如何执行各种步骤。

Chef 配置管理工具有三个重要部分:

  • 开源 Chef 服务器或托管 Chef:安装在本地的 Chef 服务器或托管的 Chef,是自动化安装运行时环境过程的核心。它是食谱和注册节点详细信息的集中存储库。Chef 工作站用于上传食谱并修改配置,使其可以应用到 AWS 和 Microsoft Azure 中的节点。

  • Chef 工作站:Chef 工作站是我们可以管理 cookbook 和其他更改的系统。我们可以在 Chef 工作站上执行所有管理任务。使用 Knife 上传 cookbooks 到 Chef 服务器,并执行插件命令。Knife 插件可以在 AWS 和 Microsoft Azure 云中执行各种操作。

  • 节点:节点是物理机或虚拟机。该虚拟机可以位于虚拟化环境、由 Openstack 或 VMware 提供支持的私有云中,或位于 AWS 或 Microsoft Azure 等公共云中:

    • 节点与开源或托管的 Chef 服务器进行通信。

    • 节点获取与自身相关的配置详细信息,然后基于这些信息开始执行步骤,以保持与管理员所决定的内容一致。

访问官方 Chef 网站 chef.io,并访问 Chef 首页。我们可以通过安装和管理本地 Chef 服务器使用它,也可以使用托管 Chef:

  1. 点击 chef.io 上的“管理控制台”或前往 manage.chef.io/login

  2. manage.chef.io/login 上点击“点击这里开始!”。

  3. 提供完整名称、公司名称、电子邮件 ID 和用户名。

  4. 勾选“我同意服务条款和主许可及服务协议”框。

  5. 点击“开始使用”按钮。

请参考以下截图:

所以显而易见的下一步是前往邮箱并验证电子邮件 ID 以完成注册过程。我们将收到电子邮件验证成功的消息:

  1. 提供密码并点击“创建用户”按钮。

  2. 现在创建一个组织。

  3. 点击“创建新组织”。

  4. 提供组织的完整名称和简称。

  5. 点击“创建组织”按钮。

请参考以下截图:

现在,下载一个入门套件:

  1. 点击“下载入门套件”。

  2. 我们将收到确认对话框;点击“继续”。

  3. 让我们验证托管 Chef 上可用的操作。

  4. 我们还没有配置任何节点,所以节点列表为空。点击“节点”。一旦我们创建并注册节点,我们将能在 Chef 服务器或托管的 Chef 上获取该节点的所有详细信息。

  5. 前往“管理”菜单,并点击侧边栏中的“用户”。

  6. 验证在注册时创建的用户名、完整名称和电子邮件 ID:

检查“报告”标签,我们将找不到任何数据。原因是节点汇聚的过程(即节点根据 Chef 服务器上可用的配置变得符合要求)尚未发生,因此没有数据。

此时,我们已有一个托管 Chef 账户。

现在,让我们配置一个 Chef 工作站,以便我们可以与托管的 Chef 通信,并汇聚 AWS 和 Microsoft Azure 云中的节点:

  1. 根据操作系统,下载 Chef 客户端可安装文件。在我们的案例中,我们使用 CentOS;因此,我们将从 downloads.chef.io/chef-client/redhat/ 下载 Chef 客户端的 Red Hat 版本。

  2. 选择操作系统类型。

  3. 选择 Chef 客户端版本。

  4. 下载安装文件。

Chef-dk 或 Chef 开发工具包用于安装开发工具,也可用于安装 AWS 和 Microsoft Azure 的 knife 插件。请从 downloads.chef.io/chef-dk/ 下载。这将帮助我们安装 knife-ec2knife-azure 插件,以便在云环境中创建和管理虚拟机。

一旦 Chef 客户端和 Chef 开发工具包的可安装文件准备好,并且托管 Chef 帐户也可用,就可以开始安装和配置 Chef 工作站。让我们在下一节中进行。

安装并配置 Chef 工作站

让我们验证是否在我们希望配置 Chef 工作站的系统或虚拟机上安装了 Chef 客户端:

  1. 执行 chef-client -version 命令;如果出现命令未找到的错误,说明 Chef 客户端没有安装。如果 Chef 客户端已安装,它将显示版本号:
 [mitesh@devops1 Desktop]$ chef-client -version
 bash: chef-client: command not found

  1. 转到下载 Chef 客户端安装包的目录:
 [mitesh@devops1 Desktop]$ cd chef/
 [mitesh@devops1 chef]$ ls
 chef-12.9.41-1.el6.x86_64.rpmchefdk-0.13.21-
        1.el6.x86_64.rpm

  1. 使用 rpm -ivh chef-<version>.rpm 来运行 Chef 客户端 RPM:
 [mitesh@devops1 chef]$ rpm -ivh chef-12.9.41-   
        1.el6.x86_64.rpm warning: chef-12.9.41-1.el6.x86_64.rpm: Header 
        V4DSA/SHA1 Signature, key ID 83ef826a: NOKEY error: can't create transaction lock on 
        /var/lib/rpm/.rpm.lock (Permission   
        denied)

  1. 如果在安装 Chef RPM 时权限被拒绝,请使用 sudo 来运行命令:
 [mitesh@devops1 chef]$ sudo rpm -ivh chef-12.9.41-
        1.el6.x86_64.rpm
 [sudo] password for mitesh:
 warning: chef-12.9.41-1.el6.x86_64.rpm: Header 
        V4DSA/SHA1 Signature, key ID 
        83ef826a: NOKEY
 Preparing...                
        ########################################### [100%]
 1:chef                   
        ########################################### [100%]
 Thank you for installing Chef!

  1. 安装成功后,验证 Chef 客户端版本,这时我们将获得 Chef 客户端的版本号:
 [mitesh@devops1 chef]$ chef-client -version
 Chef: 12.9.41

现在我们将使用在托管 Chef 创建帐户时下载的 Chef 启动工具包:

  1. 解压 chef-repo。将 .chef 目录复制到根目录或用户文件夹:

  1. 验证 chef-repo 目录下是否有 cookbooks 文件夹:

  1. .chef 文件夹中,用编辑器打开 knife.rb 文件,该文件包含各种配置。如果需要,修改 cookbooks 目录的路径:
        current_dir = File.dirname(__FILE__)
        log_level                :info
        log_locationSTDOUT
        node_name"discovertechno51"
        client_key"#{current_dir}/discovertechno51.pem"
        validation_client_name"dtechno-validator"
        validation_key"#{current_dir}/dtechno-validator.pem"
        chef_server_url"https://api.chef.io/organizations/dtechno"
        cookbook_path            ["#{current_dir}/../cookbooks"]

完成后,我们已经配置好了 Chef 工作站。下一步是使用它来合并节点。

使用 Chef 工作站合并 Chef 节点

在本节中,我们将使用 Chef 工作站在节点(物理/虚拟机)上设置运行时环境。

登录到 Chef 工作站:

  1. 打开终端并通过执行 ifconfig 命令来验证 IP 地址:
 [root@devops1 chef-repo]#ifconfig
 eth3      Link encap:EthernetHWaddr00:0C:29:D9:30:7F
 inetaddr:192.168.1.35Bcast:192.168.1.255Mask:255.255.255.0
 inet6addr: fe80::20c:29ff:fed9:307f/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST  MTU:1500Metric:1
 RX packets:841351errors:0dropped:0overruns:0frame:0
 TX packets:610551errors:0dropped:0overruns:0carrier:0
 collisions:0txqueuelen:1000
 RX bytes:520196141 (496.0 MiB)
                  TX bytes:278125183 (265.2 MiB)
 lo        Link encap:Local Loopback 
 inetaddr:127.0.0.1Mask:255.0.0.0
 inet6addr: ::1/128 Scope:Host
 UP LOOPBACK RUNNING  MTU:65536Metric:1
 RX packets:1680errors:0dropped:0overruns:0frame:0
 TX packets:1680errors:0dropped:0overruns:0carrier:0
 collisions:0txqueuelen:0
 RX bytes:521152 (508.9 KiB)  TX bytes:521152 (508.9 KiB)

  1. 使用 knife --version 验证在 Chef 工作站上安装的 knife 版本:
 [root@devops1 chef]#knife --version
 Chef: 12.9.41

  1. knife node list 命令用于获取由 Chef 服务器(在我们的情况下是托管 Chef)提供的节点列表。由于我们还没有合并任何节点,列表将为空:
 [root@devops1 chef-repo]#knife node list

  1. 使用 VMware Workstation 或 VirtualBox 创建虚拟机。安装 CentOS。一旦虚拟机准备就绪,找到其 IP 地址并记录下来。

  2. 在 Chef 工作站上,打开终端,并使用ssh命令尝试连接到我们刚刚创建的节点或虚拟机:

 [root@devops1 chef-repo]#sshroot@192.168.1.37
 The authenticity of the host 192.168.1.37 can't be established:
 RSA key fingerprint is 
        4b:56:28:62:53:59:e8:e0:5e:5f:54:08:c1:0c:1e:6c.
 Are you sure you want to continue connecting (yes/no)? yes
 Warning: Permanently added '192.168.1.37' (RSA)
        to the list of known hosts.
 root@192.168.1.37's password:
 Last login: Thu May 28 10:26:06 2015 from 192.168.1.15

  1. 现在我们已经通过 Chef 工作站在节点上建立了 SSH 会话。如果你验证 IP 地址,你会知道你正在通过远程(SSH)访问不同的机器:
 [root@localhost ~]#ifconfig
 eth1      Link encap:EthernetHWaddr00:0C:29:44:9B:4B
 inetaddr:192.168.1.37Bcast:192.168.1.255Mask:255.255.255.0
 inet6addr: fe80::20c:29ff:fe44:9b4b/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST  MTU:1500Metric:1
 RX packets:11252errors:0dropped:0overruns:0frame:0
 TX packets:6628errors:0dropped:0overruns:0carrier:0
 collisions:0txqueuelen:1000
 RX bytes:14158681 (13.5 MiB)  TX bytes:466365 (455.4 KiB)
 lo        Link encap:Local Loopback 
 inetaddr:127.0.0.1Mask:255.0.0.0
 inet6addr: ::1/128 Scope:Host
 UP LOOPBACK RUNNING  MTU:65536Metric:1
 RX packets:59513errors:0dropped:0overruns:0frame:0
 TX packets:59513errors:0dropped:0overruns:0carrier:0
 collisions:0txqueuelen:0
 RX bytes:224567119 (214.1 MiB)
                  TX bytes:224567119 (214.1 MiB)
 [root@localhost ~]#

  1. 使用 knife 收敛节点。提供 IP 地址/DNS 名称、用户、密码和节点名称。

  2. 验证输出:

 [root@devops1 chef-repo]# knife bootstrap 
        192.168.1.37 -x root -P cloud@123 -
        N tomcatserver
 Doing old-style registration with the validation    
        key at /home/mitesh/chef-               
        repo/.chef/dtechno-validator.pem...
 Delete your validation key in order to use your 
        user credentials instead
 Connecting to 192.168.1.37
 192.168.1.37 -----> Installing Chef Omnibus (-v 12)
 192.168.1.37 downloading
        https://omnitruck-direct.chef.io/chef/install.sh
 192.168.1.37   to file /tmp/install.sh.26574/install.sh
 192.168.1.37 trying wget...
 192.168.1.37 el 6 x86_64
 192.168.1.37 Getting information for chef stable 12 for el...
 192.168.1.37 downloading https://omnitruck-
        direct.chef.io/stable/chef/metadata?v=12&p=el&pv=6&m=x86_64
 192.168.1.37   to file /tmp/install.sh.26586/metadata.txt
 192.168.1.37 trying wget...
 192.168.1.37 sha1859bc9be9a40b8b13fb88744079ceef1832831b0
 192.168.1.37   
        sha256c43f48e5a2de56e4eda473a3e
        e0a80aa1aaa6c8621d9084e033d8b9cf3efc328 
 192.168.1.37 urlhttps://packages.chef.io/stable/el/6/chef-12.9.41-
        1.el6.x86_64.rpm
 192.168.1.37 version12.9.41
 192.168.1.37 downloaded metadata file looks valid...
 192.168.1.37 downloading 
        https://packages.chef.io/stable/el/6/chef-12.9.41-
        1.el6.x86_64.rpm
 192.168.1.37   to file /tmp/install.sh.26586/chef-
        12.9.41-1.el6.x86_64.rpm
 192.168.1.37 trying wget...
 192.168.1.37 Comparing checksum with sha256sum...
 192.168.1.37 Installing chef 12
 192.168.1.37 installing with rpm...
 192.168.1.37 warning: /tmp/install.sh.26586/chef-
        12.9.41-1.el6.x86_64.rpm:      
        Header V4DSA/SHA1 Signature, key ID 83ef826a: NOKEY
 192.168.1.37 Preparing...                ########################################### [100%]
 192.168.1.37    1:chef                  
              ########################################### [100%]
 192.168.1.37 Thank you for installing Chef!
 192.168.1.37 Starting the first Chef Client run...
 192.168.1.37 Starting Chef Client, version 12.9.41
 192.168.1.37 Creating a new client identity for 
        tomcatserver using the validator key.
 192.168.1.37 resolving cookbooks for run list: []
 192.168.1.37 Synchronizing Cookbooks:
 192.168.1.37 Installing Cookbook Gems:
 192.168.1.37 Compiling Cookbooks...
 192.168.1.37 [2016-05-12T23:47:49-07:00] WARN: 
        Node tomcatserver has an empty 
        run list.
 192.168.1.37 Converging 0 resources
 192.168.1.37
 192.168.1.37 Running handlers:
 192.168.1.37 Running handlers complete
 192.168.1.37 Chef Client finished, 0/0 resources 
        updated in 37 seconds

  1. 节点收敛成功:

    1. 在日志中验证第一次 Chef 客户端运行。

    2. 验证已安装的 Chef 客户端版本。

    3. 在日志中验证空运行列表消息。

    4. 验证 0 资源消息的收敛。

  2. 我们可以通过访问托管的 Chef 帐户并验证“节点名称”和“IP 地址”是否在“节点”部分中可用,来检查前面的过程是否成功。

  3. 在仪表板中,转到“详细信息”标签以获取有关节点的更多信息;验证与节点相关的属性以及权限:

  1. 在托管的 Chef 仪表板的底部部分,验证节点的 CPU 属性和其他详细信息。

  2. 报告部分提供了关于运行摘要、运行持续时间和运行计数的详细信息:

在下一部分,我们将尝试使用 Chef 安装 Tomcat。

使用食谱安装软件包

到目前为止,我们已经完成了以下任务:

  • 创建托管的 Chef 帐户

  • 配置 Chef 工作站

  • 使用 Chef 工作站收敛节点

现在我们将使用社区食谱安装应用程序包。

为了自动设置运行时环境,最好使用 Chef 社区的食谱:

  1. 访问github.com/chef-cookbooks,并查找设置运行时环境所需的所有社区食谱。

  2. 我们使用的是一个示例 Spring 应用程序,即 PetClinic。我们需要安装 Java 和 Tomcat 来运行像这样的 Java EE 应用程序。

  3. supermarket.chef.io/cookbooks/tomcat下载 Tomcat 食谱,并导航到该页面的依赖项部分。如果依赖项没有上传到 Chef 服务器,我们就无法上传 Tomcat 食谱并使用它。

  4. supermarket.chef.io/cookbooks/opensslsupermarket.chef.io/cookbooks/chef-sugar下载 OpenSSL 和 Chef sugar。

  5. 要安装 Java,下载supermarket.chef.io/cookbooks/java上的食谱及其依赖项,还需要从supermarket.chef.io/cookbooks/apt下载。将所有压缩文件解压到食谱的目录中:

  1. 转到终端中的食谱目录并执行ls命令,验证我们之前下载的社区食谱的子目录:
 [root@devops1 cookbooks]# ls
 apt  chefignore  chef-sugar  java  openssl  starter  tomcat
 [root@devops1 cookbooks]# cd ..

  1. 让我们上传其中一个食谱并验证它是否已上传到托管 Chef 上。使用knife cookbook upload apt命令上传 apt 食谱,如下所示:
 [root@devops1 chef-repo]# knife cookbook upload apt
 Uploading apt          [3.0.0]
 Uploaded 1 cookbook.

  1. 进入托管 Chef 仪表板并点击“策略”。进入托管 Chef 实例中的“食谱”部分,查看 apt 食谱是否已上传:

  1. 我们需要上传所有依赖项的食谱,以便 Tomcat 食谱能够上传,否则它会给我们报错。按顺序上传所有其他食谱:
 [root@devops1 chef-repo]# knife cookbook upload chef-sugar
 Uploading chef-sugar     [3.3.0]
 Uploaded 1 cookbook.
 [root@devops1 chef-repo]# knife cookbook upload java
 Uploading java           [1.39.0]
 Uploaded 1 cookbook.
 [root@devops1 chef-repo]# knife cookbook upload openssl
 Uploading openssl        [4.4.0]
 Uploaded 1 cookbook.
 [root@devops1 chef-repo]# knife cookbook upload tomcat
 Uploading tomcat         [0.17.0]
 Uploaded 1 cookbook.

  1. 进入托管 Chef 仪表板并验证所有食谱:

一旦我们将所有食谱上传到托管 Chef,让我们创建一个角色。

创建角色

在这个阶段,所有必需的食谱已上传到托管 Chef。现在,让我们在托管 Chef 上创建一个角色。

在创建角色之前,让我们了解一下它的含义。

角色是为特定功能创建的。它为各种模式和工作流过程提供了一条路径。

例如,Web 服务器角色可以包含 Tomcat 服务器食谱和任何自定义属性:

  1. 进入托管 Chef 仪表板中的“策略”并点击侧边菜单中的“角色”。点击“创建角色”以创建一个角色。

  2. 在创建角色窗口中,提供一个名称和描述

  3. 点击“下一步”。

请参考以下截图:

  1. 运行列表以特定的方式和顺序保存角色/食谱。它可以被认为是节点的规范。

  2. 从“可用食谱”列表中选择 Tomcat。

  3. 将 Tomcat 食谱拖到当前运行列表中。

  4. 点击“创建角色”。

请参考以下截图:

  1. 在托管 Chef 仪表板的“策略”选项卡中检查新添加的角色:

  1. 现在,让我们在终端中合并节点时指定一个角色。使用knife node run_list add tomcatserver "role[v-tomcat]"将角色添加到节点:
 [root@devops1 chef-repo]# knife node run_list add 
        tomcatserver "role[v-tomcat]"
 tomcatserver:
 run_list: role[v-tomcat]
 [root@devops1 chef-repo]#

  1. v-tomcat角色现在与tomcatserver节点相关联。

  2. 进入节点并执行chef-client;它将执行步骤,使节点状态与分配的角色保持一致:

 [root@localhost Desktop]# chef-client
 Starting Chef Client, version 12.9.41
 resolving cookbooks for run list: ["tomcat"]
 Synchronizing Cookbooks:
 - tomcat (0.17.0)
 - chef-sugar (3.3.0)
 - java (1.39.0) 
 - apt (3.0.0)
 - openssl (4.4.0)
 Installing Cookbook Gems:
 Compiling Cookbooks...
 .
 .
 .
 Chef Client finished, 11/15 resources updated in 09 minutes 59 
        seconds
 You have new mail in /var/spool/mail/root

  1. 进入节点并检查 Tomcat 是否可用:
 [root@localhost Desktop]# service tomcat6 status
 tomcat6 (pid 39782) is running...                          [  OK  ]
 You have new mail in /var/spool/mail/root

  1. 进入托管 Chef 账户中的“报告”选项卡,获取节点合并的最新详情:

在这个阶段,我们已经准备好了一个托管的 Chef 账户、配置好的工作站和已合并的节点。

在接下来的部分中,我们将为一些流行的云平台安装 knife 插件。

为 Amazon Web Services 和 Microsoft Azure 安装 knife 插件

我们的目标是安装应用程序包,以为我们的基于 Java 的 Petclinic 应用程序提供运行时环境。在传统环境中,我们需要提出物理服务器的获取请求,然后基础设施团队帮助我们在其上安装不同的软件,提供应用程序的运行时环境。通过 Chef,我们可以使用社区食谱安装这些包,从而轻松实现自动化。

在本节中,我们将使用云资源。Amazon EC2 和 Microsoft Azure 是两个非常受欢迎的公共云资源提供商。我们将在云环境中创建虚拟机,然后使用 Chef 配置管理工具安装不同的应用程序包:

  1. 首先,我们将使用 Chef 工作站和 knife 插件在 Amazon EC2 和 Microsoft Azure 中配置虚拟机。

  2. 进入 Chef 工作站。

  3. 执行knife命令在 Amazon EC2 和 Microsoft Azure 中创建实例(Chef 节点)。

以下是该过程的工作流程:

  1. 在 Chef 工作站上执行命令,以在云环境中创建新实例。

  2. 在 Amazon EC2 和 Microsoft Azure 中创建了一个新实例,并且它已经启动并运行(Chef 节点可用)。

  3. Chef 节点与 Chef 服务器进行通信。

  4. Chef 服务器指示 Chef 节点执行任务列表并下载 Chef 客户端。

  5. Chef 服务器和 Chef 节点之间会进行安全握手;Chef 服务器生成安全证书,用于验证新节点即将发出的查询。

  6. Chef 节点执行任务并向 Chef 服务器报告其合规性。

使用 Chef 配置管理工具与不同公共云服务提供商的主要好处如下:

  • 更快的市场推出时间

  • 集中控制

  • 标准策略

  • 部署应用程序的一致环境

  • 更少或没有手动操作和由于手动限制产生的错误

  • 快速应用开发

  • 轻松回滚

  • 高可用性和灾难恢复,确保在当今时代的商业连续性

  • 可供所有人访问的社区食谱

Chef 开发工具包ChefDK)提供了由 Chef 社区构建的开发工具,简化了 knife 插件的安装。

访问downloads.chef.io/chef-dk/并根据我们使用的操作系统下载 ChefDK。

在我们的案例中,选择 Red Hat Enterprise Linux 并选择 ChefDK 版本。点击 Red Hat Enterprise Linux 6 并下载,因为它适用于 64 位(x86_64)版本的 Red Hat Enterprise Linux 和 CentOS 6:

[root@localhost Desktop]# sudo rpm -ivh chefdk-0.13.21-1.el6.x86_64.rpm
Preparing...                ###########################################    [100%]   1:chefdk                 ###########################################    [100%]
Thank you for installing Chef Development Kit!

执行chef gem install knife-ec2命令来创建、启动和管理 Amazon EC2 实例。更多详情请访问github.com/chef/knife-ec2

[root@localhost Desktop]# chef gem install knife-ec2
Fetching: knife-ec2-<version>.gem (100%)
.
.
Successfully installed knife-ec2-<version>
1 gem installed

执行knife ec2 --help命令查看可用的 Amazon EC2 命令:

[root@localhost Desktop]# knife ec2 --help

** EC2 COMMANDS **
knife ec2 amis ubuntu DISTRO [TYPE] (options)
knife ec2 flavor list (options)
knife ec2 server create (options)
knife ec2 server delete SERVER [SERVER] (options)
knife ec2 server list (options)

knife.rb文件中配置 Amazon EC2 凭证以供knife插件使用。

使用knife[:aws_access_key_id]knife[:aws_secret_access_key],如示例所示:

knife[:aws_access_key_id] = "Your AWS Access Key ID"
knife[:aws_secret_access_key] = "Your AWS Secret Access Key"

执行chef gem install knife-azure命令来创建、启动和管理 Microsoft Azure 虚拟机。更多详情请访问github.com/chef/knife-ec2

[root@localhost Desktop]# chef gem install knife-azure -v 1.5.2
Fetching: knife-azure-1.5.2.gem (100%)

Successfully installed knife-azure-1.5.2
1 gem installed

使用knife azure --help验证可用的 Azure 命令:

[root@localhost Desktop]# knife azure --help

** AZURE COMMANDS **
knife azure ag create (options)
knife azure ag list (options)
knife azure image list (options)
knife azure internal lb create (options)
knife azure internal lb list (options)
knife azure server create (options)
knife azure server delete SERVER [SERVER] (options)
knife azure server list (options)
knife azure server show SERVER [SERVER]
knife azure vnet create (options)
knife azure vnet list (options)

在 Amazon EC2 中创建和配置虚拟机

使用knife node list命令获取节点列表,以便了解通过 Chef 已配置了多少个节点:

root@devops1 Desktop]# knife node list
tomcatserver

使用knife ec2 server create命令并带上以下参数来创建新的虚拟机:

参数 描述
-I ami-1ecae776 这是 Amazon 镜像 ID
-f t2.micro 这是虚拟机的类型
-N DevOpsVMonAWS 这是 Chef 节点的名称
--aws-access-key-id 您的访问密钥 ID 这是 AWS 账户的访问密钥 ID
--aws-secret-access-key 您的秘密访问密钥 这是 AWS 账户的秘密访问密钥
-S Book 这是 SSH 密钥
--identity-file book.pem 这是 PEM 文件
--ssh-user ec2-user 这是 AWS 实例的用户
-r role[v-tomcat] 这是 Chef 角色

让我们使用 knife 插件创建一个 EC2 实例:

[root@devops1 Desktop]# knife ec2 server create -I ami-1ecae776 -f t2.micro -N DevOpsVMonAWS --aws-access-key-id '< Your Access Key ID >' --aws-secret-access-key '< Your Secret Access Key >' -S book --identity-file book.pem --ssh-user ec2-user -r role[v-tomcat] 

Instance ID: i-640d2de3
Flavor: t2.micro
Image: ami-1ecae776
Region: us-east-1
Availability Zone: us-east-1a
Security Groups: default
Tags: Name: DevOpsVMonAWS
SSH Key: book

Waiting for EC2 to create the instance......
Public DNS Name: ********************.compute-1.amazonaws.com
Public IP Address: **.**.***.***
Private DNS Name: ip-***-**-1-27.ec2.internal
Private IP Address: ***.**.*.27

此时,AWS EC2 实例已经创建,并处于 等待 sshd 访问变为可用 状态:


Waiting for sshd access to become available....................done 

Creating new client for DevOpsVMonAWS
Creating new node for DevOpsVMonAWS
Connecting to ec2-**-**-***-***.compute-1.amazonaws.com

ec2-**-**-***-***.compute-1.amazonaws.com -----> Installing Chef Omnibus (-v 12)
.
.
ec2-**-**-***-***.compute-1.amazonaws.com version12.9.41
ec2-**-**-***-***.compute-1.amazonaws.com downloaded metadata file looks valid...
ec2-**-**-***-***.compute-1.amazonaws.com downloading https://packages.chef.io/stable/el/6/chef-12.9.41-1.el6.x86_64.rpm
ec2-**-**-***-***.compute-1.amazonaws.com    1:chef-12.9.41-1.el6               ################################# [100%]

ec2-**-**-***-***.compute-1.amazonaws.com Thank you for installing Chef! 

现在,Chef 客户端已经安装在 AWS 实例上,准备进行第一次 Chef Client run,版本为 12.9.41

ec2-**-**-***-***.compute-1.amazonaws.com Starting the first Chef Client run...
ec2-**-**-***-***.compute-1.amazonaws.com Starting Chef Client, version 12.9.41

它现在准备好根据角色解析 cookbook 并安装运行时环境:

ec2-**-**-***-***.compute-1.amazonaws.com resolving cookbooks for run list: ["tomcat"] 
ec2-**-**-***-***.compute-1.amazonaws.com Synchronizing Cookbooks:
ec2-**-**-***-***.compute-1.amazonaws.com   - tomcat (0.17.0)
ec2-**-**-***-***.compute-1.amazonaws.com   - java (1.39.0)
ec2-**-**-***-***.compute-1.amazonaws.com   - apt (3.0.0)
ec2-**-**-***-***.compute-1.amazonaws.com   - openssl (4.4.0)
ec2-**-**-***-***.compute-1.amazonaws.com   - chef-sugar (3.3.0)

ec2-**-**-***-***.compute-1.amazonaws.com Installing Cookbook Gems:
ec2-**-**-***-***.compute-1.amazonaws.com Compiling Cookbooks...

ec2-**-**-***-***.compute-1.amazonaws.com Converging 3 resources
ec2-**-**-***-***.compute-1.amazonaws.com Recipe: tomcat::default
ec2-**-**-***-***.compute-1.amazonaws.com   * yum_package[tomcat6] action install
ec2-**-**-***-***.compute-1.amazonaws.com     - install version 6.0.45-1.4.amzn1 of package tomcat6
ec2-**-**-***-***.compute-1.amazonaws.com   * yum_package[tomcat6-admin-webapps] action install
ec2-**-**-***-***.compute-1.amazonaws.com     - install version 6.0.45-1.4.amzn1 of package tomcat6-admin-webapps
ec2-**-**-***-***.compute-1.amazonaws.com   * tomcat_instance[base] action configure (up to date)

现在运行环境已准备好,可以在 AWS 实例中启动 Tomcat 服务;请验证日志:

ec2-**-**-***-***.compute-1.amazonaws.com 
ec2-**-**-***-***.compute-1.amazonaws.com   * service[tomcat6] action start
.
.
ec2-**-**-***-***.compute-1.amazonaws.com Chef Client finished, 13/15 resources updated in 01 minutes 13 seconds

以下是新创建的 AWS 实例的详细信息:

Instance ID: i-********
Flavor: t2.micro
Image: ami-1ecae776
Region: us-****-1
Availability Zone: us-****-1a
Security Groups: default
Security Group Ids: default
Tags: Name: DevOpsVMonAWS
SSH Key: book
Root Device Type: ebs
Root Volume ID: vol-1e0e83b5
Root Device Name: /dev/xvda
Root Device Delete on Terminate: true
Public DNS Name: ec2-**-**-***-***.compute-1.amazonaws.com
Public IP Address: 52.90.219.205
Private DNS Name: ip-172-31-1-27.ec2.internal
Private IP Address: 172.31.1.27
Environment: _default
Run List: role[v-tomcat]
You have new mail in /var/spool/mail/root
[root@devops1 Desktop]#

访问 aws.amazon.com/ 并登录。

转到 Amazon EC2 部分,在左侧边栏点击“实例”,或在资源页面的“正在运行的实例”部分查看 AWS 实例的详细信息。

验证在 Chef 客户端运行中获得的名称、标签、公共 DNS 以及其他详细信息,和 Amazon 仪表盘上的信息是否一致:

现在,让我们进入托管的 Chef 仪表盘,点击“节点”来验证在 Amazon EC2 中新创建/合并的节点:

验证实例详细信息和运行列表:

在 Amazon EC2 中创建了一个实例并安装了 Tomcat,且其服务也已启动,我们可以验证它是否真的在运行。

让我们尝试通过实例的公共域名访问安装在 AWS 实例上的 Tomcat 服务器:

  1. 如果出现连接超时错误,那么原因可能是 AWS 安全组的限制。请进入 AWS 实例中的安全组:

  1. 在 AWS 门户中,转到安全组部分,选择默认安全组,验证入站规则。我们可以看到只有 SSH 规则可用;我们需要允许端口 8080 以便访问:

  1. 让我们创建一个新的自定义规则,开放 8080 端口:

  1. 现在,尝试访问公共域名 URL,我们将在 AWS 实例上看到 Tomcat 页面。

在接下来的部分中,我们将创建并配置一个 Microsoft Azure 的虚拟机。

在 Microsoft Azure 中创建和配置虚拟机

要创建和配置 Chef 与 Microsoft Azure 的集成,我们需要提供 Microsoft Azure 账户和凭证。要获取 Microsoft Azure 凭证,请下载 publishsettings 文件并执行以下步骤:

  1. 使用登录名和密码登录 Microsoft Azure 门户,并从 manage.windowsazure.com/publishsettings/index?client=xplat 下载 publishsettings 文件。

  2. 将其复制到 Chef 工作站,并通过在 knife.rb 文件中创建条目来引用该本地文件:

        knife[:azure_publish_settings_file] = "~/<name>.publishsettings"

  1. 以下是创建 Microsoft Azure 公共云中虚拟机的参数:
参数 描述
--azure-dns-name distechnodemo 这是 DNS 名称
--azure-vm-name dtserver02 这是虚拟机的名称
--azure-vm-size Small 这是虚拟机的大小
-N DevOpsVMonAzure2 这是 Chef 节点的名称
--azure-storage-account classicstorage9883 这是 Azure 的存储账户
--bootstrap-protocol cloud-api 这是启动协议
--azure-source-image 5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-67-20160310 这是 Azure 源镜像的名称
--azure-service-location Central US 这是虚拟机托管的 Azure 地理位置
--ssh-user dtechno 这是 SSH 用户
--ssh-password <YOUR PASSWORD> 这是 SSH 密码
-r role[v-tomcat] 这是角色
--ssh-port 22 这是 SSH 端口

我们已经成功安装了 knife azure 插件。现在,我们可以通过执行以下命令来创建 Microsoft Azure Cloud 中的虚拟机:knife azure server create

[root@devops1 Desktop]# knife azure server create --azure-dns-name 'distechnodemo' --azure-vm-name 'dtserver02' --azure-vm-size 'Small' -N DevOpsVMonAzure2 --azure-storage-account 'classicstorage9883' --bootstrap-protocol 'cloud-api' --azure-source-image '5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-67-20160310' --azure-service-location 'Central US' --ssh-user 'dtechno' --ssh-password 'cloud@321' -r role[v-tomcat] --ssh-port 22 
.
.
.
Creating new node for DevOpsVMonAzure2
.........
Waiting for virtual machine to reach status 'provisioning'..............vm state 'provisioning' reached after 2.47 minutes.
..

DNS Name: distechnodemo.cloudapp.net
VM Name: dtserver02
Size: Small
Azure Source Image: 5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-67-20160310
Azure Service Location: Central US
Private Ip Address: 100.73.210.70
Environment: _default

Runlist: ["role[v-tomcat]"]

现在,我们将从 Microsoft Azure 公共云的资源配置开始:

Waiting for Resource Extension to reach status 'wagent provisioning'.....Resource extension state 'wagent provisioning' reached after 0.17 minutes.

Waiting for Resource Extension to reach status 'installing'....................Resource extension state 'installing' reached after 2.21 minutes.
Waiting for Resource Extension to reach status 'provisioning'.....Resource extension state 'provisioning' reached after 0.19 minutes.
..
DNS Name: distechnodemo.cloudapp.net
VM Name: dtserver02
Size: Small
Azure Source Image: 5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-67-20160310
Azure Service Location: Central US
Private Ip Address: 100.73.210.70
Environment: _default
Runlist: ["role[v-tomcat]"]
[root@devops1 Desktop]#

  1. 在浏览器中打开托管的 Chef 账户,并点击 Nodes 标签。

  2. 验证我们在 Microsoft Azure 公共云上创建的新节点是否已在托管的 Chef 服务器上注册。

  3. 我们可以看到 DevOpsVMonAzure2 节点名称:

  1. 转到 Microsoft Azure 门户并点击虚拟机(VIRTUAL MACHINES)部分,验证使用 Chef 配置管理工具创建的新虚拟机:

  1. 点击 Microsoft Azure 仪表板中的虚拟机(VIRTUAL MACHINES),并验证虚拟机的详细信息:

  1. 滚动到虚拟机页面底部,验证扩展部分。

  2. 检查是否显示启用了 chef-service:

我们现在已经使用安装的运行时环境和角色,通过 knife 插件在 Amazon EC2 和 Microsoft Azure 中创建了虚拟机。

总结

在本章中,我们安装并配置了 Chef 工作站,合并了节点,创建了角色,并安装了基于 Java 的 Web 应用程序的运行时环境。我们还使用了 knife 插件在 Microsoft Azure 和 Amazon EC2 上创建虚拟机,并使用角色安装运行时环境。

在下一章,我们将看到如何使用脚本或插件以自动化的方式将基于 Java 的 Web 应用程序部署到 Web 服务器中。

我们将把我们的 WAR 文件部署到本地或远程的 Tomcat。远程 Tomcat 将部署在 Amazon EC2、Microsoft Azure 虚拟机、AWS Elastic Beanstalk 或 Microsoft Azure Web Apps 上。

第五章:持续交付

技术并不重要。重要的是你要相信人们,他们本质上是善良和聪明的,如果你给他们工具,他们会用这些工具做出奇妙的事情。                                                                                                                              - 史蒂夫·乔布斯

我们已经了解了不同的 DevOps 实践,如持续集成、容器化和配置管理。接下来,我们将了解如何将包文件部署到 Web 容器或 Web 服务器。我们将使用 Apache Tomcat 作为 Web 服务器,在云虚拟机中部署我们的 Java 应用程序。

本章的主要目标是让你了解不同的应用包部署到 Web 服务器的方式。这些方式可以根据团队可用的访问权限来选择,一旦我们实现了向 Web 服务器的自动化交付,我们就可以在整体构建流程中使用这个操作。

因此,我们可以创建一个构建管道,这种协调将帮助我们实现持续交付和持续部署。

本章将涵盖以下主题:

  • 使用 Jenkins 插件在 Docker 容器中实现持续交付

  • 使用脚本在 AWS EC2 和 Microsoft Azure 虚拟机中实现持续交付

  • 使用 Jenkins 插件在 AWS Elastic Beanstalk 中实现持续交付

  • 使用 FTP 在 Microsoft Azure 应用服务中实现持续交付

  • 使用 VSTS 在 Microsoft Azure 应用服务中实现持续交付

使用 Jenkins 插件在 Docker 容器中实现持续交付

让我们了解如何使用 Jenkins 插件在 Tomcat 中部署 Web 应用程序。

我们可以按照以下几个步骤操作:

  • 运行 Apache Tomcat

  • 使用正确的 IP 地址和端口号组合访问 Tomcat 首页:

  • 进入 conf 目录,然后在 Tomcat 安装目录中打开 tomcat-users.xml 文件,取消注释角色和用户行,或者重新编写它们。为了测试目的,将 rolename 设置为 manager-script。我们需要 manager-script 来通过 Deploy to Container 插件进行部署。

  • 对于 Jenkins 部署插件,将 rolename 更改为 manager-script,如下所示:

  • 点击 Tomcat 首页上的管理应用程序链接,并输入你在 tomcat-users.xml 中设置的用户名和密码。现在我们可以访问管理应用程序。对于本地 Tomcat,我们可以使用 localhost 访问 Tomcat 页面,或者也可以使用 IP 地址。对于远程 Web 服务器,我们可以利用 IP 地址或域名来访问 Tomcat。

  • 重启 Tomcat 并访问 https://<IP 地址>:8080/manager/text/list。你应该看到以下输出:

        OK - Listed applications for virtual host localhost 
        /:running:0:ROOT 
        /petclinic:running:1:petclinic 
        /examples:running:0:examples 
        /host-manager:running:0:host-manager 
        /manager:running:0:manager 
        /docs:running:0:docs 

  • 进入 Jenkins 作业构建页面并点击配置(Configure)。选择适当的 JDK 配置用于 Jenkins 代理:

  • 在构建后操作中,选择将 war/ear 部署到容器中。提供 Jenkins 工作区中 WAR 文件的位置、Tomcat 管理凭证以及带端口的 Tomcat URL:

  • 点击应用并保存。在 Jenkins 构建页面点击立即构建。验证控制台输出显示新的部署:

  • 一旦构建成功,从浏览器访问 URL,并注意到上下文。它与应用程序的名称类似:

我们已经了解了 Docker 中可用的基本操作,因为我们在第三章中讲解了容器。我们已经创建了一个自定义的 Tomcat 镜像,并且配置了tomcat-users.xml

一旦 Docker 启动并运行,我们就准备好创建一个 Docker 容器了。请注意以下图像中默认 Docker 机器的 IP 地址:

  • 要更改容器的名称,使用:
        docker run -it -p 9999:8080 --name bootcamp_tomcat     devops_tomcat_sc  

  • 使用以下方式验证名称:
        dockerps -a  

  • 使用虚拟机 IP 地址,并使用 9999 作为端口号访问容器中运行的 Tomcat:

  • 使用以下 URL 验证manager-script角色的管理访问:

  • 让我们尝试使用 Tomcat 中的Deploy to Container插件部署应用。如果某个构建任务生成了 WAR 文件,则使用复制工件插件从该构建任务复制 WAR 文件:

  • 在构建后操作中,选择将 war/ear 部署到容器中。提供在tomcat-users.xml中设置的用户名和密码。然后我们将提供 Tomcat URL,如下所示。填写详细信息后,点击应用/保存:

  • 点击立即构建。

  • 进入控制台输出并验证部署过程:

  • 使用 Tomcat URL 和应用上下文验证应用程序 URL。

太棒了!!我们已经成功创建了一个镜像和一个容器,并在 Tomcat 容器中部署了应用程序。

使用脚本在 AWS EC2 和 Microsoft Azure 虚拟机中进行持续交付

我们已经在 AWS 和 Microsoft Azure 的虚拟机中创建了虚拟机。在 AWS 和 Microsoft Azure 虚拟机上部署应用程序时,我们需要一个 WAR 包文件。一旦它通过 Jenkins 构建任务创建,就需要执行以下步骤:

让我们配置构建任务,在 AWS 实例中通过执行如下命令来部署 WAR 文件:

  • ec2-user在 Tomcat 的webapps目录中赋予权限,以便我们可以复制 WAR 文件:
        ssh  -i /home/mitesh/book.pem -o StrictHostKeyChecking=no -t -t
        ec2-user@ec2-52-90-116-36.compute-1.amazonaws.com "sudousermod -a
        -G tomcat ec2-user;
        sudochmod -R g+w /var/lib/tomcat6/webapps; sudo service tomcat6
        stop;"  

  • 将 WAR 文件复制到远程目录:
        scp  -i /home/mitesh/book.pem /home/mitesh/target/*.war ec2-
        user@ec2-52-90-116-36.compute-
        1.amazonaws.com:/var/lib/tomcat6/webapps  

  • 启动/重启 Tomcat 服务:
        ssh  -i /home/mitesh/book.pem -o StrictHostKeyChecking=no -t -t
        ec2-user@ec2-52-90-116-36.compute-1.amazonaws.com "sudo service
        tomcat6 start"

使用Copy Artifact插件从另一个构建任务复制WAR文件,然后在执行 Shell 构建操作中执行前述命令:

点击保存,然后执行构建任务。对于 Microsoft Azure VM 的应用程序部署,利用 Jenkins 插件(Deploy to Container)或用于 AWS 的脚本,按需修改作为自我练习。

使用 Jenkins 插件在 AWS Elastic Beanstalk 中实现持续交付

AWS Elastic Beanstalk 是 Amazon 提供的 平台即服务PaaS)产品。我们将使用它在 AWS 平台上部署 PetClinic 应用程序。好处是我们不需要管理基础设施或平台,因为它是一个 PaaS 产品。我们可以配置扩展和其他细节。以下是在 AWS Elastic Beanstalk 上部署应用程序的步骤:

让我们创建一个示例应用程序,以了解 Elastic Beanstalk 是如何工作的,然后使用 Jenkins 插件来部署应用程序。

  • 进入 AWS 管理控制台,验证我们是否有默认的 虚拟私有云VPC)。如果你不小心删除了默认的 VPC 和子网,请向 AWS 客服请求重新创建:

  • 点击 AWS 管理控制台中的服务,并选择 AWS Elastic Beanstalk。创建一个名为 petclinic 的新应用程序。选择 Tomcat 作为平台,并选择示例应用程序单选按钮:

  • 验证创建示例应用程序的事件顺序:

  • 这将需要一段时间,一旦环境创建完成,它将以绿色突出显示,如图所示:

  • 点击 petclinic 环境并验证仪表板中的健康状态和运行版本:

  • 验证环境 ID 和 URL。点击 URL 并验证默认页面:

  • 安装 AWS Elastic Beanstalk Publisher 插件。

如需更多详细信息,请访问 wiki.jenkins-ci.org/display/JENKINS/AWS+Beanstalk+Publisher+Plugin

  • 打开 Jenkins 仪表板,进入构建任务。点击构建后操作并选择部署到 AWS Elastic Beanstalk:

  • 在构建后操作中会出现一个新的 Elastic Beanstalk 部分。

  • 点击 Jenkins 仪表板并选择凭证;添加你的 AWS 凭证。

  • 进入你的 Jenkins 构建并选择在全局配置中设置的 AWS 凭证。

  • 从列表中选择 AWS 区域并点击获取可用应用程序。由于我们已经创建了示例应用程序,它会像这样显示出来。

  • 在 EnvironmentLookup 中,在获取环境名称框中提供环境 ID 并点击获取可用环境:

  • 保存配置并点击立即构建。

现在让我们验证 AWS 管理控制台,检查 WAR 文件是否已被复制到 Amazon S3:

  • 进入 S3 服务并检查可用的存储桶:

  • 由于 WAR 文件较大,上传到 Amazon S3 会需要一些时间。一旦上传完成,它将在 Amazon S3 存储桶中可用。

  • 验证 Jenkins 中构建任务的执行状态。预期输出的某些部分包括:

    • 测试用例执行和 WAR 文件创建成功

    • 构建成功

  • 现在检查 AWS 管理控制台:

  • 转到服务,点击 AWS Elastic Beanstalk,验证环境。之前的版本是“示例应用”,现在版本已更新,按照 Jenkins 构建任务配置中的版本标签格式进行更新:

  • 转到仪表板,再次验证健康状况和正在运行的版本。

  • 一旦一切验证完毕,点击环境的 URL,我们的 PetClinic 应用就上线了:

  • 一旦应用部署成功,终止环境:

我们已经成功将应用部署到 Elastic Beanstalk 上。

使用 FTP 在 Microsoft Azure 应用服务中实现持续交付

Microsoft Azure 应用服务是 PaaS。在本节中,我们将看看 Azure Web 应用以及如何部署我们的 PetClinic 应用。

让我们在 Jenkins 中安装 Publish Over FTP 插件。我们将使用 Azure Web 应用的 FTP 详细信息来发布 PetClinic WAR 文件:

  • 转到 Microsoft Azure 门户 portal.azure.com,点击应用服务,然后点击“添加”。提供应用名称、订阅、资源组和应用服务计划/位置。点击“创建”:

  • 一旦 Azure Web 应用创建完成,查看是否能在 Azure 门户中显示。

  • 点击 DevOpsPetClinic,查看与 URL、状态、位置等相关的详细信息:

  • 点击“所有设置”,进入“常规”部分,点击“应用设置”以配置 Azure Web 应用用于 Java Web 应用托管。选择 Java 版本、Java 次版本、Web 容器和平台,然后点击“Always On”:

  • 从浏览器访问 Azure Web 应用的 URL,并验证它是否已经准备好托管我们的示例 Spring 应用——PetClinic:

  • 让我们转到 Jenkins 仪表板,点击“新建项目”,选择自由风格项目。

  • 点击“所有设置”,然后转到 PUBLISHING 部分中的部署凭证。提供用户名和密码,并保存更改:

  • 在 Jenkins 中,转到“管理 Jenkins”,点击“配置” | 配置 FTP 设置。提供 Azure 门户中可用的主机名、用户名和密码。

  • 转到 devopspetclinic.scm.azurewebsites.net 并下载 Kudu 控制台。导航到不同选项,找到 site directorywebapps 目录。

  • 点击“测试配置”,一旦看到成功消息,就可以准备部署 PetClinic 应用了:

  • 在我们创建的构建任务中,转到“构建”部分,配置从另一个项目复制构建产物。我们将 WAR 文件复制到虚拟机上的特定位置:

  • 在构建后操作中,点击通过 FTP 发送构建工件。选择在 Jenkins 中配置的 FTP 服务器名称。相应地配置源文件和删除前缀,以便部署 Azure Web App:

  • 勾选控制台中的详细输出:

  • 点击立即构建,看看幕后发生了什么:

  • 进入 Kudu 控制台,点击 DebugConsole,并进入 Powershell。进入 site | wwwroot | webapps。检查 WAR 文件是否已被复制:

  • 在浏览器中访问 Azure Web App URL,查看应用程序的上下文:

现在我们已经在 Azure Web Apps 上部署了一个应用程序。

需要注意的是,FTP 用户名必须包含域名。在我们的例子中,它可以是 Sample9888\m1253966。如果不包含 Web 应用名称,用户名将无法使用。

这些不同的 AWS IaaS、AWS PaaS、Microsoft Azure PaaS 和 Docker 容器部署方式都可以在最终的端到端自动化中使用。

在 Microsoft Azure App Services 中使用 VSTS 进行持续交付

Visual Studio Team Services 提供了一种配置持续集成和持续交付的方法。我们将首先进入我们的 VSTS 账户。在这里,我们需要完成以下任务:

  • 配置 Microsoft Azure 订阅,以便我们可以从 VSTS 连接到 Azure Web Apps。

  • 创建一个发布定义,实现 Azure Web Apps 中应用程序的部署任务。

在最近的项目和团队中,点击 PetClinic:

它将打开在 VSTS 中创建的项目的主页:

在顶部菜单栏中,点击 Build & Release,打开一个菜单。从中点击 Releases 菜单项:

点击页面上的 Releases 链接。

由于这是新账户,因此尚未创建任何发布定义,因此此部分为空。我们可以创建一个新的发布定义,以便自动化将应用程序部署到 Azure App Services 或 App Service Environment。

就像我们为持续集成构建了定义一样,我们也有针对持续发布、持续交付或持续部署的发布定义。发布定义包含不同的任务,这些任务可以用于将应用程序部署到目标环境中。每个发布定义包含一个或多个环境,每个环境包含一个或多个任务来部署应用程序。

接下来,让我们创建一个新的发布定义。每个发布定义可以包含一个或多个环境,每个环境可以包含一个或多个任务来部署应用程序。

点击新的定义:

一旦我们点击新的发布定义,它将打开一个对话框,展示可以用于部署自动化的部署模板。

我们将把 WAR 文件部署到 Azure App Service / Azure Web Apps,因此选择 Azure App Service 部署。

点击 Next:

在解释此部署自动化之前,让我们回顾一下前面章节中的几个内容。

我们创建了一个构建定义 PetClinic-Maven,它会编译源代码,执行单元测试并创建一个 WAR 文件。WAR 文件就是我们的工件。这个工件是构建定义执行的结果。

现在,在发布定义中,我们需要选择工件的来源,那就是来自构建。

选择 PetClinic 项目。

在源(构建定义)中,所有与 PetClinic 项目相关的构建定义将可用。我们将选择 PetClinic-Maven。

简而言之,我们想要在这里实现持续集成和持续交付。这意味着,当开发者在仓库中提交任何新的代码或修复时,它将自动触发构建定义。构建定义将编译源代码,执行单元测试(如果有的话),进行静态代码分析(如果配置了 Sonar),并生成一个 WAR/package 文件。这就是工件。一旦构建定义成功完成,它将触发发布定义,将工件或WAR文件部署到托管在 ASE 或非 ASE 环境中的 Azure Web 应用程序。

点击“持续部署(每当构建完成时创建发布并部署)”复选框。

点击“创建”:

这将打开发布定义的编辑模式。我们选择了“部署 Azure 应用服务”。第一个需要做的事情是将 Azure 订阅与 VSTS 配置。

点击任务,看到有两个字段,分别是 AzureRM 订阅和应用服务名称。我们需要在这里配置 Azure 订阅,应用服务名称将自动出现在列表中。

点击“管理”链接,位于 AzureRM 订阅字段旁边:

它将在 VSTS 门户中打开一个服务页面。目前没有配置任何服务,所以列表是空的:

点击“新建服务端点”。

它将打开一个菜单;从菜单中选择“Azure 资源管理器”菜单项来配置 Azure 订阅:

因为我们已经登录到 VSTS 和我们的 Azure 账户,所以它会在列表中显示订阅名称。在连接名称中,输入我们将在发布定义任务中用于连接到 Azure 账户的名称。

点击“确定”。

在此处添加 Azure 订阅的目的是为了获取该订阅中可用资源的列表,以便 VSTS 能够将其配置用于部署。在我们的示例中,我们需要一份托管在 ASE 或非 ASE 中的 Azure Web 应用列表,以便我们可以将 PetClinic 应用程序部署到 Azure Web 应用程序。

一旦我们关闭添加 Azure RM 端点的框,我们可以看到服务中列出了端点。因此,我们已经成功配置了 Azure RM 订阅:

点击“角色”链接以验证 Azure 订阅的可用角色:

现在,转到发布定义,点击 AzureRM 订阅的列表框,现在我们新添加的端点会出现在列表中。

选择端点:

到目前为止,我们已经在 VSTS 中配置了 Azure 订阅端点,因此可以在发布定义中使用它,将工件部署到托管在 ASE 和非 ASE 环境中的 Azure 应用服务中。我们已经配置了 AzureRM 订阅。一旦完成,我们可以选择应用服务名称。点击下拉箭头,已配置的 AzureRM 订阅中的 Azure Web 应用将显示在列表中:

转到“选择文件或文件夹”并点击三个点(...);转到 PetClinic-Maven,并选择在构建定义成功执行后创建的 WAR 文件。

我们的发布定义将拾取这个 WAR 文件并将其部署到 Azure Web 应用中。

点击“确定”。

现在,我们已准备好执行发布定义,但在此之前,我们需要保存发布定义:

点击保存按钮,它会打开一个新的对话框。提供一个评论并点击“确定”以在 VSTS 中保存发布定义:

验证你是否已经保存了发布定义。

“触发器”部分允许我们安排何时创建新的发布。我们可以在新版本的工件可用时设置,或者换句话说,当构建定义执行成功完成时:

为了检查端到端自动化,我们将开始构建定义执行。所以,一旦成功,它将触发一个发布定义。保存发布定义并点击“Queue new build...”。

为 PetClinic-Maven 构建定义排队构建,如果它成功完成,将触发发布定义。点击“确定”:

一旦构建定义成功完成,PetClinic-Release 发布定义将被触发。它的任务是将 .war 工件部署到 Azure 应用服务中。

部署失败!让我们找出此次部署失败的原因。

发布定义执行失败。让我们尝试排查问题:

首先验证历史记录:我们可以看到发布定义已被触发,但部署失败了:

让我们从日志中找出失败的可能原因。

转到日志部分,验证发布定义执行步骤。它清楚地表明,最终的部署操作失败了:

点击失败的步骤,即“部署 Azure 应用服务”:

仔细检查日志后,我们可以看到提到 .war 文件没有 .zip 文件扩展名。

请记住,我们选择的是 petclinic.war 而不是 petclinic.zip,所以它正在用这个任务部署 .war 文件;我们需要的是 .zip 文件,而不是 WAR 文件。

如何解决这个问题?

如果我们可以将 WAR 文件转换为 .zip 文件,那么它应该自动完成:

最好的方法是使用任何可以将 .war 转换为 .zip 文件的任务。那么我们就这样做。

  1. 点击“添加任务”,然后点击“Marketplace”链接:

它将打开一个新的 Marketplace 窗口。

  1. 查找 Trackyon:

在部署之前,我们将使用 Trackyon 将 WAR 文件转换为 ZIP 文件。完成后,Azure Web 应用程序上的部署应该会正常工作。

  1. 点击安装:

  2. 选择我们希望安装 Trackyon 的 VSTS 账户。

  3. 点击继续:

  4. 点击继续到账户。

  5. 点击关闭:

安装完成后,我们的下一任务是将该任务添加到发布定义中,以便在部署到 Azure Web 应用程序之前,将 WAR 文件转换为 ZIP 文件。

  1. 选择 Trackyon WAR 转换任务。

  2. 点击关闭:

  1. 选择 WAR 文件所在的文件夹:

  2. 选择 ZIP 文件应创建的文件夹:

  3. 现在,我们的发布定义有两个任务要执行:

  • .war 转换为 .zip 文件。

  • .zip 文件部署到 Azure Web 应用程序:

  1. 进入 PetClinic-Maven 构建定义并点击“队列新构建...”

  2. 当托管代理可用时,构建将开始。

等待构建执行成功完成。

由于我们已经为持续交付配置了发布定义,成功的构建定义执行将触发发布定义,完成端到端的自动化。

注意构建编号 Build 20161230.2:

如果构建成功完成,这个构建将触发发布定义。

总结

在本章中,我们介绍了不同的方式,将应用程序包部署到本地 Tomcat 服务器(使用 Jenkins 插件),Docker 容器,AWS Elastic Beanstalk,使用 FTP 部署到 Microsoft Azure 应用服务,以及使用 Visual Studio Team Services 部署到 Microsoft Azure 应用服务。

如果我们观察之前的自动化,它是部署应用程序的一种方式,可以使用不同的方法,如脚本、插件和 VSTS,在本地或云服务器上部署应用程序。

构建定义侧重于持续集成,而发布定义侧重于持续交付。因此,到目前为止,我们已经使用开源和商业工具覆盖了 CI 和 CD。

在下一章中,我们将介绍自动化测试(功能测试和负载测试),以便将其视为持续测试的一部分。

我们将在本地和云环境中分别使用 Selenium 进行功能测试,使用 Apache JMeter 进行负载测试。

第六章:自动化测试(功能测试和负载测试)

“大多数人高估了自己一年内能做到的事,低估了十年内能做到的事。”

  • 比尔·盖茨

在本章中,我们将学习在将应用程序部署到非生产环境后可以执行的各种类型的测试。持续测试对于验证应用程序的功能、性能等非常重要。自动化测试不仅能加快验证过程,还能标准化测试的执行方式。我们的重点将是简单的功能测试,看看我们如何执行它,以及使用开源和商业工具或服务进行负载测试。

我们将创建一个使用 Selenium 的功能测试示例,并在 Eclipse IDE 中执行该测试以验证其结果。我们还将把基于 Selenium 的 Maven 项目与 Jenkins 集成,这样我们就可以在 Jenkins 中执行该功能测试,并将其作为我们端到端自动化目标的一部分。

对于负载测试,我们将使用 Apache JMeter GUI 创建一个负载测试示例,然后使用保存的 .jmx 文件在 Jenkins 中执行负载测试。

本章将涵盖以下主题:

  • 使用 Eclipse 进行基于 Selenium 的 Web 应用功能测试

  • Selenium 与 Jenkins 集成

  • 使用基于 URL 的测试进行负载测试,Visual Studio Team System (VSTS)

  • 使用 Apache JMeter 进行负载测试

使用 Selenium 进行功能测试

在本章中,我们将使用 Selenium 和 Eclipse 执行一个功能测试用例。让我们一步步地创建一个示例功能测试用例,然后使用 Jenkins 执行它。

PetClinic 项目是一个基于 Maven 的 Spring 应用,我们将使用 Eclipse 和 Maven 创建一个测试用例。因此,我们将使用 Eclipse 中的 m2eclipse 插件。

我们已安装 Eclipse Java EE IDE for Web Developers,版本:Mars.2 Release (4.5.2),构建 ID:20160218-0600:

  1. 进入 Eclipse 市场,安装 Maven Integration for Eclipse 插件。

  2. 在 Eclipse 中使用向导创建一个 Maven 项目:

  1. 选择“创建一个简单项目”(跳过原型选择),然后点击“下一步”:

  1. 跟随向导创建一个项目。创建项目可能需要一些时间。在此过程中,提供 Artifact、版本、打包类型、名称和描述。点击完成。

  2. 等待 Maven 项目创建并配置完成。确保 Maven 已正确安装和配置。如果 Maven 位于代理后面,请将代理详细信息配置到 conf.xml 文件中,该文件位于 Maven 目录下。

  3. Pom.xml 文件中,我们需要在 <project> 节点内添加 Maven、Selenium、TestNG 和 JUnit 依赖项。以下是修改后的 Pom.xml

<project   
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
  <modelVersion>4.0.0</modelVersion> 
  <groupId>com.tiny</groupId> 
  <artifactId>test</artifactId> 
  <version>0.0.1-SNAPSHOT</version> 
  <name>test</name> 
  <build> 
    <plugins> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-compiler-plugin</artifactId> 
        <version>3.6.1</version> 
        <configuration> 
          <source>1.8</source> 
          <target>1.8</target> 
        </configuration> 
      </plugin> 
      <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-surefire-plugin</artifactId> 
        <version>2.19.1</version> 
        <configuration> 
          <suiteXmlFiles> 
            <suiteXmlFile>testng.xml</suiteXmlFile> 
          </suiteXmlFiles> 
        </configuration> 
      </plugin> 
    </plugins> 
  </build> 
  <dependencies> 
    <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>3.8.1</version> 
      <scope>test</scope> 
    </dependency> 
    <dependency> 
      <groupId>org.seleniumhq.selenium</groupId> 
      <artifactId>selenium-java</artifactId> 
      <version>3.0.1</version> 
    </dependency> 
    <dependency> 
      <groupId>org.testng</groupId> 
      <artifactId>testng</artifactId> 
      <version>6.8</version> 
      <scope>test</scope> 
    </dependency> 
  </dependencies> 
</project> 

  1. 添加完这些更改后,保存 pom.xml 文件,并从“项目”菜单重新构建项目。它将下载新的依赖项:

  1. 点击对话框中的“详细信息”按钮以验证正在进行的操作。

  2. 接下来的任务是编写TestNG类。安装 TestNG 插件。点击帮助并选择安装新软件。添加仓库:

  1. 选择我们需要安装的项目:

  1. 审核所有需要安装的项目并点击下一步。

  2. 接受许可协议并点击完成。

  3. 在 Eclipse 中验证安装进度。

  4. 现在让我们创建一个TestNG类:

  1. 提供一个类名:

  1. 给一个包名并点击完成。

  2. 新创建的类将如下截图所示:

  1. 右键点击test文件并点击 TestNG,转换为 TestNG。

  2. 它将创建一个包含测试套件详细信息的testing.xml文件:

  1. 右键点击项目并点击 Run Configurations。

  2. 右键点击 TestNG,然后点击 New:

  1. 提供项目名称并在套件中选择testing.xml

  2. 点击确定并应用。

  3. 点击运行:

  1. 如果 Windows 防火墙阻止了该操作,请点击允许访问。

  2. testing.xml中没有可用于执行的配置,因此即使 Maven 执行成功,也不会执行任何套件:

  1. test文件夹下生成TestNG类。

  2. 选择locationsuite nameclass name

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> 
<suite name="Suite"> 
<test name="Test"> 
<classes> 
<class name="example.PetClinicTest"/> 
</classes> 
</test><!-- Test --> 
</suite><!-- Suite --> 

  1. 访问github.com/mozilla/geckodriver/releases并下载一个版本。

  2. 根据我们系统的配置,从下载的 ZIP 文件中提取文件。在我们的例子中,我们下载了geckodriver-v0.13.0-win64

  3. 点击它并验证驱动程序的详细信息。

让我们写一些代码。它将检查网页标题是否包含特定的字符串。以下代码的结果或输出取决于页面的标题。如果标题包含给定的字符串,则测试用例通过;否则测试用例失败:

package example;     

importjava.io.File; 
importorg.openqa.selenium.WebDriver;     
importorg.openqa.selenium.firefox.FirefoxDriver;   
importorg.testng.Assert;     
importorg.testng.annotations.Test;   
importorg.testng.annotations.BeforeTest;   
importorg.testng.annotations.AfterTest;     
public class PetClinicTest {     
  private WebDriver driver;     
    @Test         
    public void testPetClinic() {   
      driver.get("http://localhost:8090/petclinic/");   
      String title = driver.getTitle();     
      Assert.assertTrue(title.contains("a Spring Frameworkk"));  
    }   
    @BeforeTest 
    public void beforeTest() {   
      File file = new File("F:\\##DevOpsBootCamp\\geckodriver-v0.13.0-win64\\geckodriver.exe"); 
      System.setProperty("webdriver.gecko.driver", file.getAbsolutePath());       
      driver = new FirefoxDriver();   
    }     
    @AfterTest 
    public void afterTest() { 
      driver.quit();       
    }     
}   

IDE 中会显示相同的文件,如下所示。

让我们再次从 Eclipse 运行 Maven 测试。

以下是测试用例成功执行时的输出:

  1. 在 Eclipse 的运行套件结果中的 All Tests 标签验证。我们可以在这里看到成功的执行:

  1. 在 Eclipse 的运行套件结果中验证 Failed Tests 标签。

  2. 在 Eclipse 的运行套件结果中的 Summary 标签验证成功的场景。

  3. 在代码中,修改用于标题比较的文本,以便测试用例失败。

  4. 在控制台验证输出:

  1. 在 Eclipse 的运行套件结果中的 All Tests 标签验证,并注意失败图标:

  1. 在 Eclipse 的运行套件结果中的 Failed Tests 标签验证。

  2. 点击 testPetClinic 并验证 Failure Exception。

  3. 在 Eclipse 的运行套件结果中的 Summary 标签验证。

因此,我们基于 Selenium 创建了一个示例测试用例来验证 PetClinic 首页的标题。

Jenkins 中的功能测试执行

现在让我们尝试从 Jenkins 执行相同操作:

  1. 在 Repository 中检查测试项目。 在 Jenkins 中创建一个 PetClinic-FuncTest 自由风格作业。

  2. 在构建部分,提供根 POM 位置和要执行的目标与选项:

  1. 保存构建作业并点击立即构建。

  2. 验证构建作业在控制台输出中的执行。

  3. 这将打开一个 Mozilla Firefox 窗口并打开代码中给定的 URL。 这需要我们的 PetClinic 应用程序已经部署在 web 服务器上并且运行没有问题:

  1. 现在在代码中进行更改,使标题验证失败,并执行构建作业。

  2. 在 Jenkins 的控制台输出中标记了一个失败:

  1. 转到项目仪表盘并验证 TestNG 结果的图表:

我们已经了解了如何在 Jenkins 中执行基于 Selenium 的测试用例。

在下一部分中,我们将展示如何使用 Jenkins 执行负载测试。

使用 Jenkins 执行负载测试

步骤如下:

  1. 打开 Apache JMeter 控制台。 创建一个测试计划。

  2. 右键点击测试计划并点击添加;选择线程(用户)。

  3. 选择线程组。

  4. 提供线程组名称。

  5. 在线程组属性中,提供线程数、启动时间和循环次数。

  6. 右键点击线程组。 点击添加。 点击采样器。 点击 HTTP 请求。

  7. 在 HTTP 请求中,提供服务器名称或 IP 地址。 在我们的例子中,它将是 localhost 或某个 IP 地址。

  8. 提供您的 Web 服务器运行的端口号。

  9. 选择 GET 方法并提供负载测试的路径:

  1. 保存 .jmx 文件。

  2. 现在让我们创建一个 Jenkins 作业。

  3. 在 Jenkins 中创建一个自由风格作业:

  1. 添加构建步骤,执行 Windows 批处理命令。

    1. 添加以下命令。 根据安装目录和 .jmx 文件的位置,替换 jmeter.bat 的位置:
    C:\apache-jmeter-3.0\bin\jmeter.bat -Jjmeter.save.saveservice.output_format=xml -n -t C:\Users\Mitesh\Desktop\PetClinic.jmx -l Test.jtl  

  1. 添加构建后操作。 发布性能测试结果报告,添加 **/*.jtl 文件。

  2. 点击立即构建:

  1. 验证项目仪表盘中的性能趋势。

  2. 点击性能趋势:

  1. 验证性能分解。

在下一部分中,我们将看到如何使用 VSTS 中的选项对部署在 Microsoft Azure App Services 中的 Web 应用程序进行负载测试。

使用基于 URL 的测试和 Apache JMeter 在 Microsoft Azure 上进行负载测试

一旦我们成功将应用程序部署到 Azure App Services,我们就可以对 Azure App Service 或 Azure Web Apps 进行负载测试。 让我们看看如何使用 Visual Studio Team Services 执行测试。

基于 URL 的测试

  1. 在顶部菜单栏中,点击负载测试。 让我们在 VSTS 中创建我们的第一个测试并执行它。

  2. 点击新建并选择基于 URL 的测试:

  1. 验证 HTTP 方法和 URL:

  1. 点击“设置”;根据需要在不同参数中提供输入:

  1. 点击“保存”并点击“运行测试”。

  2. 负载测试正在进行中:

  1. 在 VSTS 门户中查看完整的测试数据,数据一旦可用。

  2. 在 VSTS 中验证基于 URL 的测试执行的最终总结:

  1. 测试执行后,我们还会在 VSTS 中获得性能和吞吐量图表:

  1. 同时验证测试和与错误相关的细节。

我们已经了解了如何在 Azure Web 应用上执行基于 URL 的测试。在下一部分,我们将讲解如何使用 Apache JMeter 进行负载测试。

Apache JMeter

我们常常需要验证一个应用程序能够承受多少负载,以便基于此检查许多功能或瓶颈,提升性能,使其能够高效地处理尽可能多的请求。在这一部分,我们将介绍如何执行 Apache JMeter 测试。我们将在 Azure App Services 上部署的 PetClinic 应用上进行负载测试。

欲了解更多有关此主题的详细信息,请访问 jmeter.apache.org/usermanual/

要开始执行,请按以下步骤操作:

  1. jmeter.apache.org/ 下载 Apache JMeter。

  2. 在 Apache JMeter 中启动并创建一个线程组。这里,我们需要设置线程数(用户数)、逐步加载时间(以秒为单位)和循环次数:

  1. 右键点击线程组并点击“添加”。

  2. 选择采样器并点击“HTTP 请求”:

  1. 在服务器名称中提供 Azure Web 应用的 URL,并选择 HTTPS 协议:

  1. 执行测试并在 Apache JMeter 中验证结果:

  1. 在 HTTP 请求中添加汇总图表:

  1. 在负载测试执行后,验证图表。

  2. 欲了解更多详情,请点击“表格中查看结果”:

我们也可以在 VSTS 中执行 Apache JMeter 测试。

执行进度如下:

  1. 点击“新建”,选择 Apache JMeter 测试:

  1. 我们将使用之前用于对 Azure Web 应用进行负载测试的相同 JMX 文件。

  2. 选择负载持续时间和负载位置。点击“运行测试”:

总结

“测试是一项技能。虽然这对某些人来说可能是个惊讶,但这确实是一个简单的事实。”

  • Fewster 和 Graham

验证应用程序质量是非常重要的。测试是应用程序生命周期管理中的一部分,我们不能忽视它。它是高质量产品的基石之一。

因此,养成测试的习惯至关重要。不同类型的测试关注质量的不同维度,从而使应用程序更加稳健。

持续测试在持续集成和持续交付中扮演着重要角色。如果该部分是自动化的,自动化模式下的持续测试有助于更快地实现稳健性,并与更短的市场周期保持同步。

在本章中,我们介绍了与 Jenkins 集成的功能和负载测试。

在下一章中,我们将看到如何将我们至今执行的所有操作按顺序编排。这将让我们感受到端到端自动化的真实感。更多的是在 Jenkins 中创建流水线,并配置构建和发布定义的触发器,从而实现应用程序生命周期管理步骤的自动化。

第七章:协调 - 端到端自动化

"遵循持续交付路径的关键是不断质疑自己对可能性假设的看法。"

  • Jeff Sussna

本章中,我们将讨论使用开源和商业替代方案提供的协调功能,自动化应用程序生命周期管理的不同方法。

我们将使用 Jenkins 插件和 Visual Studio Team Services 任务来协调和自动化应用程序生命周期管理期间执行的所有活动。

本章我们将涵盖以下主题:

  • 使用 Jenkins 进行应用程序生命周期管理的端到端自动化协调

  • 使用 Jenkins、Chef 和 AWS EC2 的端到端自动化

  • 使用 Jenkins 和 AWS Elastic Beanstalk 的端到端自动化

  • 使用 Jenkins 和 Microsoft Azure 应用服务的端到端自动化

  • 使用 VSTS 进行应用程序生命周期管理的端到端自动化协调

使用 Jenkins 进行应用程序生命周期管理的端到端自动化

在 第二章,持续集成 中,我们创建了一个构建作业,该作业执行以下任务:

  1. 对 PetClinic Web 应用程序的静态代码分析:

  1. 静态代码分析成功执行后,Jenkins 仪表板会显示指向特定项目的 SonaQube 仪表板的 URL。

  2. 验证 Jenkins 仪表板以及所有分析细节:

  1. 源文件编译和单元测试执行:

  1. 单元测试结果将显示在 Jenkins 项目仪表板本身。

  2. 包文件的创建:

一旦我们的包文件准备好,我们可以将其部署到 AWSEC2 实例、Microsoft Azure 虚拟机、AWS Elastic Beanstalk、Microsoft Azure 应用服务、容器或任何可以从安装了 Jenkins 系统的物理机器访问的机器上。

使用 Jenkins、Chef 和 AWS EC2 的端到端自动化

在本节中,我们将使用 Jenkins 中可用的 Build Pipeline 插件来协调不同的任务。

在 第四章,云计算与配置管理 中,我们安装了 Chef 工作站,配置了托管 Chef 账户,并为 AWS 和 Microsoft Azure 安装了刀具插件。

我们使用以下命令在 AWS EC2 中创建了一个实例:

[root@devops1 Desktop]# knife ec2 server create -I ami-1ecae776 -f t2.micro -N DevOpsVMonAWS --aws-access-key-id '< Your Access Key ID >' --aws-secret-access-key '< Your Secret Access Key >' -S book --identity-file book.pem --ssh-user ec2-user -r role[v-tomcat]  

我们使用以下命令在 Microsoft Azure 中创建了一个虚拟机:

[root@devops1 Desktop]# knife azure server create --azure-dns-name 'distechnodemo' --azure-vm-name 'dtserver02' --azure-vm-size 'Small' -N DevOpsVMonAzure2 --azure-storage-account 'classicstorage9883' --bootstrap-protocol 'cloud-api' --azure-source-image '5112500ae3b842c8b9c604889f8753c3__OpenLogic-CentOS-67-20160310' --azure-service-location 'Central US' --ssh-user 'dtechno' --ssh-password 'cloud@321' -r role[v-tomcat] --ssh-port 22  

我们验证了 AWS EC2 实例和 Microsoft Azure 虚拟机在托管 Chef 中的注册。

我们从命令提示符执行了这两个命令。在 Jenkins 中,我们可以为 Windows、Linux 或 Mac 执行命令。我们也可以通过创建自由风格的作业,在 Jenkins 构建作业中执行相同的命令。

使用密钥配置 SSH 身份验证

安装在虚拟机上的 Chef 工作站可以从安装了 Jenkins 的系统中访问。我们可以使用虚拟盒子或 VMware 工作站在笔记本上创建虚拟机;然后可以安装 CentOS 6 或 7,并按照我们在第四章中所做的配置 Chef 工作站,云计算与配置管理

在开始配置端到端自动化和使用构建管道插件以及上下游任务进行编排之前,我们将使用密钥配置 SSH 认证。

配置 SSH 认证的主要目的是允许 Jenkins 虚拟机连接到 Chef 工作站虚拟机。这样我们就可以从 Jenkins 机器执行命令到 Chef 工作站。通过这种方式,我们可以使用 Chef 工作站在 AWS 或 Azure 云中创建实例,并在其上安装运行时环境来部署 PetClinic 应用程序:

如果我们尝试从 Jenkins 访问 Chef 工作站,它将不起作用,因为我们仍然需要配置无密码配置,因为在 Jenkins 作业执行中,我们不能在流程中间等待输入密码。让我们配置无密码访问 Jenkins,以便访问 Chef 工作站:

  1. 打开安装了 Jenkins 的虚拟机中的终端。使用ssh-keygen创建一个新密钥:

  1. 在本地文件系统上验证密钥。

  2. 使用ssh-copy-id将密钥复制到配置了 Chef 工作站的远程主机:

  1. 现在通过执行execute Shell 命令,尝试通过 Jenkins 构建作业访问 Chef 工作站虚拟机。

  2. 如果失败,则尝试从 Jenkins 虚拟机通过终端访问 Chef 工作站。如果看到“代理被拒绝使用密钥签名”的错误信息,则执行ssh-add命令来解决问题。

  3. 一旦在终端中连接成功,执行ifconfig命令来查找 IP 地址,这样我们就能找出在哪台虚拟机上执行该命令:

  1. 此时,我们的 SSH 连接已成功使用我们创建和配置的密钥,而不是密码。

  2. 现在我们可以从 Jenkins 的虚拟机访问 Chef 工作站,因此我们可以从 Jenkins 执行 knife 命令到 Chef 工作站。我们的下一个目标是尝试使用 Jenkins 构建作业和 Chef 工作站在 AWS 中创建实例。

  3. 在 Jenkins 构建作业中,添加一个构建步骤,选择执行 Shell,并添加此处显示的命令。我们已经讨论过knife ec2命令:

 ssh -t -t root@192.168.1.36 "ifconfig; rvm use 
        2.1.0; knife ec2 server create -I ami-1ecae776 -f 
        t2.micro -N DevOpsVMonAWS1 --aws-access-key-id 
        '<YOUR ACCESS KEY ID>' --aws-secret-access-key 
        '<YOUR SECRET ACCESS KEY>' -S book --identity-file 
        book.pem --ssh-user ec2-user -r role[v-tomcat]"  

  1. 使用你自己的 Access Key ID 和 Secret Access Key 替换。点击保存。点击“立即构建”链接以执行构建作业。

  2. 转到控制台输出查看进度:

  1. 检查日志;AWS 实例创建已启动。

  2. 在 AWS 管理控制台中验证:

  1. 在执行进一步操作之前,请检查 AWS 安全组是否已为 SSH 访问设置条目:

  1. 一旦 SSH 访问可用,它将开始安装 Chef 客户端。

  2. 在我们的案例中,它将开始下载 Chef 客户端,并将其安装到我们使用 Chef 工作站创建的 AWS 实例上:

  3. 在控制台中验证 Chef 安装过程。一旦 Chef 客户端安装在 AWS 实例上,它将启动第一次 Chef 客户端执行。

  4. 观察运行列表并同步 cookbook。它将汇聚并开始安装软件包。

  5. 验证软件包的安装情况。

  6. 它还将显示 conf.xml,可以根据配置验证与端口相关的详细信息。

  7. 一旦软件包安装完成,将开始服务管理。

  8. 现在,Chef 客户端执行已完成,并将显示我们创建的 AWS 实例的相关信息:

  1. 检查 AWS 管理控制台,确认构建状态是否成功。

  2. 验证已注册节点的托管 Chef:

在此阶段,我们已经准备好了一个 AWS 实例,该实例已安装 Tomcat 和 Java,因此我们可以轻松部署我们的应用程序。现在,我们已经准备好所有资源来配置构建流水线:

  1. 转到 PetClinic-Code 任务,并从“添加构建后操作”中选择“构建其他项目”。

  2. 在“要构建的项目”中输入 PetClinic:

  1. 在此,PetClinic-Code 成为 PetClinic 的上游项目,而 PetClinic 成为 PetClinic-Code 的下游项目。构建流水线插件需要建立关系,使用上游和下游项目进行可视化。

  2. 转到 PetClinic-Code 任务,并从“添加构建后操作”中选择“构建其他项目”。

  3. 在“PetClinic-CloudProvisioning”项目中输入,进行构建:

  1. 如果此构建任务执行成功,则表示已部署的虚拟机已准备好,并安装了运行时环境。

  2. 转到 PetClinic-CloudProvisioning 任务,并从“添加构建后操作”中选择“构建其他项目”。

  3. 在“要构建的项目”中输入 PetClinic-Deploy:

  1. 一旦验证了工件复制操作,配置构建任务以便我们可以将其作为手动操作进行部署。我们将创建一个作业,使用新创建实例的域名或 IP 地址作为字符串参数:

  1. 配置构建任务,在 AWS 实例上执行部署 WAR 文件的操作,执行以下命令:
 ssh -i /home/mitesh/book.pem -o 
        StrictHostKeyChecking=no -t -t ec2-user@$AWSDNS 
        "sudousermod -a -G tomcat ec2-user; sudochmod -R 
        g+w /var/lib/tomcat6/webapps; sudo service tomcat6 
        stop;"

 scp -i /home/mitesh/book.pem 
        /home/mitesh/target/*.war ec2-
        user@$AWSDNS:/var/lib/tomcat6/webapps

 ssh -i /home/mitesh/book.pem -o 
        StrictHostKeyChecking=no -t -t ec2-user@$AWSDNS 
        "sudo service tomcat6 start"

  1. 在 Jenkins 构建任务中的“执行 shell 命令”部分执行以下命令:

  1. 一旦此构建任务执行成功,意味着应用程序部署成功,我们可以进行功能测试。

  2. 使用 Promotion 插件配置 PetClinic-FuncTest 构建的提升:

  1. 执行 PetClinic-FuncTest 后,我们的流水线结束:

  1. 保存 PetClinic-FuncTest,并验证上游项目。

  2. 从“管理 Jenkins | 管理插件”安装 Build Pipeline 插件。

  3. 在 Jenkins 仪表板上,点击+号。

  4. 提供视图名称:

  1. 在 Upstream / downstream 配置中选择初始任务:

  1. 点击 Run 执行。确保在 Jenkins 中配置的 Tomcat 和 Sonar 正在运行。

  2. 我们已经将 PetClinic-Deploy 配置为 Build 其他项目中的下游项目(手动步骤)。我们也定义了参数:

图:用于端到端应用生命周期管理自动化的构建流水线

  1. 验证参数符号:

图:具有参数化任务的构建流水线

  1. 一旦 PetClinic-CloudProvisioning 项目成功完成,记下域名并将其作为默认参数提供给 PetClinic-Deploy 项目。

  2. 点击 Trigger:

图:具有手动触发的构建流水线

  1. 验证端到端构建流水线执行。

因此,使用 Build Pipeline 插件我们可以协调不同活动的自动化。

使用 Jenkins 和 AWS Elastic Beanstalk 进行端到端自动化

要在 Amazon Elastic Beanstalk(PaaS)中部署 PetClinic Spring 应用程序,我们需要以下流程:

我们在本章中创建了 PetClinic-Code、PetClinic 和 PetClinic-Deploy-ElasticBeanstalk 构建任务。

将 PetClinic 配置为 PetClinic-Code 的下游任务;并将 PetClinic-Deploy-ElasticBeanstalk 配置为 PetClinic 构建任务的下游任务。

使用 Jenkins 和 Microsoft Azure 应用服务进行端到端自动化

要在 Microsoft Azure Web 应用(PaaS)中部署 PetClinic Spring 应用程序,我们需要以下流程:

我们在本章中创建了 PetClinic-Code、PetClinic 和 PetClinic-Deploy-Azure 构建任务。将 PetClinic 配置为 PetClinic-Code 的下游任务;并将 PetClinic-Deploy-Azure 配置为 PetClinic 构建任务的下游任务。

在 Microsoft Azure 的情况下,也有替代方案:我们可以使用 Visual Studio Team 服务器和 TFS 在线进行持续集成、持续交付和持续部署。

使用 VSTS 进行端到端的应用生命周期管理自动化协调

在第五章,持续交付中,我们看到如何使用 VSTS 部署我们的 Web 应用:

  1. 转到 Releases 并检查最新的发布定义。

  2. 查看 Build & Release 列以验证构建编号。

  3. 双击 Release-22 以获取 VSTS 中发布定义执行的更多详细信息:

现在让我们验证在 VSTS 中发布定义执行的详细信息:

  1. 在 Details 中,验证触发发布定义执行的构建编号。它还提供了请求持续部署的用户的详细信息。

  2. 环境部分提供了有关环境发布定义执行了哪些部署的详细信息。它还显示了部署状态:发布定义何时被触发,何时完成,以及是否执行了测试。在我们的例子中,发布定义中没有测试用例:

  1. 要获取有关发布定义执行的更多详细信息,请单击日志。它将显示在发布定义执行过程中执行的一系列步骤。

  2. 如果设置了审批机制,它将首先要求审批;一旦获得审批,它将在代理上运行。它将首先初始化代理;然后,一旦代理可用于发布定义执行,它将从源文件夹下载构件或 WAR 文件。

  3. 我们已经知道无法直接部署 WAR 文件,因此,根据我们的配置,它将把 WAR 文件转换为 ZIP 文件。一旦我们拥有了 ZIP 格式的包文件,我们的部署 Azure 应用服务任务将把应用程序包部署到 Azure Web 应用中。

  4. 单击每个单独的步骤,以获取该步骤执行的详细日志。

  5. 让我们看看 WAR 转换器 **/*.war 步骤的作用。

  6. 类似地,部署 Azure 应用服务步骤执行将提供有关如何执行部署过程的详细信息:

  1. 由于没有配置后部署审批,它会自动批准,因此构建执行成功:

我们已经知道 Azure Web 应用程序的 URL,或者我们可以从 Azure 门户中获取它。访问该 URL 并检查应用程序是否已正确部署。

到目前为止,我们已经使用持续集成和持续部署配置了端到端的应用程序生命周期管理自动化。

我们使用部署槽来处理不同的环境。所以,我们应该在发布定义中创建多个环境并进行部署。

所以,下一个问题是如何创建一个环境,以便我们可以在 Azure Web 应用中的特定部署槽中使用它进行包部署?

在发布定义中,单击 +添加环境,然后选择创建新环境。如果我们想在新环境中使用现有环境的相同任务,可以选择克隆所选环境:

在新环境中,我们保持自动的前部署审批:

  1. 选择触发器,以便每当部署到生产环境成功时,自动进行部署。我们可以在所有环境配置完成后重新排列或重命名它。

  2. 选择用于发布定义执行的托管代理。

  3. 单击创建。

  4. 双击环境名称来更改环境名称。

  5. 根据环境,可以配置其余的部署详细信息:

  1. 将现有环境名称更改为 Dev,然后单击(...)。这将打开一个菜单,选择克隆所选环境选项。

  2. 如果是新环境,假设我们想在部署过程开始前保留审批,怎么办?

  3. 在预部署批准中,选择特定用户。VSTS 帐户中的所有用户都可以获得审批权限。我们可以从该列表中提供任何名称。

  4. 选择触发器,以便每次向环境 Dev 部署成功后自动部署。配置完所有环境后,我们可以重新排列或重命名它。

  5. 为发布定义执行选择已托管代理。

  6. 点击创建。通过双击环境名称,将环境名称更改为 QA。根据环境,其他部署细节可以配置:

  1. 以类似的方式配置 UAT 环境。

  2. 要手动分配审批到任何环境,选择“环境”,点击(...),然后选择“分配审批人...”。

  3. 在预部署批准中,我们可以指定可以批准执行发布定义的用户。

  4. 点击确定。

  5. 我们只需配置最近创建的不同环境中部署 WAR 文件的位置:

让我们从 Dev 环境开始:

  1. 点击 Dev 环境。

  2. 转到发布定义中的 Deploy Azure App Service 任务。

  3. AzureRM 订阅和应用服务名称已经配置,就像我们之前做的那样。

  4. 要将 WAR 文件部署到特定插槽,在此案例中为 dev,请勾选部署到插槽复选框。

  5. 它会要求选择资源组:选择可用的 Azure Web 应用所在的资源组。

  6. 在插槽列表中,将列出为 Azure Web 应用创建的所有插槽。选择 dev 插槽。

  7. 保持其余细节不变并保存发布定义:

现在,让我们配置 QA 环境:

  1. 点击 QA 环境。

  2. 转到发布定义中的 Deploy Azure App Service 任务。

  3. AzureRM 订阅和应用服务名称也已经配置,就像我们之前做的那样。

  4. 要将 WAR 文件部署到特定插槽,在此案例中为 qa,请勾选部署到插槽复选框。

  5. 它会要求选择资源组:选择可用的 Azure Web 应用所在的资源组。

  6. 在插槽列表中,将列出为 Azure Web 应用创建的所有插槽。选择 qa 插槽。

  7. 保持其余细节不变并保存发布定义:

配置 UAT 环境,请按照以下步骤操作:

  1. 点击 UAT 环境。

  2. 转到发布定义中的 Deploy Azure App Service 任务。

  3. Azure RM 订阅和应用服务名称已经配置,就像我们之前做的那样。

  4. 要将 WAR 文件部署到特定插槽,在此案例中为 dev,请勾选部署到插槽复选框。

  5. 它会要求选择资源组:选择 Azure Web 应用所在的资源组。

  6. 在插槽列表中,将列出为 Azure Web 应用创建的所有插槽。选择 uat/stage 插槽。

  7. 保持其他细节不变,保存发布定义:

  1. 要在生产插槽或主要 Azure Web 应用中部署应用程序,我们无需选择任何插槽。只需提供 Azure Web 应用名称,系统将自动将其部署到 Azure 中的主 Web 应用:

  1. 保存发布定义:

  2. 点击发布链接:

我们在发布定义执行中已设置了批准流程,因此,除非批准者批准,否则发布定义的执行将不会进行。

查看发布定义执行的摘要部分中的警告。它显示dev环境的预部署批准正在等待中。

由于我已将自己的 ID 配置为批准者,因此可以使用批准或拒绝构建的链接:

  1. 让我们点击批准或拒绝链接。

  2. 它会打开一个小对话框。我们需要在其中提供评论,然后点击批准或拒绝。我们还可以在此机制中分配多个批准者,并且可以设置是否希望所有批准者或任何一个批准者进行批准。

  3. 在这种情况下,我们将点击批准:

  1. 在日志中,我们现在可以看到已经给予了预部署批准,接下来的流程即将执行,用于在开发插槽中的应用部署:

  1. 来自构建定义的工件将被下载,然后可以将其转换为 ZIP 文件,接着我们可以部署到开发插槽:

  1. 一旦成功部署到开发环境,执行过程将等待批准,然后才会开始部署到 QA 插槽。

  2. 我们需要提供批准,以便开始执行应用程序部署步骤:

  1. 在发布记录中,我们可以看到有四个不同的环境,因为在我们的发布定义中创建了这些环境。

  2. 我们可以看到当前发布定义执行的状态:

  1. 对 QA 插槽的部署给予批准,它也将把 WAR 文件部署到 QA 插槽中。

我们需要记住,除了某些参数之外,应用程序部署到不同 Azure Web 应用程序部署插槽中的过程是相同的,且不会改变。

我们需要记住,每个插槽都是一个实时的 Web 应用程序,因此,如果我们想查看应用程序部署的位置以及幕后发生了什么,可以进入每个插槽的Kudu编辑器,验证是否已在每个 Azure Web 应用程序的插槽中执行了部署操作。

同样地,也需要部署到 UAT 或 Stage 插槽以及生产插槽:

现在,作为你自己的练习,提交一些应用程序代码的更改,并观察构建定义是如何执行的;它是如何在构建任务成功执行后触发发布定义的;以及如何将应用程序部署到不同的插槽。完成后,访问 Azure Web 应用程序的某个部署插槽的特定 URL,检查应用程序在不同环境中的部署是否成功。

总结

在这一章中,我们已经看到了如何自动化应用生命周期管理中不同任务的执行。

我们已经使用 Jenkins 在 AWS 和 Microsoft Azure 云服务提供商上部署了一个应用程序,并使用 Chef 配置管理工具来安装运行时环境。

我们还使用 Jenkins 在 AWS Elastic Beanstalk 上部署了一个应用程序,并使用 Visual Studio Team Services 进行端到端自动化,以便在 Azure App Services 上部署该应用程序,Azure App Services 是微软提供的 PaaS 服务。

在下一章,我们将学习更多关于配置安全性和监控相关的内容。我们将进一步探讨 Jenkins、VSTS 和 Microsoft Azure 中基于角色的资源访问控制。

第八章:安全性与监控

“展示强有力的成功和明显的好处是让其他人同意尝试你方法的关键。”

  • Frederic Rivain

安全性是应用生命周期管理中最重要的部分之一,因此,在 DevOps 的背景下,这项服务提高了价值。

在本章中,我们将讨论用户管理、监控以及部分故障排除内容。

我们将看到如何在 Jenkins 和 VSTS 中创建和管理用户。对于开源和商业工具,功能方面差异不大,但在易用性和支持可用程度上可能有所不同。

本章将涉及以下主题:

  • Jenkins 中的用户管理

  • Visual Studio 团队服务VSTS)中的用户管理

  • 监控 Jenkins 和 Microsoft Azure

  • Azure Web 应用程序故障排除和监控

Jenkins 和 VSTS 中的安全性

安全性是 Jenkins 和 VSTS 的主要关注点。然而,安全性不仅仅局限于这一方面。安全性更是一个整体视角,涉及应用程序和基础设施的安全。考虑到我们在云环境中操作,基础设施安全变得尤为重要。

在本章中,我们将讨论 Jenkins 和 VSTS 中的用户管理。

Jenkins 中的用户管理

安全性涉及认证授权,它们是 AAA 三元组的一部分:

要进行安全配置,请转到“管理 Jenkins”并点击“配置全局安全性”:

要启用 Jenkins 中的安全性,请点击“启用安全性”。默认情况下,Jenkins 启用了安全性:

我们需要将 JNLP 代理的 TCP 端口更改为随机端口,以便可以配置代理。

对于认证中的访问控制,在安全领域部分选择 Jenkins 自己的用户数据库。

勾选“允许用户注册”,这样新用户就可以创建账户:

在授权部分,选择基于矩阵的安全性,以根据需要为所有可用用户提供权限:

我们还可以选择基于项目的矩阵授权策略。在这种情况下,我们需要进入单个构建任务或项目,并进入其配置:

勾选启用基于项目的安全性并为各个用户提供权限:

经常发生的情况是,我们因为没有为管理员用户单独提供权限而错误地锁定了 Jenkins,并保存了安全配置。

在这种情况下,要恢复 Jenkins 访问,请进入任何安装了 Jenkins 的操作系统中的 JENKINS_HOME 目录。

打开Config.xml,将useSecurity的值更改为false并重启 Jenkins:

在下一节中,我们将看到 VSTS 中的用户管理。

VSTS 中的用户管理

对于配置和用户管理,按照以下步骤操作:

  1. 打开新创建的项目 PetClinic 并点击设置图标。在项目配置页面,团队信息可用。点击 PetClinic 团队:

  1. 默认情况下,管理员帐户已作为团队成员。点击+添加...来添加一个新的团队成员进行协作:

  1. 使用登录地址或组别别名,点击保存更改:

  1. 在仪表板中验证 PetClinic 团队成员:

  1. 进入团队项目的主页并验证“团队成员”部分:

我们已成功将团队成员添加到项目的主团队。这就是如何创建项目并管理团队。

监控 Jenkins 和 Microsoft Azure

Azure 应用服务/Azure Web 应用自带诊断与解决问题功能,用于了解资源健康状况和解决一些常见问题。

监控 Jenkins

在 Jenkins 中,我们可以通过使用监控插件监控主机和不同的代理:

  1. 进入管理 Jenkins|管理插件并安装监控插件:

  1. 安装成功后,进入管理 Jenkins 并选择 Jenkins 主机的监控。

  2. 点击同一部分中的 Jenkins 节点以查看 Jenkins 代理的监控:

  1. 在浏览器中验证 JavaMelody 监控在特定时间戳的统计数据:

  1. 点击“其他图表”以获取更多有关 Jenkins 各个方面的信息,例如缓冲区内存、线程数、交换空间等:

  1. 向下滚动并获取线程的详细信息:

  1. 点击调试日志以获取更多详细信息:

  1. 在底部区域,我们可以找到调试日志:

  1. 我们还可以使用构建监控视图插件监控不同的构建作业。

  2. 进入管理 Jenkins|管理插件并安装“构建监控视图”插件:

  1. 安装成功后,进入 Jenkins 仪表板并点击+号。

  2. 提供视图名称。

  3. 选择构建监控视图并点击确定:

  1. 选择要监控的作业数量。

  2. 点击确定:

  1. 从一个窗口中,我们可以监控在构建监控视图中配置的所有构建作业的状态:

本书中,我们也在 Microsoft Azure Web Apps 上部署了应用程序,接下来的章节将展示如何监控 Azure Web Apps 并进行故障排除。

Azure Web Apps 故障排除与监控

让我们深入了解“诊断与解决问题”以获取更多细节:

  1. 进入 Azure 应用服务并选择我们之前创建的 Azure Web 应用。点击“诊断与解决问题”。

  2. 另一个面板将被打开,面板上将有资源健康指示器和常见问题解决方案。

  3. 我们可以看到,根据状态和绿色指示器,MyPetClinic Azure Web 应用程序可用且正常运行。

在我遇到的 Azure Web Apps 问题中,因各种原因,我多次遇到 HTTP 5xx 错误。识别问题的根本原因并加以修复也很重要。不过,这里提供了一些快速的解决方案/建议:

  1. 在资源健康中,点击更多详细信息以获取 MyPetClinic Azure Web 应用程序的现有状态:

  1. 点击查看历史记录以查找 Azure Web 应用程序的详细信息,了解其何时可用或不可用:

Azure 应用服务 - HTTP 实时流量

在常见问题解决方案中,我们可以评估实时流量,以了解现有资源是否能管理当前的负载。

如果实时流量正常,那么可能没有问题,我们应该进一步排查问题:

我们可以根据 Azure 应用服务中可用的一个或多个主机名获取 HTTP 实时流量。

Azure 应用服务 - CPU 和内存消耗

我们还可以获取有关 CPU 和内存百分比的详细信息,以了解 Azure Web 应用程序的性能,并确定是否需要进行扩展操作:

我们已经知道有一个主要的 Azure Web 应用程序,其他部署槽也可以使用。我们还可以获取 Azure Web Apps 或服务计划中的站点的详细信息:

这里,我们查看的是 Azure Web Apps 的 MyPetClinic(dev)部署槽的详细信息:

我们可以选择一个或多个部署槽,或选择全部槽,以查看 应用服务计划ASP)中的 CPU 和内存使用情况:

类似地,我们可以验证特定 ASP 中托管的主要 Azure Web 应用程序和部署槽的 HTTP 统计信息:

我们还可以验证特定 ASP 中托管的主要 Azure Web 应用程序和部署槽的网络统计信息:

如果我们将光标放置在图表的特定位置,那么我们将获得该特定点的所有详细信息,包括主应用和其他部署槽:

到目前为止,我们已经查看了诊断和解决问题的部分。在下一部分中,我们将查看与活动日志相关的详细信息。

Azure 应用服务 - 活动日志

活动日志显示了基于订阅、资源组、资源、资源类型、操作、时间范围、事件类别、事件严重性和事件发起者在 Azure Web 应用程序中执行的操作:

我们可以看到不同的操作,例如更新、写入和删除操作。

Azure 应用程序洞察用于应用监控

在 Azure 资源管理门户中,转到 Azure 应用服务,选择 Azure Web 应用程序,进入监控部分;点击应用洞察。

Application Insights 帮助我们识别并诊断 Azure Web 应用程序中的问题。当我们创建 Azure Web 应用程序时,我们可以选择创建与 Azure Web 应用程序关联的 Application Insights;如果我们没有这样做,也可以为我们的 Azure Web 应用程序创建新的 Application Insights 资源:

一旦创建了 Application Insights 资源,我们也可以从 Azure Web 应用程序中访问它。让我们尝试从不同区域检查 Azure Web 应用程序的可用性。

在 INVESTIGATE 标签中,点击可用性。此时没有 Web 测试或数据可用:

让我们添加一个 Web 测试。点击 +Add Web Test。提供测试名称、测试类型中的 URLping 测试,以及测试可用性的 URL:

在测试频率中,选择 5 分钟,在测试位置中,选择我们希望测试 Azure Web 应用程序可用性的任意五个位置:

设置 HTTP 响应:200 为成功标准,并设置警报。在完成所有这些配置后,点击创建:

在一段时间后,它将开始从我们在 Web 测试中配置的时区开始对 Azure Web 应用程序进行 ping 测试。我们可以看到 TOTAL SUCCESSFUL TESTS(总成功测试)、TOTAL FAILED TESTS(总失败测试)、AVERAGE RESPONSE TIME(平均响应时间)以及其他细节:

在 Application Insights 门户中,我们还可以看到 Web 测试的历史记录。

Azure Web 应用程序监控

我们已经在 Kudu 编辑器中看到了不同类型的日志文件。现在让我们在 Azure 门户中查看它们。

诊断日志

要启用或禁用诊断日志,我们需要在 Azure 门户中进入 Azure 应用服务,点击 MyPetClinic Azure Web 应用程序,在 MONITORING 部分点击诊断日志:

我们可以根据需求和环境启用或禁用不同种类的日志:

完成更改后,点击保存按钮。

总结

安全性和监控是过于庞大的概念,无法在一个章节中全面涵盖,因为它们涉及的方面非常广泛。

本章我们涵盖了 Jenkins 和 VSTS 中的用户管理和监控的一些方面。我们还讨论了如何诊断问题并在 Microsoft Azure 应用服务或 Azure Web 应用中进行故障排除。

这是本书旅程的结束;然而,教育是没有尽头的。

Jiddu Krishnamurti 的名言是:

“教育没有终点。不是你读一本书,通过考试,就结束了教育。整个人生,从你出生到你去世,都是一个学习的过程。”

本书是从 AvaxHome 下载的!

访问我的博客,获取更多新书:

avxhm.se/blogs/AlenMiler

posted @ 2025-06-29 10:38  绝不原创的飞龙  阅读(29)  评论(0)    收藏  举报