谷歌云自动化高级教程-全-
谷歌云自动化高级教程(全)
一、GCP 自动化简介
本章涵盖了 GCP(谷歌云平台)的自动化构建模块,并解释了如何建立一个 GCP 帐户。本章涵盖的主题如下:
-
GCP 简介
-
GCP 的自动化积木
-
注册谷歌云
GCP 简介
谷歌云平台(GCP)是谷歌的公共云产品,它根据需求向最终用户提供一系列 IaaS 和 PaaS 服务。他们的服务非常适合现代应用开发用户。GCP 在大数据分析、人工智能和容器化领域有一些独特的产品。
谷歌首次涉足云计算是通过谷歌应用引擎,它于 2008 年 4 月作为平台即服务(PaaS)产品推出。它使开发者能够在谷歌的基础设施上构建和托管应用。2011 年 9 月,App Engine 走出预览版,2013 年正式采用 Google 云平台名称。该公司随后发布了各种工具,如其数据存储层、云 SQL、BigQuery、计算引擎以及组成今天谷歌云平台的其余工具。
GCP IaaS 资源包括物理硬件基础设施——计算机、硬盘驱动器、固态驱动器和网络——包含在谷歌的全球分布式数据中心中。这种硬件以虚拟化资源的形式提供给客户,比如虚拟机 (VMs)。
为了构建云应用,GCP 提供了各种产品。下面介绍了一些比较流行的服务:
|服务
|
描述
|
| --- | --- |
| 谷歌计算引擎 | 帮助创建虚拟机来运行操作系统,并允许在云中创建不同的计算机。 |
| 谷歌库比厄引擎 | 帮助管理容器编排器;使用 Kubernetes 作为托管服务来帮助部署、扩展和发布。 |
| 谷歌云功能 | 有助于实现事件驱动的无服务器云平台,有助于创建代码形式的基础设施(即由代码设计和实现的基础设施)。 |
| 谷歌容器注册 | 在 GCP 上提供安全、私有的 Docker 图像存储。它为团队提供了一个单一位置来管理 Docker 映像、执行漏洞分析,并通过细粒度的访问控制来管理谁可以访问什么。 |
| Google Stackdriver(现在的 Google Operations) | 帮助向公共云用户提供性能和诊断数据。提供对 Google 云和 AWS 云环境的支持,使其成为混合云解决方案。 |
GCP 的自动化积木
许多新的应用正在被创建和开发,以便在云原生环境中运行。其中一些利用了容器化的架构,并部署在容器上。每个云提供商都有围绕 Kubernetes 的产品——谷歌有 GKE,Azure 有 Azure Kubernetes 服务,亚马逊有亚马逊 EKS 和亚马逊 Fargate。
容器化和云原生架构的整体理念以可用性、可伸缩性、自动化和开发运维为中心。Docker 和 Kubernetes 为开发人员和管理员提供了轻松部署和管理容器化应用的选项。
在容器化的环境中有许多发布和部署选项。其中最流行的是金丝雀部署、蓝绿部署和 A/B 测试。开发人员和发布/部署团队现在可以使用与 Kubernetes 生态系统完美集成的新型工具,轻松直观地开发/管理应用。在本书中,我们将介绍四种重要的工具,它们可用于持续部署和支持基于 Kubernetes 的应用部署。我们将讨论 Google 部署管理器、Spinnaker、Tekton 和 Jenkins。此外,我们还将介绍如何利用这四种解决方案的原生 GCP 服务来自动化 GCP 上的应用生命周期管理。
这些系统中的一些公共元素有助于开发人员和部署团队自动化他们的持续部署版本,这些元素将在下面的章节中进行解释。
支持简化部署
前面提到的大多数工具都允许开发人员简化云环境中应用的部署。它们通过提供易于使用的标准和模板以及应用部署的声明式格式来实现这种简化。一些工具支持 YAML 格式,并支持 Python 和 Jinja 模板来提供配置的参数化。
这些工具支持标准化,只需创建一个模板,然后允许它在类似的部署和不同的应用中重用。支持应用的核心基础设施元素包括自动扩展组、负载平衡器、节点、pod 等。它们都可以作为模板项或资源提供,通过模板进行配置,然后以标准化、可重复的方式进行部署。
可重复的部署流程
由于这些工具提供了一种创建声明性模板的方法,模板和部署策略在整个组织中的可重用性得到了增强。团队可以标准化处理不同类型发布的方式,以及定义和执行在容器化环境中运行应用所需的跨基础架构组件的标准。这可以节省部署工作和时间,并减少错误。
应用焦点
连续部署工具帮助团队专注于应用,选择适当的部署策略,并在将来的修改中重用模板,而不是专注于 Kubernetes 平台和相关基础设施元素的部署,然后重新定义部署策略。这使得应用开发/发布团队能够通过抽象特定于平台(如操作系统、数据库、Web 服务器)和云(私有云或公共云)的底层组件供应和配置过程的复杂性,专注于应用本身。
自动发布
这些工具支持端到端 CI/CD,因此可以与 CI 中的现有工具很好地集成。一些流行的 CI 工具有 Jenkins、Travis CI 等等。CD 工具与它们无缝集成,支持端到端的管道自动化和部署。因此,通过利用这些集成,实现了在容器化或云环境中完全自动化交付管道的端到端自动化愿景。
启用最佳实践
持续部署工具通过确保部署流程的标准化、模板的可重用性、不可变映像的部署、完全自动化和快速的应用部署,以及在出现问题时执行回滚的能力,在整个组织中实现最佳实践。这些工具还通过为深入诊断提供简单直观的界面和相关日志,使调试更容易,并有助于更快地解决与部署相关的事件。
零停机部署
在推出新的应用版本时,应用和业务所有者已经开始期望没有应用停机时间,或者至少是最小的停机时间。利用 Jenkins、Spinnaker 和 Google Deployment Manager 等解决方案,并使用 blue-green/canary/dark releases 等部署策略,运营团队能够以自动化方式管理 GCP 上的发布,最大限度地减少停机时间。虽然 GCP 本地和第三方工具在自动化发布中起着重要作用,但部署模式在实现最小或零停机时间方面也起着至关重要的作用。以下小节将介绍一些更常见的零停机部署策略。
蓝绿色部署
使用蓝绿色部署策略,有两个相同应用版本的生产实例(蓝色和绿色),它们相互隔离。只有蓝色实例接收所有生产流量。在发布过程中,新的代码版本部署在绿色实例中,并执行各种测试(如负载、功能和安全测试)。如果成功通过所有测试,绿色实例将被提升为接收所有生产流量(使用负载平衡器、DNS、反向代理等解决方案)。在使用这种方法时,应用团队必须记住长时间运行的数据库事务和应用会话带来的复杂性。
在 GCP 上使用这种方法(如图 1-1 所示)将需要应用的蓝色和绿色实例在 GCP 上运行,这会产生成本。通过利用 Google Deployment Manager 旋转蓝色和绿色实例,这变得相当简单,并有助于控制成本。绿色环境仅在与蓝色环境具有相同规格的版本中部署,使用 infra as code 原则。Jenkins X 和 Spinnaker 等解决方案在 CI/CD 管道中模拟蓝绿色模式。
图 1-1
蓝绿色部署
滚动更新
这种部署策略(也称为渐变部署策略)包括通过逐渐替换旧实例来推出新版本。虽然这种方法可以解决长期运行的事务问题,或者在推出新版本时维护状态,但是总的部署时间可能相当长(取决于要执行的总体测试和要替换的组件)。如图 1-2 所示,通过滚动更新部署,旧版本将被批量更新的实例所取代,流量将通过 GCP 负载均衡器进行管理。
图 1-2
滚动更新方法
金丝雀
金丝雀方法(也称为金丝雀或增量部署)与蓝绿方法类似,唯一的区别是新版本的应用逐渐接收生产流量(如新旧版本之间的 90-10、75-25 和 50-50),而不是完全的流量切换(如图 1-3 所示)。
图 1-3
金丝雀部署
如果在测试过程中检测到问题,所有流量都将转移到旧的稳定版本。利用 GCP 本地负载平衡器有助于实现逐步流量切换功能,然后可以与部署管理器一起利用该功能来设置新环境。
这种方法与 A/B 测试密切相关,通过这种方法,可以在一部分用户中测试新特性(通常用于测试 UX 或应用级别的功能)。除了用于 A/B 测试和 canary 部署的负载平衡器的流量分配功能之外,应用开发人员还可以使用各种条件,如浏览器 cookies 或版本、地理位置等。
注册谷歌云
让我们从 GCP 开始吧。第一步是报名 GCP。以下部分包含注册所需的步骤,适用于初次用户。
注册该平台的首要先决条件是一个谷歌账户。GCP 使用谷歌账户进行访问管理和认证。如图 1-4 所示,您只需在浏览器窗口中输入 https://cloud.google.com/free#
网址。
图 1-4
谷歌云平台
点击免费开始按钮。然后你会看到登录界面,如图 1-5 所示。
图 1-5
GCP 登录屏幕
系统会提示您输入一个 Google 帐户。如果您没有帐户,请按照创建帐户流程创建一个帐户。
Note
如果您已经登录到您的 Google,您将被重定向到图 1-6 所示的 GCP 云控制台。选择适当的国家,然后单击协议复选框。然后点击同意并继续。
图 1-6
GCP 云平台
如果您符合免费层的条件,系统会提示您输入帐户详情,如图 1-7 所示。
图 1-7
GCP 自由层注册,步骤 1
选择您的国家,同意服务条款,然后单击同意并继续按钮。这将带您进入第二步,如图 1-8 所示,在这里您可以创建并选择您的支付模式。提供所需的账单详情;但是,请放心,除非您手动请求,否则自动借记不会发生。
图 1-8
GCP 自由层注册,步骤 2
当您创建付款资料并登录时,右侧面板会显示详细信息,如图 1-9 所示。
图 1-9
GCP 自由层信息
如图 1-9 所示,谷歌向所有用户提供 300 美元的信用额度,可以在 12 个月内使用。这不仅足以探究书中所有的练习,也足以进一步评价 GCP。一旦您指定了所有的细节,点击开始我的免费试用按钮。
注册需要一段时间才能完成。一旦必要的验证完成,你将被重定向到谷歌控制台,你就可以开始了。
使用虚拟机创建控制台
点击创建按钮,创建一个新的虚拟机选项,如图 1-10 所示。
图 1-10
虚拟机创建控制台
单击页面右上角的激活按钮。它会提示你升级。点击升级,如图 1-11 所示。
图 1-11
虚拟机创建控制台
根据提示刷新页面(参见图 1-12 )。
图 1-12
当询问您时,选择刷新
一旦激活过程完成,将显示图 1-13 中的屏幕。
图 1-13
激活屏幕后
为谷歌 GKE 设置环境
本节描述了为谷歌 GKE 设置环境的步骤。
创建项目
首先,您需要创建一个项目,如下所示:
图 1-15
新项目视图
-
转到云控制台中的管理资源页面。
-
在页面顶部的选择组织下拉列表中选择您的组织。
注意如果您使用的是免费试用版,此列表不会出现。
-
单击新建项目。
-
In the New Project window, enter your project name, as shown in Figure 1-14.
图 1-14
新项目详细信息屏幕
项目 ID 是所有 Google Cloud 项目的唯一名称(我们选择的名称不适合您)。这是本书其余部分使用的
PROJECT_ID
。 -
输入完新项目的详细信息后,单击创建。新项目将被选中并出现,如图 1-15 所示。
发射云壳
使用右上角工具栏上的 GCP 控制台云壳图标激活 Google 云壳,如图 1-16 所示。
图 1-16
云壳按钮
将出现图 1-17 所示的屏幕。单击继续。
图 1-17
云壳屏
接下来,点击启动云壳按钮,如图 1-18 所示,启动云壳会话。
图 1-18
云壳开始屏幕
配置和连接到环境应该需要一些时间。这是一次性活动;下次点击云壳按钮,将会看到图 1-19 中的屏幕。
图 1-19
云壳屏
这个虚拟机提供了一个持久的 5GB 主目录,它运行在 Google Cloud 上。你已经通过认证了。请注意,项目被设置为您的PROJECT_ID
。
在云 Shell 中运行以下命令,以确认您已经过身份验证:
gcloud config list project
该命令的输出如图 1-20 所示。
图 1-20
list project 命令的输出
摘要
本章包括 GCP 服务和支持自动化构建模块的简要概述。您还了解了如何创建 GCP 帐户,这将在后续章节的实践练习中用到。下一章从 GCP 部署管理器服务开始,并向您展示如何使用它来自动化设置 GCP 服务的过程。
二、GCP 开发管理器入门
在本章中,我们将介绍 GCP 部署管理器服务的核心概念,并解释如何使用它来实现基础设施即代码(IaC ),以管理和供应 Google 云基础设施。本章涵盖以下主题:
-
部署管理器简介
-
了解部署管理器的组件
-
部署管理器的实践用例
部署管理器简介
DevOps 和基础设施即代码(IaC)正在获得全球开发者、管理员、架构师和云工程师的青睐。DevOps 是一种包含人员、流程和工具的哲学。它的目标是加速软件开发以及相关的发布和部署过程。在 DevOps 的总体框架中,IaC 是一个重要的组件,它从基础设施方面提供敏捷性和可伸缩性,以满足开发团队的需求。IaC 还支持稳定、安全和一致的平台来托管应用。
市场上有许多工具可用于实现 IaC。如今,Terraform 和 Ansible 在 DevOps 和开发人员社区中越来越受欢迎。同样,公共云托管平台提供原生解决方案,这些解决方案被打包为公共云服务产品的一部分,如 AWS 的 Amazon Cloud Formation 和 Azure 的 Azure Resource Manager。
在 GCP,云原生 IaC 原生产品被称为部署管理器。部署管理器提供了一种使用声明性语言定义 Google 云基础设施资源的机制。Deployment Manager 使用户能够使用 IaC 原则来设计和构建他们的 GCP 资源,以便他们可以使用软件开发的源代码控制和版本控制机制来维护对所提供内容的粒度控制,并自动执行提供过程。
部署管理器使您能够使用声明性配置(使用 Jinja 和 Python 语言)管理您的 GCP 基础设施。它帮助您编写灵活的模板和配置文件,然后使用它们来创建各种 GCP 服务,如 GKE、虚拟机、VPC、网络等等。
部署管理器的主要特性
作为 Google 部署管理器中的一个概念,部署只不过是 GCP 的另一个资源。通过更新部署文件和运行 update 命令对部署配置所做的任何修改,都只会通过将新配置与早期部署进行比较来引发所需的更改。这确保了通过有限的努力,从配置中移除的任何资源也从 GCP 基础设施中移除。图 2-1 总结了部署管理器的主要特性。
图 2-1
部署管理器功能
Python 和 Jinja
要理解 Python 和 Jinja 的关系,我们需要理解什么是模板引擎。开发人员使用模板作为中间格式,以编程方式生成不同的所需输出格式,如 HTML 或 XML。这个活动是在模板引擎的帮助下执行的,模板引擎接受输入标记化的字符串,并生成一个呈现的字符串,用一个值代替标记作为输出。模板引擎通过使用一些数据和编程结构(如条件和循环)来操作输出。由开发人员创建然后由模板引擎处理的模板文件由预先编写的标记和插入数据的模板标记块组成。
Python 使用了几个模板引擎,比如可比、Django、string。模板,还有 Jinja2。这些模板引擎在允许代码执行和使用模板标签授予有限的功能集方面是不同的。
Jinja 或 jinja2 是最广泛使用的 Python 模板引擎,它是作为开源项目编写的。其流行的原因是其他模板引擎,如 Django 模板,可以作为大型 web 框架的一部分使用,这使得在项目之外使用它们很麻烦,因为它们与它们的库紧密耦合。许多 Python 开源应用,如配置管理工具 Ansible 和 SaltStack,默认使用 Jinja 模板来生成输出文件。
要了解关于 Python 和 Jinja 的更多信息,请参考以下链接:
-
忍者!忍者
了解部署管理器组件
部署管理器 GCP 服务是管理谷歌云环境的一种非常有效的方式。在使用部署管理器管理 GCP 资源生命周期之前,您需要首先理解它的关键概念。
部署管理器的工作原理是,一组 GCP 资源形成一个逻辑单元,称为部署,一起部署。部署单元可以是任何 GCP 资源,如 GKE 集群、虚拟机、数据库、网络、IPs 等等。Deployment Manager 借助于使用声明性语句设置的模板,通过部署、更新和删除云资源来管理云基础设施。部署管理器在以下组件的帮助下执行部署的实施活动:
-
配置文件
-
资源
-
类型
-
模板
-
显示
-
部署
配置文件
配置文件是一起创建和管理的 GCP 资源的集合。配置文件以 YAML 模板的形式编写,包含要部署的资源的定义。部署管理器使用单个配置文件来管理多个资源。YAML 格式的配置文件的基本结构如图 2-2 所示。
图 2-2
配置文件示例
典型的配置文件包含以下部分:
-
Type: 表示要作为虚拟机、IP 地址等进行配置的 GCP 资源的类型。
-
Name: 一个名称字段,用于标识使用部署管理器设置的资源。这将作为将来对 GCP 资源集进行任何修改或删除操作的关键。
-
属性:定义将要创建的 GCP 资源的参数和属性,如机器类型、网络接口、启动盘等。这些值与从 GCP 控制台或云外壳手动创建服务时所需的值相同。
配置文件还包含一个类似这样的部分:
- Import: 包含配置所需的所有模板文件的列表,最终由部署管理器扩展。
配置文件的其他可选部分包括:
-
输出:当需要将一个模板和配置中的数据输出到另一个模板供最终用户使用时使用。
-
元数据:用于设置资源之间的显式依赖关系。
部署管理器施加了以下限制:
-
配置的大小。原始格式和扩展格式都不能超过 1MB。
-
执行配置文件所花费的时间或处理能力也是有限的。如果超过这些,解决方案是将配置文件分成多个配置。
-
Python 模板不能进行任何系统或网络调用。如果他们尝试,他们将被拒绝。
让我们使用 YAML 文件创建一个简单的部署,如图 2-3 所示,其中我们在 Google 计算引擎服务中创建一个虚拟机。
图 2-3
简单配置文件
资源部分
配置文件中的资源部分描述了单个 API 资源。当我们编写配置文件时,我们可以选择使用 Google 管理的基本类型提供的 API 资源,或者使用第三方类型提供者提供的 API 资源。计算引擎实例和云 SQL 实例是 Google 云服务资源的例子。
类型
您必须为每个资源定义一个类型。描述资源需要类型。该类型可以是基类型或复合类型,如下所述。
基本类型
当您必须创建单个原始 Google Cloud 资源时,您可以选择基本类型。基本类型使用 RESTful APIs 对资源执行 CRUD(创建、读取、更新和删除)操作。常用的 Google owned base 类型有compute.v1.instance
和storage.v1.bucket
。可以分别使用compute.v1.instance
API 和storage.v1.bucket
API 来访问它们。
要获得受支持资源类型的完整列表,包括 alpha 中的资源,请在gcloud
中运行这个 types list
命令:
gcloud deployment-manager types list
示例输出如图 2-4 所示。
图 2-4
部署管理器类型列表
复合类型
当您必须创建一组原始的 Google Cloud 资源时,您需要多个模板作为一个单元一起工作,这可以使用 Python 或 Jinja 来完成。复合类型通常用于定义模板的一部分,可以很容易地重用。例如,您可以为网络创建负载平衡器资源。
每个资源都必须在配置文件中定义为一个类型。该类型可以是 Google 托管类型、复合类型、类型提供者或导入类型。这些类型可以在配置文件中定义。
Google 托管类型
这些类型与 Google 自己的托管基础云资源类型相关,如云存储桶或计算实例。在配置文件中定义它的语法如图 2-5 所示。
图 2-5
Google 管理的类型模板片段
Example: For Compute Engine instance type and Cloud Storage
bucket type
type: compute.v1.instance
type: storage.v1.bucket
复合或类型提供程序
在配置文件中定义复合和类型提供者的语法如图 2-6 和 2-7 所示。
模板:复合
图 2-6
复合提供程序模板片段
模板:类型提供者
图 2-7
类型提供程序模板片段
导入的模板
在配置文件中定义导入模板的语法如图 2-8 所示。模板导入一个名为my_vm_template.jinja
的模板来创建一个名为my-first-virtual-machine
的计算引擎实例。
图 2-8
导入的模板片段
模板:模板导入
模板
模板是配置文件的一部分。这些是包含一组资源详细信息的单个文件。对于复杂的部署,我们可以创建包含资源集信息的不同模板,从而在不同的部署之间提供一致性。部署管理器以内嵌的方式扫描和解释每个模板。
让我们创建一个基本模板。考虑下面的配置文件,它用于创建一个名为vm-created-by-deployment-manager
的计算引擎虚拟机,如图 2-9 所示。
图 2-9
配置文件基本模板片段
现在我们将为这个配置创建一个模板,方法是取出相关的部分并创建一个新的 Jinja 文件。参见图 2-10 所示的模板片段。
图 2-10
Jinja 文件中的基本模板
部署管理器还创建包含部署信息的预定义环境变量。当我们在模板中使用这些环境变量时,部署管理器设置这些变量并替换它们的值。例如,project_number
是一个保存部署的项目编号的环境变量。当在模板中使用它时,它被替换为该部署的实际project_number
值。用于声明环境变量的语法如图 2-11 所示。
图 2-11
环境变量模板片段
图 2-11 显示了 GCP 提供的内置环境变量,该变量在代码中用于自动获取项目 ID。(参见表 2-1 。)图 2-12 显示了 Jinja 模板中环境变量的使用示例。
图 2-12
Jinja 模板片段中的环境变量示例
表 2-1 列出了部署管理器使用的环境变量集。
表 2-1
环境变量列表和描述
|环境变量名
|
描述
|
| --- | --- |
| Deployment
| 部署的名称 |
| Name
| 使用此模板的配置文件中声明的名称 |
| project
| 本次部署的Project_Id
|
| project_number
| 本次部署的project_number
|
| current_time
| 此部署开始扩展时的 UTC 时间戳 |
| type
| 顶级配置中声明的资源类型 |
| username
| 当前部署管理器用户 |
显示
每个部署都有相应的清单。清单是描述部署中所有资源的只读属性,并且是在每次新部署时自动创建的。清单创建后不能修改。清单不同于配置文件,而是基于配置文件创建的。您可以通过清单的惟一 ID 来识别它,ID 的格式是manifest-TIMESTAMP
。例如,查看图 2-13 中所示的例子。
图 2-13
清单 ID 示例
清单提供了部署的三个视图,即初始配置视图、完全评估的配置视图和部署布局。我们将在接下来的章节中逐一讨论。
初始配置视图
原始配置是您在任何模板扩展之前提供给部署的配置。初始配置由config
属性表示,如图 2-14 所示。
图 2-14
清单的初始配置视图
完全评估的配置视图
该视图在所有模板和导入展开后显示。扩展配置是对您的部署的完整描述,包括处理所有模板后的所有资源及其属性。这是您配置的最终状态。清单的扩展配置部分由expandedConfig
属性表示,如图 2-15 所示。
图 2-15
清单的扩展配置
部署的布局
该视图以分层结构描述了部署的所有资源。布局是您的部署及其资源的概要,并显示资源名称和类型。您可以使用布局来可视化您的展开结构、在初始展开期间设置的视图样板属性以及展开前有关您的配置的其他信息。在您的 manifest 中,您可以看到layout
属性中的布局,如图 2-16 所示。
图 2-16
清单的布局视图
部署
一个部署是作为一个单元一起部署和管理的 GCP 资源的集合。我们可以使用配置文件和 GCP 云 Shell 的 create 命令来创建部署。用于执行部署的命令如图 2-17 所示。
图 2-17
在 GCP 创建新部署的命令
要定义配置文件,您必须使用--config
选项,后跟配置文件的名称。当部署完成后,您可以使用图 2-18 中所示的命令来查看是否配置正确。
图 2-18
描述部署的命令
部署管理器的实际使用案例
既然我们已经介绍了 GCP 部署管理器的基本概念,那么让我们进入代码开发部分,开始在部署管理器的帮助下创建云基础设施。在开始之前,我们必须设置 GCP 环境以使用部署管理器。您可以通过以下链接访问本教程中使用的所有文件:
https://github.com/dryice-devops/GCPAutomation
步骤 1:为了使用部署管理器,您需要一个 Google 项目。我们为本教程创建了一个名为LearnDMProject
的项目,因此我们将选择该项目,如图 2-19 所示。您可以通过单击屏幕右上角的“新建项目”选项来创建新项目。
图 2-19
选择 LearnDMProject 项目
第二步:第一次点击部署管理器时,如图 2-20 所示,会提示您启用云部署管理器 V2 API,如图 2-21 所示。
图 2-20
选择部署屏幕
点击启用按钮,如图 2-21 所示,启用部署管理器 API。
图 2-21
启用部署管理器 API 屏幕
单击 Enable 按钮后,该 API 将可用于该项目。您将看到部署管理器屏幕,如图 2-22 所示。
图 2-22
部署管理器控制台
第三步:作为先决条件,你也可以安装名为gcloud
的 Cloud SDK 命令行工具,或者你可以使用 Google Cloud Shell,它默认启用了gcloud
。在本教程的剩余部分,我们将使用 Google Cloud Shell。
一旦满足了先决条件,就可以使用部署管理器来配置 GCP 资源。我们将首先处理一个用例,在这个用例中,我们将配置一个由虚拟机组成的部署。
步骤 1:第一步是激活云 Shell,它提供对 Google 云资源的命令行访问。在云控制台中,点击右上方工具栏中的激活云壳按钮,如图 2-23 所示。
图 2-23
激活云壳
点击激活云壳图标后,您将看到如图 2-24 所示的屏幕。单击继续按钮继续。
图 2-24
云壳信息屏幕
云壳终端现已可用,项目设置为PROJECT_ID
,如图 2-25 所示。
图 2-25
云壳终端
步骤 2:为了开始为配置文件编写代码,我们将使用云外壳编辑器。点击打开编辑器按钮,如图 2-26 所示。
图 2-26
云 Shell 终端中的“打开编辑器”按钮
可以查看云编辑器和云终端,如图 2-27 所示。
图 2-27
云壳编辑器和终端视图
步骤 3:正如您之前看到的,我们将通过创建一个配置文件来定义我们的基础设施。我们将首先创建网络和子网配置。
创建网络和子网
在本节中,我们将使用部署管理器创建 GCP 网络和子网。这些网络和子网的一般表示如图 2-28 所示。
图 2-28
通用 VPC 网络
这个 VPC 网络在us-west1
区域将subnet1
定义为10.240.0.0/24
,在us-east1
区域将subnet2
定义为10.2.0.0/16
。Subnet1
在Subnet1
的可用地址范围内有两个 IP 为10.240.0.2
和10.240.0.3
的虚拟机。类似地,Subnet2
有两个虚拟机,其 IP10.2.0.2
和10.2.0.3
位于定义的子网范围内。
对于本教程,我们将创建以下三个配置文件:
-
networkconfig.yaml
:配置 YAML 文件,我们在其中定义资源(网络和子网)类型和属性。 -
network.py
:这将被导入到配置文件中,包含网络/子网定义以及特定的环境变量。 -
network.py.schema
:描述了部署管理器的规范。它包含部署管理器在使用network.py
模板时将强制执行的一组规则。
对于这个用例,实施解决方案架构可以如图 2-29 所示。
图 2-29
实现架构
现在,按照以下步骤进行实施:
-
Create a file called
networkconfig.yaml
in the Cloud Shell Editor by navigating to File ➤ New ➤File, as shown in Figure 2-30.图 2-30
新文件视图
Once it’s created, the file will appear in the Explorer along with the text editor, as shown in Figure 2-31.
图 2-31
创建网络配置文件
Now paste the following code into the
networkconfig.yaml
file and save the file, as shown in Figure 2-32.图 2-32
网络配置代码
-
Create another file called
network.py
in the Cloud Shell Editor by choosing File ➤ New ➤ File, as shown in Figure 2-33.图 2-33
新文件视图
Now paste the following code into the
network.py
file and save the file. This file is used to describe the network and subnetwork configuration and is imported by thenetworkconfig.yaml
file to create the network setup, as shown in Figure 2-34.图 2-34
网络配置代码
-
Create another file called
network.py.schema
in the Cloud Shell Editor by choosing File ➤ New ➤ File, as shown in Figure 2-35.图 2-35
新文件视图
Now paste the following code into the
network.py.schema
file and save it, as shown in Figure 2-36.图 2-36
网络配置模式代码
-
现在我们已经创建了配置文件,我们将使用以下命令执行部署:
gcloud deployment-manager deployments
create networsubnetworkdm –config networkconfig.yaml
该命令将执行网络和子网的部署,并将产生如图 2-37 所示的输出。
图 2-37
部署命令 CLI
您可以在 GCP 控制台上通过导航到主➤ VPC 网络来验证部署。这样做将显示如图 2-38 所示的屏幕。
图 2-38
VPC 网络屏幕
- 最后,您可以从 CLI 使用以下命令删除创建的网络和子网:
gcloud deployment-manager deployments delete networsubnetworkdm
此命令将删除您创建的网络和子网。在删除过程中,系统会提示您“是否要继续(y/N)?”键入y
以产生如图 2-39 所示的输出。
图 2-39
删除部署 CLI
可以在谷歌云控制台验证 learndmproject-network
被删除,如图 2-40 。
图 2-40
VPC 网络控制台
创建虚拟机
在本节中,我们将使用部署管理器创建一个 VM 实例。我们将编写包含虚拟机创建定义的createVMConfig.yaml
配置文件。
实施方案如图 2-41 所示。
图 2-41
实现架构
现在,按照以下步骤进行实施
图 2-45
编辑器中的 createVMConfig.yaml 代码片段
图 2-44
createVMConfig.yaml 代码片段
-
Create a file called
createVMConfig.yaml
in the Cloud Shell Editor by going to File ➤ New ➤ File, as shown in Figure 2-42.图 2-42
新文件视图
Once it’s been created, the file will appear in the Explorer along with text editor, as shown in Figure 2-43.
图 2-43
新文件视图
-
现在将下面的代码粘贴到
createVMConfig.yaml
文件中并保存,如图 2-44 和 2-45 所示。
在进入下一步之前,您需要理解前面代码中使用的参数和值。我们通过声明提到的资源 VM 实例类型及其名称来启动配置文件,如图 2-46 所示。
图 2-46
资源配置
name
是一个用户定义的字符串,它可以是任何有意义的名称,以后会被引用。接下来,我们将实例的类型定义为compute.v1.instance
。我们可以通过运行以下命令来检查哪些类型可用:
gcloud deployment-manager types list
该命令将列出部署管理器的所有类型。它将产生如图 2-47 所示的输出。
图 2-47
DM 类型列表
我们可以使用下面的命令来过滤结果以找到实例类型。输出将如图 2-48 所示。
图 2-48
过滤的 DM 类型列表
gcloud deployment-manager types list | grep instance
现在让我们看看在tutorialConfig.yaml
文件中为虚拟机定义的属性。
Zone
:描述虚拟机将驻留在哪里。我们可以通过运行以下命令来检查哪些类型可用:
gcloud compute zones list
前面的命令将列出所有可用的区域并产生输出,如图 2-49 所示。
图 2-49
区域列表
machineType
:您可以使用以下命令检查machineType
。由于本例中的区域是us-central1-a
,我们可以在这个区域上过滤我们的列表搜索。
gcloud compute machine-types list | grep us-central1-a
该命令将列出us-central1-a
中所有可用的机器类型,并将产生如图 2-50 所示的输出。
图 2-50
在区域上过滤的机器类型
从前面的列表中选择机器类型后(本例中为f1-micro
,我们需要在配置文件中定义f1-micro
机器类型的selfLink
URL。为了获得selfLink
URL,我们将使用之前在配置文件中定义的相同区域选择(即us-central1-a
)来执行以下命令。
gcloud compute machine-types describe f1-micro --zone us-
central1-a | grep selfLink
该命令将显示配置文件中使用的selfLink
URL,并将产生如图 2-51 所示的输出。
图 2-51
机器类型自链接
-
disk
:disk
配置将具有以下值: -
initializeParams
:这将有启动盘的初始化参数。您可以使用以下命令检查图像列表:
- deviceName: boot
- type: PERSISTENT
- boot: true
- autoDelete: true
gcloud compute images list
该命令将显示可用图像列表,并将产生如图 2-52 所示的输出。
图 2-52
计算图像列表
在这个例子中,我们将创建一个 Linux 实例,因此我们将过滤 Debian-9 映像上的搜索列表。我们可以使用以下命令获得图像列表:
gcloud compute images list | grep debian
该命令将显示可用的 Debian 映像列表,并将产生如图 2-53 所示的输出。
图 2-53
过滤的计算图像列表
它显示了两个 Debian 映像,所以我们将获得 Debian-9 映像的selfLink
URL,并将其放在我们的配置文件中。
gcloud compute images describe debian-9-stretch-v20200714 --project debian-cloud | grep selfLink
该命令将显示配置文件中使用的selfLink
URL,并将产生如图 2-54 所示的输出。
图 2-54
计算机图像自动链接
network
:要列出项目可用的网络,使用以下命令。
gcloud compute networks list
该命令将显示配置文件中使用的网络列表,并将产生如图 2-55 所示的输出。
图 2-55
网络列表
我们有一个默认网络可用,所以我们现在将为默认网络生成selfLink
,以便在配置文件中使用它。
gcloud compute networks describe default | grep selfLink
该命令将为默认网络生成selfLink
,并将产生如图 2-56 所示的输出。
图 2-56
默认网络自动链接
配置文件中的最后一个条目将accessConfigs
添加到默认网络。有两个参数,定义如下:
-
name
:External NAT
-
type
:ONE_TO_ONE_NAT
有关更多属性,请参考以下链接:
https://cloud.google.com/compute/docs/reference/rest/v1/instances
现在我们已经创建了配置文件,我们可以继续下一步并部署它。
gcloud deployment-manager deployments create my-first-deployment --config createVMConfig.yaml
该命令将部署我们创建的配置文件,并将产生如图 2-57 所示的输出。
图 2-57
虚拟机部署 CLI
在图 2-57 中可以看到,名为createfirstvm
的配置文件已经被部署管理器成功执行。此外,您还可以验证配置文件的执行和 Linux 虚拟机的创建,如图 2-58 所示。
图 2-58
部署管理器控制台
导航到谷歌云控制台➤部署经理➤仪表板控制台。它将显示名为my-first-deployment
的部署列表,如图 2-58 所示。
您还可以验证 Debian-9 Linux VM 是否已经创建。导航到谷歌云控制台➤计算引擎➤虚拟机实例。它将显示一个用名称createfirstvm
创建的虚拟机,如图 2-59 中的配置文件所定义。
图 2-59
计算引擎控制台
在配置文件中,我们将网络定义为默认网络。我们可以通过单击createfirstvm
来验证这一点,这将显示所创建虚拟机的详细信息,如图 2-60 所示。
图 2-60
计算引擎网络详细信息
删除部署
如果部署不是根据您的要求创建的,或者其中有错误,您可以使用以下命令将其删除:
gcloud deployment-manager deployments delete my-first-deployment
此命令将删除部署。在删除过程中,您会得到一个提示,“您要继续吗(y/N)?”。键入y
以查看如图 2-61 所示的输出。
图 2-61
删除部署 CLI
现在让我们在 Google Cloud 控制台中验证部署管理器和 VM 实例控制台,以确认部署和 VM 已经被删除。见图 2-62 。
图 2-62
部署管理器控制台
类似地,我们可以验证虚拟机已经从计算引擎控制台中删除,如图 2-63 所示。
图 2-63
计算引擎控制台
摘要
本章详细介绍了部署管理器的主要概念,并解释了如何定义配置文件,以便在代码的帮助下执行环境供应和维护。您还进行了创建网络、子网和 GCP 单实例虚拟机的实践练习。下一章将介绍 Spinnaker,它是一个强大而灵活的 Kubernetes-native 开源框架,用于创建持续集成和交付(CI/CD)系统。
三、GCP Spinnaker 入门
Spinnaker 是一个流行的持续部署工具,它支持主要的云提供商在 Kubernetes、Function as a Service (FaaS)等平台上部署应用。本章涵盖了 Spinnaker 架构、组件和用例。您还将学习如何在 GCP 上安装和配置 Spinnaker。
本章涵盖以下主题:
-
三角帆的特点
-
三角帆的建筑
-
GCP 大三角帆
-
在 GCP 上安装三角帆
-
使用 Spinnaker
-
Spinnaker 的金丝雀部署用例
三角帆的特点
Spinnaker 是一个开源的持续部署工具,它本身支持将应用部署到主要的云提供商,如 GCP、AWS 等。Spinnaker 由谷歌和网飞联合开发,旨在加速他们的软件交付。Spinnaker 现在是开源的,其不断增长的社区正在积极开发新功能,并推动产品向前发展。主要贡献者是谷歌、网飞、微软、亚马逊和其他公司。Spinnaker 的源代码可以在 GitHub 的 https://github.com/spinnaker
获得。
Spinnaker 是 GCP 的一个市场解决方案,只需点击几下就可以安装。Spinnaker 不支持持续集成;但是,它提供了与 Jenkins 等市场领先 CI 工具的集成。市场上还有提供 CI/CD 实施的其他工具。表 3-1 是 Jenkins、JenkinsX 和 Spinnaker 的功能比较。
表 3-1
特征比较
|特征
|
Jenkins
|
Jenkins
|
大三角帆
|
| --- | --- | --- | --- |
| 图像使用者界面 | |
|
|
| 管道作为代码 | 宣言的 | 亚姆 | 数据 |
| kubernetes-本地(基于控制器) | |
|
|
| 海峡群岛 | |
|
|
| 激光唱片 | |
|
|
| WebHook 触发 | |
|
|
| Git 轮询触发 | |
|
|
| 模板支持 | | 通过脚本 DIY |
|
可用
不可用
现在让我们看看 Spinnaker 的主要特性:
-
多云支持 : Spinnaker 支持主要的云提供商,如 Google、Amazon 等等。
-
连续交付工具 : Spinnaker 是一个连续交付工具,因为它以安全和自动化的方式部署应用。
-
开源:Spinnaker 得到了大型开发者社区的支持,包括谷歌、网飞、亚马逊等等。
-
支持主要部署策略 : Spinnaker 支持许多部署策略,包括 blue-green、滚动更新、canary 和具有轻松回滚功能的 highlander。
三角帆建筑
Spinnaker 是一个基于微服务的架构,其中有 11 个独立的微服务。以下是这些微服务的列表:
-
Deck:Spinnaker 基于浏览器的 UI 和前端服务。
-
Gate :一个 API 网关;Spinnaker 的所有微服务都通过这个网关相互通信。
-
Orca :负责所有特别操作的编排引擎。这个微服务还负责保存有关管道执行的信息。
-
CloudDriver :负责建立与云提供商的连接,缓存所有部署的资源。它是与云提供商集成的主要服务。
-
Front50 :负责在应用、管道、项目、通知中持久化元数据。
-
Rosco :负责烘焙不可变的 VM 镜像,比如 GCE 镜像、AWS AMI 等等,它们将被部署到特定的云。它使用打包工具来创建虚拟机映像。
-
Igor :用于连接像 Jenkins 或 Travis CI 这样的 CI 工具。它允许在自己的管道中使用 Jenkins/Travis CI 阶段。没有这项服务,您就无法与任何 CI 工具集成。
-
Echo :用于通过 Slack、email 或者 SMS 发送通知,负责所有传入的 WebHooks,比如 GitHub 到 Spinnaker。
-
Fiat :负责 Spinnaker 中的用户授权。它用于查询应用和服务帐户的用户权限。
-
Kayenta :负责 spinnaker 的自动金丝雀分析。
-
Halyard:Spinnaker 的配置服务,在 Spinnaker 启动、更新和回滚期间维护这些服务的生命周期。
图 3-1 显示了哪些微服务相互依赖。绿框代表“外部”组件,包括在浏览器中运行的 Deck UI。黄色框表示 Halyard 组件,它们仅在启动、更新和回滚期间配置 Spinnaker 时运行。
图 3-1
Spinnaker 微服务架构
应用管理和部署是 Spinnaker 的两个主要组件。让我们来详细了解一下这些组件。
应用管理
应用管理用于查看和管理云资源。它表示需要由用户部署的服务。应用、集群和服务器组是 Spinnaker 用来描述服务的关键概念。负载平衡器和防火墙描述了服务是如何暴露给外部用户的,如图 3-2 所示。
图 3-2
Spinnaker 应用管理
应用管理包括托管服务的以下基础架构。
-
集群:Spinnaker 中服务器组的逻辑分组。例如,在 GCP,它将是 GKE 集群节点。
-
服务器组:基础资源,即服务器组,标识可部署的工件,例如 VM 镜像、Docker 镜像和源位置,以及基本的配置设置,例如实例数量、自动伸缩策略等等。部署时,服务器组是运行软件实例的集合。例如,在 GCP,这将是虚拟机。
-
防火墙:通过一组防火墙规则定义网络流量访问,这些规则由具有通信协议和端口/端口范围的 IP 范围定义。
-
负载平衡器:与入口协议和端口范围相关。它平衡其服务器组中实例之间的流量。
应用部署
Spinnaker 用于通过管道和阶段执行应用的连续部署。管道由一系列动作组成,称为阶段,可以按任何顺序组合。阶段又包含任务,任务是具体的行动,如图 3-3 所示。
Spinnaker 提供了许多阶段,比如部署、禁用、手动判断等等。基于某些事件,可以手动或自动触发管道。例如,一旦 Jenkins 构建了代码并放置了可部署单元,就会触发 Spinnaker 管道进行部署。Spinnaker 支持广泛使用的云本地部署策略,包括蓝绿色、滚动红/黑和金丝雀部署。
图 3-3
三角帆管道流
GCP 大三角帆
GCP 的 Spinnaker 平台带有内置的部署最佳实践,用户可以利用 Google 托管服务,如 Google Kubernetes 引擎、Google 计算引擎、合规性、安全性等。
表 3-2 列出了 Spinnaker 在 GCP 的优势。
表 3-2
三角帆在 GCP 的优势
| **安全安装** | Spinnaker for GCP 提供一键式 HTTPS 配置和云身份感知代理(IAP),后者控制谁可以访问 Spinnaker 安装。 | | **自动备份** | Spinnaker 安装的配置会自动安全备份,这有助于用户进行审计和快速恢复。 | | **集成审计和监控** | Spinnaker for GCP 集成了 Spinnaker 和 Google Stackdriver,用于监控、故障排除和审计应用和 Spinnaker 本身的更改、部署和整体健康状况。 | | **易于维护** | 面向 GCP 的 Spinnaker 提供了许多助手来自动维护 Spinnaker 安装,其中包括面向 GKE 的 Spinnaker 配置。 |Google 在 GKE 集群上提供了一个生产就绪的 Spinnaker 实例。基于云 Shell 的安装工具遵循推荐的做法,如防火墙、服务帐户、实例组和 bucket 来存储在 Google 云平台上运行 Spinnaker 的 Spinnaker 相关数据。该解决方案还与谷歌提供的其他服务(如谷歌云平台)进行了很好的集成,包括 Stackdriver(现为谷歌运营)、云构建、容器注册、谷歌 Kubernetes 引擎、谷歌计算引擎、谷歌应用引擎和云身份感知代理。
在 Google 云平台上安装 Spinnaker
现在让我们从在 GCP 上设置 Spinnaker 开始:
第一步:使用您在第一章中创建的 https://accounts.google.com/
链接和凭证登录 GCP。
步骤 2:在本练习中,我们将创建一个新项目。使用以下步骤在 GCP 创建项目。点击新建项目,如图 3-4 所示。
图 3-4
GCP 上的三角帆装置
在下一个屏幕中提供项目名称。在这种情况下,我们将项目命名为mylearndmproject
。点击创建按钮,如图 3-5 所示。
图 3-5
为 GCP 的 Spinnaker 装置创建新项目
第三步:选择新建的名为mylearndmproject
的项目,如图 3-6 所示。
图 3-6
选择项目
第四步:导航到市场,如图 3-7 所示。
图 3-7
GCP 市场
第五步:搜索“用于 Google 云平台的 Spinnaker”,如图 3-8 所示。
图 3-8
用于谷歌云平台的 Spinnaker
第六步:点击 Spinnaker for Google Cloud Platform,如图 3-9 。
图 3-9
单击 Spinnaker for Google Cloud Platform,选择它
第 7 步:它将打开 Spinnaker for Google Cloud Platform 页面。点击转到 Spinnaker For Google 云平台选项,如图 3-10 所示。
图 3-10
转到 Spinnaker for Google 云平台
第八步:点击链接后,会得到云壳提示,确认将 GitHub repo https://github.com/GoogleCloudPlatform/spinnaker-for-gcp.git
克隆到云壳中。点击确认,如图 3-11 所示。
图 3-11
在云外壳中克隆 Spinnaker 代码
Cloud Shell 显示了一个文件树,其中包含了 Spinnaker 存储库中的文件,如图 3-12 所示。
图 3-12
Spinnaker 为云壳中的 GCP 代码
步骤 9:在终端上使用以下命令配置 Git。将[EMAIL_ADDRESS]
替换为您的 Git 电子邮件地址,将[USERNAME]
替换为您的 Git 用户名。
git config --global user.email \
"[EMAIL_ADDRESS]"
git config --global user.name \
"[USERNAME]"
步骤 10:现在通过在终端上执行以下命令,在您的项目中提供 Spinnaker(在我们的例子中,它是mylearndmproject
)。
PROJECT_ID=mylearndmproject\
~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup_properties.sh
该命令的输出如图 3-13 所示。
图 3-13
我的学习项目 GCP 大三角帆
步骤 11:通过执行以下命令,将安装 Spinnaker。此安装命令可能需要大约 20 分钟才能完成。当输出显示Installation complete
时,安装完成。观察云壳命令行,看看什么时候完成。
~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup.sh
该命令的输出如图 3-14 和 3-15 所示。
图 3-15
用于 GCP 安装脚本执行的 Spinnaker
图 3-14
用于 GCP 设置的三角帆
步骤 12:重启云壳加载新的环境设置,如图 3-16 所示。
图 3-16
重启 GCP 云外壳
进入三角帆
安装 Spinnaker 后,您可以执行一个命令来转发端口以访问 Deck UI 并开始使用 Spinnaker。使用以下步骤访问 Spinnaker UI。
第一步:在云壳终端执行以下命令:
~/cloudshell_open/spinnaker-for-gcp/scripts/manage/connect_unsecured.sh
该命令将本地端口 8080 转发到端口 9000,供 Deck UI 使用。见图 3-17 。
图 3-17
GCP 港转运用三角帆
第二步:点击高亮显示的预览按钮,选择 8080 端口预览,如图 3-18 所示。
图 3-18
查看 GCP GUI 的 Spinnaker
这将打开 Spinnaker UI,如图 3-19 所示。
图 3-19
Spinnaker GUI
Spinnaker UI 将显示各种选项,例如搜索、项目、应用等等。在下一节中,您将了解 Spinnaker 中的一些关键选项;见图 3-20
图 3-20
Spinnaker GUI 选项
三角帆导航
让我们探索 Spinnaker UI 中的一些可用选项,并看看它们的相关性。
应用
要查看应用,点击应用选项,如图 3-21 所示。
图 3-21
Spinnaker GUI 应用选项
由于 GCP 的 Spinnaker 运行在 Kubernetes 集群上,该集群是在 GCP 安装 Spinnaker 期间创建的,因此在您再次登录到 Spinnaker UI 后,您将看到该应用显示为“Kubernetes”。要查看更多详情,请点击 Kubernetes,如图 3-22 所示。
图 3-22
Spinnaker 应用页面
在特定的应用页面(在本例中是 Kubernetes)上,单击 Config 选项可以深入到与应用相关的信息,比如应用属性、通知、特性等等。见图 3-23 。
图 3-23
Spinnaker 应用详细信息
通知
Spinnaker 可以向管道事件发送通知。它使用各种渠道发送通知,如电子邮件、SMS 和 Slack。
特征
您可以禁用任何不需要的主要功能,如图 3-24 所示。
图 3-24
Spinnaker 应用功能
链接
在“链接”部分,您可以包含自定义链接,这些链接是常用功能的快捷方式,如日志、健康状况等。
交通警卫集群
这种集群总是至少有一个活动实例。如果 Spinnaker 知道尝试删除、禁用或调整服务器组大小的用户或进程会使集群没有活动的实例,则该操作将被停止。表 3-3 显示了相关字段。
表 3-3
流量防护集群字段详细信息
|田
|
必需的?
|
描述
|
| --- | --- | --- |
| 账户 | 是 | 您正在为其设置流量监控的帐户。 |
| 地区 | 是 | 列表中的适用区域,或*
代表所有区域。 |
| 堆 | 不 | 要应用此流量保护的堆栈。将此项留空,以便仅将保护应用于没有堆栈的集群。 |
| 详述 | 不 | 通过应用堆栈详细信息命名约定标识该集群所需的详细信息字符串。 |
应用创建
您必须在中创建应用,才能创建部署管道。要创建应用,请使用以下步骤。
第一步:点击操作,然后创建应用,如图 3-25 所示。
图 3-25
Spinnaker 应用创建
将出现新的申请单,如图 3-26 所示。
图 3-26
Spinnaker 创建表单
申请表包含各种需要填写的选项。有些是强制的,比如名字。表 3-4 列出了更多细节。
表 3-4
Spinnaker 应用表单字段详细信息
|田
|
需要
|
描述
|
| --- | --- | --- |
| 名字 | 是 | 用于标识该应用的唯一名称。 |
| 所有者电子邮件 | 是 | 在您安装的 Spinnaker 中,该应用所有者的电子邮件地址。 |
| 回购类型 | 不 | 承载此应用的代码库的平台。可能是 Stash,Bitbucket,GitHub,Google Storage,AWS S3 桶,Kubernetes 对象,Oracle 对象。 |
| 描述 | 不 | 如有必要,使用此文本字段描述应用。 |
| 仅考虑云提供商的健康状况 | 布尔,默认值 = 否 | 如果启用,云提供商报告的实例状态被认为足以确定任务完成。禁用时,任务需要由其他健康提供者(负载平衡器或发现服务)报告健康状态。 |
| 显示健康覆盖选项 | 布尔,默认值 = 否 | 如果启用,用户可以切换每个任务的先前选项。 |
| 实例端口 | 不 | 该字段用于生成从 Spinnaker 实例详细信息到正在运行的实例的链接。实例端口可以用于或覆盖为应用配置的特定链接(通过配置屏幕)。 |
| 启用重新启动正在运行的管道 | 布尔,默认值 = 否 | 如果启用,用户可以在管道仍在运行时重新启动管道阶段。不推荐这种行为。 |
在本章的后面,你会学到更多关于创建应用的知识。
管道模板
管道控制如何通过一系列阶段部署应用,这些阶段映射到应用部署/发布过程步骤。Pipeline 既可以手动执行,也可以自动执行,通过广泛的外部输入(比如 WebHook,在 Jenkins 作业完成后触发,基于从 Google 云存储上传工件的触发等等)。
创建管道
使用下列步骤创建管线:
步骤 1:选择要在其中创建管道的应用。
第二步:导航到 Spinnaker UI 中的 Pipelines 选项卡,如图 3-27 所示。
图 3-27
Spinnaker 管道选项
第三步:点击管道页签右上角的新建,如图 3-28 所示。
图 3-28
Spinnaker 管道创建
第 4 步:从下拉菜单中选择 Pipeline 并命名管道。然后点击创建按钮,如图 3-29 所示。
图 3-29
Spinnaker 新的管道创建选项
管道的配置信息作为一个 JSON 文件存储在 Spinnaker 中。当 Spinnaker 保存管道时,您使用 UI 对管道所做的任何更改都会被转换为 JSON 文件。创建管道后,您可以根据管道的需要添加任意多个阶段。我们将在“Spinnaker 的 CI/CD 用例”一节中详细介绍这一点。
第五步:要手动触发管道,在管道页签中点击开始手动执行,如图 3-30 和 3-31 所示。然后,Spinnaker 会显示一个确认对话框,您可以在其中添加任何必要的参数。
图 3-31
Spinnaker 管道执行参数
图 3-30
Spinnaker 管道手动执行
管道管理
管道管理用于在管道中执行与管理相关的活动,如重命名、删除、锁定等。您可以在管道管理中执行下列操作。
-
重命名管道:这个动作负责重命名管道。
-
删除管道:该操作允许您删除现有的管道。
-
禁用管道:如果想阻止管道执行,可以将其禁用。
-
锁定管道:锁定管道可以防止所有用户使用 Spinnaker UI 修改它。
-
将管道编辑为 JSON :无论您在 Spinnaker 上为创建应用或管道做了什么更改,Spinnaker 都会将它们转换为 JSON 格式。您可以根据需要编辑 JSON 文件,这些更改将会反映在 UI 中。
-
查看和恢复修订历史:每次保存管道,当前版本被添加到修订历史中。您可以使用不同版本管线的修订历史,或恢复较旧版本的管线。
-
将管道导出为模板:这个特性有助于在团队中标准化和分发可重用的管道。这些管道模板可以在单个应用中使用,也可以跨不同应用使用,甚至可以跨 Spinnaker 的不同部署使用。
管道表达式
通过管道表达式,开发人员可以通过设置变量并在管道执行期间动态使用它们来参数化管道。Spinnaker 提供了各种文本字段来提供这样的输入(例如,端口名、集群 IP 等。)在可以使用这些表达式的流水线阶段。管道表达式的一些用例可能是获取当前阶段名称、禁用特定阶段、检查另一个阶段的状态或获取内部版本号。开发人员也可以将 Java/Groovy 逻辑写入管道表达式。管道表达式语法基于 Spring 表达式语言(SpEL) 。
管道表达式以$
开始,后跟开/闭括号:${ }
。比如:${buildnumber}
Spinnaker 在某个阶段开始时计算该阶段的表达式。管道表达式不能在管道配置阶段使用,因为 Spinnaker 直到配置阶段完成后才开始计算表达式。
密码
Spinnaker 允许在管道表达式中执行 Java 代码。这对于高级的定制逻辑很有用,比如字符串操作。
操作员
Spinnaker 支持关系运算符,如==
、<>
、!=
等等。这些运算符可用于比较表达式中的值。例如,您可以使用关系运算符检查实例大小是否大于 200(参见 https://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html
):
${instance["size"] > 200}
列表
Spinnaker 还支持可以在表达式中使用的列表。Spinnaker 提供了一个名为 stages 的列表,您可以使用它通过索引访问每个阶段。例如,${execution["stages"][0]}
返回管道中第一阶段的值。
地图
您还可以使用映射从管道的 JSON 表示中访问数据。例如,${trigger["properties"]["example"]}
计算出示例触发器属性的值。
数学
可以在表达式中使用算术运算,比如${trigger["buildInfo"]["number"] * 4}
。
用线串
字符串对自己求值:${"Spinnaker"}
比如变成了“Spinnaker”
。
助手功能
Spinnaker 提供了内置的助手函数 1 ,帮助创建常见用途的管道表达式,例如通过名称访问特定阶段、解析 JSON 等等。以下是一些有用的表达方式:
-
#fromUrl(String)
。以字符串形式返回指定 URL 的内容。 -
#currentStage().
返回当前阶段。 -
#toInt(String)
。将值转换为整数。 -
#alphanumerical(String)
。返回传入字符串的字母数字值。
您可以通过在管道中添加一个井号(#
)来获得管道表达式。它显示所有可用的助手功能列表,如图 3-32 所示。
图 3-32
Spinnaker 辅助函数
Note
https://spinnaker.io/reference/pipeline/expressions/#helper-properties
亦见。
条件表达式
Spinnaker 管道表达式流程允许您使用条件表达式来触发特定条件下的任何事件。例如,假设您想在演习期间跳过某个特定阶段。您可以使用以下条件表达式trigger["dryRun"] == false
。
前往 https://spinnaker.io/reference/pipeline/expressions/
获取更多关于帮助器功能及其属性的详细信息。
项目
您会在 Spinnaker UI 的标题中找到项目选项,如图 3-33 所示。项目选项提供了各种应用的聚合视图。一个应用可以是许多项目的一部分,反之亦然。项目将有助于根据应用的性质对其进行隔离。如果 Spinnaker 正在为多个项目(基于 Java 的、基于 Python 的等等)执行交付管道,您可以在 Spinnaker 中隔离这些项目,以便于管理,并通过基于角色的访问控制来限制用户访问。
图 3-33
Spinnaker 项目选项
要创建项目,请单击项目菜单,然后导航至操作。选择创建项目,如图 3-34 所示。
图 3-34
Spinnaker 项目创建
单击 Create Project 选项后,需要用应用项目名称、所有者名称等填充一个表单。添加应用、集群和管道的详细信息,然后点击保存按钮创建项目,如图 3-35 所示。
图 3-35
Spinnaker 项目配置
带 Spinnaker 的 CI/CD 用例
在本节中,您将学习如何使用 Spinnaker 执行应用部署。在这个练习中,我们将使用一个基于微服务架构的袜子商店应用。使用以下步骤在 GKE 集群上部署 sock-shop 应用,如图 3-36 所示。
图 3-36
三角帆管道流
在 Spinnaker 管道中,我们检查袜子商店应用代码,它本质上是一个清单文件(complete-demo.yaml
),基于来自 GitHub 的 Kubernetes,位于 https://github.com/dryice-devops
。然后,我们将连接到 GKE 集群(我们使用 Google 创建的相同集群和服务帐户来部署 Spinnaker。).最后,我们将袜子商店应用部署到同一个 GKE 集群。现在让我们看看袜子商店应用架构。
袜子商店应用架构
sock-shop 应用是一个容器化的云原生应用,其中前端服务构建在 Node.js 上。
支付、用户和目录微服务运行在前端服务之后,使用 Go 语言构建。
订单、购物车、运输和队列管理微服务都是基于 Java 语言的。
MySQL 被用作持久性存储数据库,而 MongoDB 被用作服务数据存储。这两个数据库都作为 pods 下的一个容器运行,并在 Kubernetes 集群内部公开。
RabbitMQ 是一个开源消息队列框架,用于订单队列。它也作为一个容器运行,并在 Kubernetes 集群内部公开。图 3-37 显示了袜子店应用架构设计图。
图 3-37
袜子商店应用架构
Sock-shop 应用被打包成一个 Docker 映像,使用一个 Docker 文件,该文件包含如何构建映像的说明。我们使用complete-demo.yaml
文件,这是该应用基于 Kubernetes 的部署。以下部分解释了应用的节点池和其他组件。
节点池选择
sock-shop 应用使用在创建 Kubernetes 集群时创建的默认节点池。
节点选择
我们在 YAML 文件中定义了节点选择,该文件用于在 Kubernetes 集群上部署应用。以下是在 Kubernetes 中将 pod 分配给节点的各种方法。
-
nodeSelector
:通过匹配用户定义的节点标签来选择部署特定 pod 的节点的最流行、最简单的方法。 -
节点关联:这个特性是在 Kubernetes 1.4 中引入的。它是节点选择器的增强版本。它提供了更具表现力的语法来控制如何将 pod 部署到特定节点。
-
Pod 间关联:Pod 间关联通过将 Pod 调度到已经运行特定 Pod 的节点上,而不是基于节点上的标签,来实现共存。
在 sock-shop 应用中,我们使用nodeSelector
在特定节点上部署 pod,如图 3-38 所示。
图 3-38
配置文件中的节点选择器片段
袜子商店应用中的服务
Kubernetes 中的服务是 pod 的逻辑集合/组。每个服务都有一个选择器部分,其中包含要连接的 pod 标签。这些是 Kubernetes 中的服务类型:
-
ClusterIP(默认):在集群中的内部 IP 上公开服务,使服务只能从集群内部访问。
-
NodePort :每个节点上的一个静态端口,服务在该端口上公开,并且可以从集群外部使用。
-
负载平衡器:在当前云中创建一个外部负载平衡器,并将固定的外部 IP 分配给服务。
按照袜子商店应用架构,前端与终端用户交互,这就是为什么前端服务是使用 GCP 外部负载平衡器公开的。
为了将前端服务公开为外部负载均衡器,我们在complete-demo.yaml
文件中将其定义为type:LoadBalancer
,如图 3-39 所示。在这种情况下,GKE 将通过调用适当的 Google Cloud API 并将其附加到前端服务来创建一个区域性的非代理外部网络负载平衡器。
图 3-39
作为负载平衡器的前端服务类型
sock-shop 应用的其他服务作为集群 IP 公开,这些服务在 GKE 集群内部,不能通过互联网访问(它们都是后端服务)。
下面是对complete-demo.yaml
文件的简要说明:
-
apiVersion :定义 Kubernetes 的
apiVersion
,与 Kubernetes API 服务器交互,创建对象。apiVersion
根据用于容器平台的 Kubernetes 版本的不同而不同。 -
kind :定义 Kubernetes 对象的类型,如 clusterRole、deployment、service、pods 等。在本例中,我们将其定义为部署和服务。
-
元数据:定义对象,如
name as carts-db
。 -
命名空间:定义将要创建 Kubernetes 对象的命名空间名称,比如
sock-shop
。 -
副本:要创建的 pod 的副本。
-
选择器:客户/用户用来识别一组对象。
-
模板:待复制对象的定义——在其他情况下可以自己创建的对象。
-
容器:定义容器的特性。
-
名称:容器的名称。
-
图像:哪个 Docker 图像用于创建容器。
-
Ports:Docker 容器运行的端口。
-
Env :
env
在 Docker 图像中使用的变量来运行容器。
-
-
securityContext
:管理 Kubernetes 集群上运行的 pod 或容器的权限和特权。该功能通过添加控制(如限制运行 pod 的用户的访问权限)、捕获流程系统调用或使用 AppArmor 功能限制程序执行权限(如读/写权限)来保护容器部署。
容器的安全设置如下:
-
volumeMounts
:这是容器中将要进行卷安装的路径。 -
volume
:这定义了我们将要使用的体积定义。
在 Spinnaker 中创建连续的交付管道
现在,我们将在 Spinnaker 中创建管道,为袜子商店应用执行连续交付。首先,我们将通过 Halyard 在 Spinnaker 中配置 GitHub 工件。它将从 GitHub ( https://github.com/dryice-devops/spinnaker
)获取清单文件。使用以下步骤来配置 GitHub 工件。
配置一个 GitHub 工件
第一步:通过升降索执行以下命令。
hal config features edit –artifacts true
hal config artifact github enable
这些命令的输出将是“成功启用 GitHub”,如图 3-40 所示。
图 3-40
Spinnaker 上的 GitHub 配置
步骤 2:执行以下命令来添加 GitHub 帐户。在这种情况下,我们添加了dryice-devops
帐户。如果您想添加您的 GitHub 帐户,请用该帐户名称替换dryice-devops
。
hal config artifact github account add dryice-devops
你应该得到"Successfully added artifacts account dryice-devops for artifact"
消息,如图 3-41 所示。
图 3-41
GitHub 帐户添加到 Spinnaker
步骤 3:执行以下命令,在 Spinnaker 上应用更改:
hal deploy apply
输出如图 3-42 、 3-43 和 3-44 所示。
图 3-44
GitHub 配置更改在 Spinnaker 上成功部署
图 3-43
GitHub 配置更改了 Spinnaker 上的部署进度
图 3-42
Spinnaker 上部署的 GitHub 配置更改
一旦配置了 GitHub 帐户,就可以在 Spinnaker 中创建应用了。
在 Spinnaker 中创建应用
按照以下步骤在 Spinnaker 中创建应用。
步骤 1:打开 Spinnaker GUI 并单击 Actions 下拉选项,该选项位于 Spinnaker GUI 屏幕的右上角。选择创建应用选项,如图 3-45 所示。
图 3-45
在 Spinnaker 上为 CI/CD 创建应用
第二步:打开新的应用窗口,如图 3-46 所示。
图 3-46
申请表格选项
填写行内必填字段,这些字段标有星号(*
):
-
名称:输入应用名称。在这种情况下,我们称之为
sock-shop-application
。 -
所有者电子邮件:提供 Spinnaker 将向其发送通知的所有者电子邮件。
-
回购类型:选择回购类型。在本例中,我们选择 GitHub 来获取袜子商店应用清单文件(一个基于 Kubernetes 的 YAML 文件)。
在 Repo Project 字段中,提供您的 GitHub 项目名称。在这种情况下,我们使用了名称dryice-devops
。在 Repo Name 字段中,提供 GitHub 存储库名称。在这种情况下,我们使用spinnaker
作为存储库名称,如图 3-47 所示。
图 3-47
申请表详情
保持其余选项不变,然后点击创建按钮,如图 3-48 所示。
图 3-48
保存申请表格
创建管道
Spinnaker 将按照给定的名称创建应用。现在可以创建管道来获取袜子商店应用清单文件(Kubernetes YAML 文件)。
步骤 1:打开新创建的应用页面,并导航到 Pipelines 页面。点击位于管道页签右上角的创建管道按钮,如图 3-49 所示。
图 3-49
为袜子店应用的 CI/CD 创建管道
步骤 2:在您点击 Create New Pipeline 按钮(一个+号)之后,一个表单将会打开。提供一个管道名称(在本例中,我们使用sock-shop-pipeline
) 。保持其他选项不变,单击 Create 按钮在 Spinnaker 中创建管道。见图 3-50 。
图 3-50
袜子店应用的管道创建表单 CI/CD
第三步:新管道创建完成后,将打开配置页面,如图 3-51 所示。
图 3-51
袜子商店管道配置
第四步:对于配置,首先选择添加工件,可以在配置的预期工件部分找到,如图 3-52 所示。这些工件将被用于管道中的 Kubernetes 集群。
图 3-52
添加工件
步骤 5:单击 Add Artifacts 选项后,会打开一个包含更多选项的菜单。首先,您必须选择用于从各种来源获取工件的帐户,例如 Docker 图像的 Docker 注册表、Kubernetes 等等。您也可以定义您的定制工件。当我们从 GitHub 获取清单文件时,我们选择了在“配置 GitHub 工件”一节中配置的dryice-devops
帐户。见图 3-53 。
图 3-53
添加工件帐户
接下来,提供在 GitHub 中dryice-devops
项目下提交的清单文件 ( complete-demo.yaml
) 的文件路径,并提供显示名称。在这种情况下,显示名称是sock-shop-github
。点击保存按钮,如图 3-54 所示。
图 3-54
添加工件帐户详细信息
现在,我们将在管道中添加执行所需操作的阶段,以便在 GKE 集群上部署工件(complete-demo.yaml
)文件。使用以下步骤在管道中添加阶段:
第一步:点击添加阶段选项,在配置的下方,如图 3-55 所示。
图 3-55
添加工件帐户详细信息
第二步:点击添加阶段将显示图 3-56 中的选项。
图 3-56
添加部署阶段
步骤 3:单击类型以获得 Spinnaker 支持的用于应用部署的各种选项。选择 Deploy (Manifest)选项部署一个 Kubernetes 清单 YAML 文件,如图 3-57 所示。
图 3-57
选择部署清单选项
选择 Deploy 之后,Spinnaker 将在基本设置下显示与部署(清单)配置相关的选项。选择spinnaker-install-account
账户,如图 3-58 所示。这是 GCP 在 GKE 集群上安装 Spinnaker 时创建的服务帐户。
图 3-58
选择服务帐户
现在选择sock-shop-application
我们在应用部分创建的应用,如图 3-59 所示。
图 3-59
选择应用
步骤 4:在清单配置选项中,我们必须选择部署 GKE 集群所需的 Kubernetes 工件。有两个选项——一个是文本,您可以按原样粘贴清单文件,第二个是您可以在工件选项中选择清单文件。在这种情况下,我们将选择 Artifact 选项,它将显示其他子选项,如图 3-60 所示。现在选择sock-shop-github
作为我们在管道的配置部分创建的清单工件,并保留其他选项。
图 3-60
清单配置
点击保存修改按钮,如图 3-61 所示。
图 3-61
保存更改
第五步:点击开始手动执行选项,现在手动运行sock-shop-pipeline
,如图 3-62 所示。
图 3-62
流水线执行
第 6 步:你会看到流水线执行的进度,如图 3-63 所示。
图 3-63
管道执行进度
如果所有定义的阶段的状态都显示为SUCCEEDED
,那么 sock-shop 应用在 GKE 集群上的部署是成功的。
在下一步中,您将学习如何验证 sock-shop 应用是否部署在 GKE 上,并获取前端 UI IP 地址,以便您可以在任何浏览器上打开 sock-shop 应用。
您可以获得关于 Spinnaker 执行的步骤的更多细节,并获得关于已部署的 Kubernetes 工作负载的特定信息(例如,部署、pods 等。)从正在运行的流水线状态的执行细节部分,如图 3-64 所示。
图 3-64
管道阶段详细信息
要获得关于特定 Kubernetes 对象的更多详细信息,请单击相应的详细信息链接,如图 3-65 所示。
图 3-65
袜子店部署详情
一旦你点击详细信息选项,Spinnaker 将显示状态、创建类型、种类和其他详细信息,如图 3-66 所示。
图 3-66
袜子店应用组件详细信息
从 Load Balancers 部分,您将获得根据 sock-shop 应用的清单文件创建的服务和入口的详细信息,如图 3-67 所示。
图 3-67
袜子店负载平衡器详细信息
第 7 步:导航到 GCP 控制台页面并选择 Kubernetes 引擎。点击集群选项,如图 3-68 所示。
图 3-68
GKE 集群
步骤 8:选择工作负载,查看与 sock-shop 应用相关的 Kubernetes 部署和 pod,如图 3-69 所示。
图 3-69
袜子店应用工作负载详细信息
您也可以通过执行下面的kubectl
命令从云 Shell 中验证这些:
kubectl get namespace
这验证了 sock-shop 名称空间已创建。现在执行下面提到的其他命令来查看部署在sock-shop
名称空间下的 pod 和服务。
kubectl get pods -n sock-shop
kubectl get service -n sock-shop
你会看到命令的输出,如图 3-70 、 3-71 和 3-72 所示。
图 3-72
GKE 集群中的袜子店服务列表
图 3-71
GKE 集群中的袜子店列表
图 3-70
GKE 集群中的 sock-shop 命名空间
步骤 9:现在我们将获取袜子商店应用前端组件端点,以在浏览器中打开袜子商店应用。导航到 Kubernetes 引擎页面,然后单击服务和入口。您将能够查看部署在 GKE 集群上的服务。现在查找前端服务,然后注意外部负载平衡器的详细信息,如图 3-73 中突出显示的。
图 3-73
袜子商店前端端点
第十步:打开任意浏览器,按照上一步粘贴复制的 IP 地址(如 http://34.75.85.135
)。按下输入按钮。你将看到袜子店应用,如图 3-74 所示。
图 3-74
袜子商店应用 web 界面
Spinnaker 的金丝雀部署用例
在本节中,我们将使用 Google 云组件(如 Google Kubernetes Engine (GKE)、Spinnaker 以及云构建和云源存储库)创建一个持续交付管道。我们将利用 Google 提供的一个样例应用,并配置这些 GCP 服务来建立一个自动化的构建、测试和部署过程。任何代码修改都将触发新代码变更的自动构建、测试和部署,以展示连续交付。连续输送管道流程如图 3-75 所示。
图 3-75
canary 部署的 CI/CD
此使用案例的主要目标如下:
-
创建一个名为
app-cluster
的新 GKE 集群来部署示例应用。 -
下载一个示例应用,创建一个 Git 存储库,并将其上传到一个云资源存储库。
-
建立你的码头工人形象。
-
创建触发器,以便在应用代码更改时创建 Docker 图像。
-
配置一个 Spinnaker 管道,使用 canary 部署策略在 GKE 集群上部署示例应用。
-
手动执行 Spinnaker 管道,并在 Docker 图像标签改变时自动触发。把它推到容器注册处。
创建新的 GKE 集群
在部署示例应用之前,按照以下步骤创建一个名为app-cluster
的新 GKE 集群。
步骤 1:使用 Cloud Shell,我们将创建一个名为app-cluster
的新 GKE 集群来部署示例应用。在云 Shell 中执行内联命令。
ZONE=us-east1-c
gcloud config set compute/zone $ZONE
gcloud container clusters create app-cluster \
--machine-type=n1-standard-2
这些命令的输出如图 3-76 、 3-77 和 3-78 所示。
图 3-78
GKE 应用-集群已创建
图 3-77
GKE 应用-集群创建开始
图 3-76
GKE app-集群创建命令
您可以在 GCP 控制台中通过导航到 Kubernetes 引擎➤集群来验证这一点。您可以查看新创建的集群,如图 3-79 所示。
图 3-79
GCP 控制台上的 GKE 应用集群验证
步骤 2:通过执行以下命令,将新的 GKE 集群添加到 Spinnaker 中。
~/cloudshell_open/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
该命令的输出如图 3-80 所示。
图 3-80
将 GKE 应用集群添加到 Spinnaker
步骤 3:现在通过执行以下命令,将 Kubernetes 上下文改回到名为spinnaker1
的 Spinnaker 集群:
kubectl config use-context gke_mylearndmproject_us-east1-c_spinnaker-1
我们这样做是为了创建管道,以便在 GKE 集群上部署示例应用。该命令的输出如图 3-81 所示。
图 3-81
将 Kubernetes 上下文从 app-cluster 更改为 Spinnaker
步骤 4:现在,我们将通过执行以下命令,将配置更改推送并应用到 Spinnaker。
~/cloudshell_open/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
该命令的输出如图 3-82 所示。
图 3-82
将更改应用到 Spinnaker
第五步:为了让 Cloud Build 检测到你的应用源代码的变化,你必须构建一个 Docker 镜像,然后把它推送到容器注册中心。在 Cloud Shell 中执行以下命令来下载示例源代码。
cd ~
wget https://gke-spinnaker.storage.googleapis.com/sample-app-v4.tgz
该命令的输出如图 3-83 所示。
图 3-83
下载示例应用源代码
步骤 6:通过执行下面的命令来解包源代码。
tar xzfv sample-app-v4.tgz
该命令的输出如图 3-84 所示。
图 3-84
解包示例应用源代码
步骤 7:现在通过执行下面的命令来改变目录。
cd sample-app
该命令的输出如图 3-85 所示。
图 3-85
进入示例应用
步骤 8:让我们通过执行下面的 Git 命令对源代码库进行初始提交。
git init
git add .
git commit -m "Initial commit"
这些命令的输出如图 3-86 所示。
图 3-86
进入示例应用
步骤 9:通过执行以下命令,创建一个存储库来存放这段代码。
gcloud source repos create sample-app
git config credential.helper gcloud.sh
这些命令的输出如图 3-87 和 3-88 所示。
图 3-88
在存储库中配置凭据
图 3-87
在 GCP 上创建知识库
步骤 10:添加新创建的存储库作为remote
。
export PROJECT=$(gcloud info --format='value(config.project)')
git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
该命令的输出如图 3-89 所示。
图 3-89
存储库作为远程添加
步骤 11:现在通过执行下面的命令将代码推送到新存储库的主分支。
git push origin master
该命令的输出如图 3-90 所示。
图 3-90
将代码推入新的存储库
第 12 步:导航到 https://console.cloud.google.com/code/develop/browse/sample-app/master?ga
链接,可以在控制台看到签入的源代码,如图 3-91 所示。
图 3-91
将代码推入新的存储库
在接下来的步骤中,我们将构建 Docker 映像,运行单元测试,并将 Docker 映像推送到 Google 容器注册表,如图 3-92 所示。
图 3-92
谷歌代码构建管道
现在,我们将配置 Cloud Build,以便每当我们将 Git 标签推送到源存储库时,构建并推送 Docker 映像。Cloud Build 自动检查源代码,从存储库中的 Docker 文件构建 Docker 映像,并将该映像推送到容器注册中心。
使用以下步骤执行这些任务。
第一步:在云控制台中,导航到云构建部分,点击触发器,然后点击创建触发器,如图 3-93 和 3-94 所示。
图 3-94
Google 代码构建触发器
图 3-93
谷歌代码构建
步骤 2:在触发器表单中设置以下触发器设置:
-
姓名 :
sample-app-tags
-
事件:选择推送新标签
-
储存库 :
sample-app
-
标签(regex) :
v.*
(用于触发) -
构建配置 :
/cloudbuild.yaml
这个文件附带了示例代码,用于在每次将 Git 标签推送到源存储库时构建和推送 Docker 映像。
完成后,点击创建按钮,如图 3-95 所示。
图 3-95
Google 代码构建触发器表单
一旦新的触发器被创建,你可以在同一个触发器上看到它,如图 3-96 所示。
图 3-96
触发器创建的 Google 代码版本
现在,每当我们将前缀为字母v
的 Git 标签推送到源代码库时,Cloud Build 会自动构建应用,并将它作为 Docker 映像推送到容器注册表。
现在我们将准备 Kubernetes 清单,Spinnaker 将使用它来部署 GKE 集群。
本节创建一个云存储桶,在云构建中的 CI 过程中,将使用清单填充该桶。清单存储在云存储中后,Spinnaker 将在管道执行期间下载并应用它们。
步骤 1:通过执行以下命令在 GCP 创建 bucket。
export PROJECT=$(gcloud info --format='value(config.project)')
gsutil mb gs://$PROJECT-kubernetes-manifests
这些命令的输出如图 3-97 所示。
图 3-97
GCP 的水桶创作
导航到存储➤浏览器,可以看到新的存储桶已经创建,如图 3-98 所示。
图 3-98
GCP 的水桶创作
步骤 2:在存储桶上启用版本控制,这样您就可以维护清单的历史。
gsutil versioning set on gs://$PROJECT-kubernetes-manifests
该命令的输出如图 3-99 所示。
图 3-99
GCP 的水桶创作
步骤 3:在 Kubernetes 部署清单中设置正确的 Google Cloud 项目 ID:
sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
该命令的输出如图 3-100 所示。
图 3-100
在 Kubernetes 部署中设置云项目 ID
步骤 4:将变更提交给存储库。
git commit -a -m "Set project ID"
该命令的输出如图 3-101 所示。
图 3-101
将更改提交到存储库
在下一部分中,我们将在 Spinnaker 中创建一个持续部署管道,如图 3-102 所示。
图 3-102
将更改提交到存储库
第 1 步:使用命令行界面spin
创建一个名为sample
的应用。Spinnaker 附带了用于 GCP 的 Spinnaker 包,所以没有必要在 GCP 明确地安装它。
spin application save --application-name sample \
--owner-email example@example.com \
--cloud-providers kubernetes \
--gate-endpoint http://localhost:8080/gate
该命令的输出如图 3-103 所示。
图 3-103
在 Spinnaker 中创建应用
步骤 2:在云 Shell 上,从sample-app
根目录运行以下命令,为示例应用创建 Kubernetes 服务。
kubectl apply -f k8s/services
该命令的输出如图 3-104 所示。
图 3-104
为示例应用创建的服务
第三步:导航到 Spinnaker UI ➤应用➤样例,如图 3-105 所示。
图 3-105
为示例应用创建的服务
现在我们将在sample
应用中创建新的管道deploy
,点击创建按钮,如图 3-106 所示。
图 3-106
创建部署管道
步骤 4:在 Cloud Shell 中,在源代码目录下运行下面的命令,创建一个新的 spinnaker 管道模板作为updated-pipeline-deploy.json
。这是基于当前的 Google 项目,带有名为pipeline-deploy.json
的现有管道模板,附带示例代码。
export PROJECT=$(gcloud info --format='value(config.project)')
sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > updated-pipeline-deploy.json
执行完这些命令后,点击打开的编辑器查看新创建的updated-pipeline-deploy.json
文件,如图 3-107 所示。
图 3-107
打开编辑器
你会看到项目文件夹➤大三角帆➤ updated-pipeline-deploy.json
。复制updated-pipeline-deploy.json
文件的内容,如图 3-108 所示。
图 3-108
updated-pipeline-deploy.json 文件
步骤 5:在 Spinnaker 中,导航到我们刚刚创建的部署管道的配置页面,并选择管道操作➤编辑为 JSON,如图 3-109 所示。
图 3-109
编辑管道
在 JSON 编辑器中,复制updated-pipeline-deploy.json
文件的内容,点击更新管道按钮,如图 3-110 所示。
图 3-110
编辑管道的 JSON
第 6 步:您将看到更新后的管道配置,如图 3-111 所示。
图 3-111
部署管道流
手动运行管道
我们刚刚创建的配置包含一个触发器,每当推送一个包含前缀v
的新 Git 标记时,该触发器就会启动管道。现在,您将通过手动运行来测试管道。
第一步:在部署管道页面,点击开始手动执行选项,如图 3-112 所示。
图 3-112
手动执行管道
您将在 pipeline execution 页面上看到管道的进度,在这里您可以验证 Spinnaker 管道采用了新的 Docker 镜像版本v1.0.0
,如图 3-113 所示。
图 3-113
管道的手动执行
从执行细节部分还可以看到流水线流程图,如图 3-114 所示。
图 3-114
管道执行细节
步骤 2:管道执行将暂停,等待人工批准将 Kubernetes 清单部署到 GKE 集群上。点击继续按钮,提供手工审批,如图 3-115 所示。
图 3-115
人工批准
点击继续按钮后,流水线执行剩余阶段,如图 3-116 和 3-117 所示。
图 3-117
生产部署进度
图 3-116
生产部署
当所有阶段运行成功后,管道状态为SUCCEEDED
,如图 3-118 所示。
图 3-118
Spinnaker 部署管道状态
第三步:导航到 Google 控制台➤ Kubernetes 引擎➤工作负载,查看示例应用 Kubernetes 工作负载,如图 3-119 所示。
图 3-119
Spinnaker 管道状态
现在点击服务和入口来查看sample-frontend-canary
和sample-frontend-production
的端点。要导航至应用 GUI,请在浏览器中打开它。复制端点并粘贴到浏览器中,如图 3-120 、 3-121 和 3-122 所示。
图 3-122
示例应用生产前端 GUI
图 3-121
示例应用金丝雀前端 GUI
图 3-120
示例应用前端端点
通过代码更改自动触发管道
现在,让我们通过更改代码、推送 Git 标记并观察管道的响应执行来测试管道的端到端。通过推送一个以v
开头的 Git 标签,我们将触发容器构建器构建一个新的 Docker 映像,并将其推送到容器注册中心。Spinnaker 自动检测到新的图像标签以v
开始,并触发管道将图像部署到 canaries,运行测试,并将图像部署到部署中的所有 pod。
第一步:在sample-app
目录下执行以下命令,将 app 的颜色从橙色改为黄色。
sed -i 's/orange/yellow/g' cmd/gke-info/common-service.go
该命令的输出如图 3-123 所示。
图 3-123
更改示例应用的背景颜色
步骤 2:现在我们将标记变更,并将其推送到源代码存储库。为此,请执行以下命令。
git tag v1.0.1
git push --tags
该命令的输出如图 3-124 所示。
图 3-124
新标签
一旦这个命令被执行,我们将看到新的构建出现在 Google Cloud 构建中。导航到 https://console.cloud.google.com/cloud-build/builds
。
然后你会看到新的标签V1.0.1
,如图 3-125 所示。
图 3-125
创造历史
步骤 3:观察金丝雀部署。当部署暂停,等待推广到生产时,开始刷新包含应用的选项卡。九个后端运行应用的前一版本,而只有一个后端运行金丝雀。参见图 3-126 。
图 3-126
自动触发部署管道
步骤 4:当管道完成时,如图 3-127 所示,你会看到由于代码的改变,颜色变成了黄色,版本字段现在显示为v1.0.1
。
图 3-127
自动触发部署管道成功完成
现在单击服务和入口来确定sample-frontend-canary
的端点。要在浏览器中打开它并查看 GUI,只需复制端点 IP 地址并将其粘贴到浏览器中。您将看到图形用户界面更新为黄色,如图 3-128 和 3-129 所示。
图 3-129
黄色淡黄色 GUI
图 3-128
canary 部署的端点
摘要
在本章中,您学习了 Spinnaker 连续部署工具。我们讨论了 Spinnaker 架构及其在 Google 云平台(GPC)上的安装步骤。您还了解了如何使用 Spinnaker 在 GKE 上部署应用,以及可以使用 Spinnaker 轻松配置的各种部署策略。在下一章中,我们将介绍如何利用 Tekton 实现 GCP 自动化。
四、GCP Tekton 入门
本章介绍 Tekton,这是一个即将推出的用于在 Google 云平台上部署应用的解决方案。本章涵盖以下主题:
-
Tekton 的特性介绍
-
Tekton 流水线架构
-
Tekton 管道组件配置
-
在 GCP 建立泰克顿管道
-
Tekton 管道的用例实现
Tekton 功能
让我们先简要介绍一下 Tekton 及其主要特性。Tekton 是一个开源框架,专为云原生 CI/CD 实施而设计。
它最初是由 Google 为基于 Kubernetes-native 的软件构建和部署开发的。2018 年,Tekton 项目捐赠给持续交付基金会。从那时起,CDF 接管了新功能和增强功能的责任。
Tekton 基于 Kubernetes-native 原则,允许开发人员跨多个云提供商构建、测试和部署云原生的容器化应用。Kubernetes 环境包括 AWS 弹性 Kubernetes 服务、Google Kubernetes 服务和混合环境。
Tekton 拥有定义 Kubernetes 风格的资源的最佳实践,用于声明 CI/CD 风格的管道,这将帮助开发人员轻松创建云原生 CI/CD 管道。开发人员还可以轻松地构建和部署不可变的映像、管理基础设施版本控制,以及执行高级 Kubernetes 部署/回滚策略,如 blue-green、canary 部署、滚动更新等。Tekton 使用其他第三方工具来存储、管理和保护工件。由于 Tekton 是由 Google 早期设计/开发的,它与 GCP 特定的 Kubernetes 解决方案(如用于 K8 本地应用部署的 GKE 或用于存储/扫描容器图像的 Google container registry)配合得很好。
虽然 Tekton 具有基于 Kubernentes 的应用的原生功能,但在涉及第三方插件和创建完整应用工作流的用户友好选项时,它仍然缺乏 Jenkins/Azure DevOps 等工具的功能。表 4-1 显示了 Jenkins、JenkinsX 和 Tekton 的功能比较,让您了解 Tekton 的功能。
表 4-1
工具比较
|特征
|
Jenkins
|
Jenkins
|
泰顿
|
| --- | --- | --- | --- |
| 图像使用者界面 | |
|
|
| 管道作为代码 | 宣言的 | 亚姆 | 亚姆 |
| kubernetes-本地(基于控制器) | |
|
|
| 海峡群岛 | |
|
|
| 激光唱片 | |
|
|
| WebHook 触发 | |
|
|
| Git 轮询触发 | |
|
|
| 模板支持 | | 通过脚本 DIY | 通过脚本 DIY |
可用
不可用
Tekton 有四个核心组件:
-
Tekton pipelines :该组件定义了 CI/CD 工作流的基本构建模块(管道和任务)。
-
触发器:CI/CD 工作流的触发事件。
-
CI/CD 工作流管理的命令行界面。
-
Dashboard :基于 web 的管道管理 UI。
Tekton 的流水线架构
Tekton 的管道设计在 Kubernetes 上运行。它利用了 Kubernetes 自定义资源定义(CRD ),用于定义其组件,如管道、任务等。CRD 是一个 Kubernetes API 扩展,用于创建自定义对象,并像使用其他 Kubernetes 对象一样使用它们(如 pod、服务等)。).一旦安装完毕,就可以通过 Kubernetes CLI ( kubectl
)和 API 调用来访问 Tekton 管道,就像在 Kubernetes 中调用 pod 和其他资源一样。这些特性使得 Tekton 能够很好地与整个 Kubernetes 系统集成。图 4-1 展示了 Tekton 流水线的架构,图 4-2 展示了流水线的执行。让我们在接下来的小节中看看这个架构中的核心组件。
图 4-2
泰克顿管道流程图
图 4-1
Tekton 的流水线架构
步伐
一个步骤是 Tekton 流水线的最小操作。它在 CI/CD 中执行特定的功能,比如管理工作流、编译代码、运行单元测试、构建和推送 Docker 映像等等。
任务
一个任务是步骤的集合,这些步骤按照用户定义的特定顺序执行,如图 4-3 所示。任务在 K8 集群中以 Kubernetes pods 的形式执行,而步骤在同一个 pod 中作为容器运行。在任务中,我们还可以提供共享的环境信息,在同一个 pod 中运行的所有步骤都可以访问这些信息。我们可以在 Tekton 任务中安装秘密,在同一个 Tekton 任务中定义的每个步骤都可以访问它。
图 4-3
任务和步骤
集群任务
集群任务类似于 Kubernetes 集群级别范围内的任务(任务范围仅特定于单个名称空间)。
管道
管道定义了要按顺序执行的任务集。管道是无状态的、可重用的和参数化的。简而言之,Tekton 根据任务创建几个 pod,并确保所有 pod 都按预期成功运行。管道可以在不同的 Kubernetes 节点上执行任务。
管道按以下顺序执行:
-
连续的
-
同时地
-
有向无环图
任务执行的顺序如图 4-4 所示。图中的任务 A 表示执行的顺序,其中步骤 1、2 和 3 依次执行。
图 4-4
管道流动
图中的任务 B 和 C 表示任务执行的并发流程,其中步骤 1 和 2 中的两个任务并行执行。
图 4-4 中的任务 D 代表有向无环图流,其中任务按照有向无环图(DAG)顺序组织。DAG 执行还允许连接管道任务,以便一个可以在另一个之前运行,因此管道执行不会陷入无限循环。有关更多详细信息,请参见以下链接:
https://en.wikipedia.org/wiki/Directed_acyclic_graph
管道资源(输入/输出资源)
管道资源组件定义了可以在管道或任务中用作输入或输出的对象。例如,pipeline/task 需要 Git 存储库位置作为输入,以获取最新的代码并提供容器图像作为输出。
Tekton 支持多种类型的资源(图 4-5 中提到了其中几种):
图 4-5
管道输入输出流
-
Git:一个 Git 库
-
Pull 请求:Git 存储库中特定的 pull 请求
-
图像:容器图像
-
丛集:丛集
任务运行和管道运行
PipelineRun 负责对特定事件执行管道,并将所需的执行参数、输入和输出传递给管道。
类似地,任务运行是任务的特定触发点。任务运行和管道运行将资源与任务和管道连接起来。您可以手动或自动创建 TaskRuns 和 PipelineRuns,以立即或在特定时间触发任务和管道(如图 4-6 )。
图 4-6
taskerun 和 pipelinerun 流量
例如,您可以在 Tekton 中设置每天执行管道的具体时间,或者在开发人员通过 WebHook 将代码签入 Git 存储库时执行管道。
PipelineRun 或 TaskRun 必须包含与管道或任务相关联的所有输入和输出资源。您可以在规范中声明它们,或者使用 Tekton 在执行时自动解析的名称引用(如图 4-6 和 4-7 所示)。
图 4-7
任务运行管道资源和管道运行流程
在下一节中,您将学习如何在 Tekton 中定义这些组件来创建管道。
配置 Tekton 的管道组件
在 Kubernetes 中,YAML 经常被用来定义其工作负载(如 pod、服务定义等)。),因为维护简单,使用灵活。Tekton 组件在 Kubernetes 集群上运行,它也使用 YAML 来定义它们。让我们看看如何通过 YAML 以声明的方式定义 Tekton 管道组件。
配置任务
在 Tekton 中,任务包含一组步骤,这些步骤在 Kubernetes 集群中作为一个 pod 执行。按照最佳实践,它们应该部署在特定的 Kubernetes 名称空间中。默认情况下,它们被部署到default
Kubernetes 名称空间。图 4-8 显示了 Tekton 中任务定义的一个例子。
图 4-8
任务配置片段
现在让我们根据图 4-8 中使用的例子来看看必填和可选字段及其相关性。
以下是必填字段:
-
apiVersion
:用于与 Kubernetes API 服务器交互,创建对象。在 Tekton 中,任务的 API 版本被称为tekton.dev/v1beta1
。API 版本取决于 Tekton 管道的版本。 -
kind
:我们定义 Kubernetes 对象的类型(例如,集群角色、部署)。在 Tekton 中,管道任务总是使用种类task
来将这个资源对象标识为任务对象。 -
metadata
:指定在 Kubernetes 集群中唯一标识任务资源对象的元数据。例如,根据 CI/CD 流,Name
应该是有意义的。在前面的例子中,我们使用任务名为name: build-ui
,这意味着该任务基于构建 UI 应用。 -
spec
:指定该任务资源对象的配置信息。 -
steps
:指定在任务中运行的一个或多个容器图像。
可选字段详细信息:
-
description
:任务的描述。 -
params
: Specifies parameters that are passed to the task at execution time. As per the example in Figure 4-9, we have defined a parameter calledpathToDockerFile
, which has astring
type, a description, and a default location of the dockerfile that needs to be built by the Tekton task.图 4-9
参数
-
resources
:指定 PipelineResources 提供的输入输出资源。您将在 PipelineResources 部分获得关于它的详细信息。 -
在 inputs 部分,我们定义了任务输入的资源。
-
outputs
:在输出部分,我们定义任务产生的资源。 -
workspaces
:指定任务执行过程中需要的一个或多个卷的路径。你会在本章的工作区部分得到更多的细节。 -
results
:在 result 部分,我们指定任务用来写入和存储其执行结果的文件。 -
volumes
:指定任务中的步骤可用的一个或多个卷。
任务运行配置
TaskRun 实例化并执行任务,我们可以在 TaskRun 中指定任务,既可以在taskRef
中提供任务名称,也可以直接在 TaskRun 中嵌入任务定义。
在 Tekton 中调用 TaskRun 配置中的任务有两种方法,一种是将目标任务指定为 taskRef,另一种是通过将其嵌入 TaskRun 来指定目标任务。
将目标任务指定为 taskdef
在图 4-10 所示的例子中,我们在 TaskRun 配置中将任务名称build-ui
作为taskRef
提供。
图 4-10
taskRef 片段
通过将目标任务嵌入 TaskRun 来指定目标任务
在图 4-11 的例子中,任务定义作为taskSpec
嵌入到 TaskRun 中。
图 4-11
任务片段中的目标
检查字段
现在让我们看看定义 TaskRun 的强制和可选字段。以下是必填字段:
-
apiVersion
:指定 API 版本,例如tekton.dev/v1beta1
。这取决于 Tekton 管道版本。 -
kind
:将这个 Kubernetes 资源对象标识为 TaskRun 对象。 -
metadata
:指定唯一标识 TaskRun 对象的元数据(如generateName: build-ui-app
)。 -
spec
:指定任务运行的配置。 -
taskRef
或taskSpec
:指定 TaskRun 将要执行的任务(如name: build-ui
)。
以下是可选字段:
图 4-12
参数定义片段中的参数
-
serviceAccountName
:指定一个ServiceAccount
对象名,为在 Kubernetes 集群中执行 TaskRun 提供凭证。 -
params
:如果任务有参数,则在params
中指定,如图 4-12 所示。
contextDir
是参数的名称,app/java/account
是该参数的值。如果参数没有隐式默认值,则必须显式设置其值。
-
resources
:指定 PipelineResource 值。 -
inputs
:指定输入资源名称。 -
outputs
:指定输出资源名称。 -
timeout
:指定任务运行失败前的超时时间(分钟)。
有关 TaskRun 的更多信息,请访问以下链接: https://tekton.dev/docs/pipelines/taskruns/
。
定义管道
请记住,在 Tekton 中,管道是任务的集合。任务是按照 CI/CD 顺序定义的(例如,从源代码管理中签出代码,选择构建代码,运行单元测试)。图 4-13 显示了在 Tekton 中定义管道的例子。
图 4-13
管道定义片段
现在,让我们了解一下管道配置中必需的强制和可选字段。以下是必填字段:
-
apiVersion
:如前几节所述,API 版本需要与 Kubernetes API 服务器交互来创建对象。apiVersion
取决于 Tekton 的版本。在前面的例子中,我们使用apiVersion
作为泰克顿。Dev/ v1beta1.
在 Tekton 的旧版本中,它可能是一个 alpha 版本。 -
kind
:用于标识 Kubernetes 资源对象,如 pod、service 等。如果是管道类的,永远都是Pipeline
only。 -
metadata
:用于唯一标识管道对象。比如一个name: build-ci-cd-pipeline
。 -
spec
:指定Pipeline
对象的配置信息(如资源或任务)。 -
tasks
:指定流水线定义的任务及其执行顺序。
现在让我们来看看可用于在 Tekton 中定义管道的可选字段。
图 4-14
资源定义片段
-
from
: 如果一个任务需要前一个任务的输出作为其输入,则在from
参数中定义,该参数在需要该输出作为其输入的任务之前执行。 -
任务:
-
资源.输入/资源.输出
-
resources
:在管道定义的spec
部分声明,具有唯一的名称和类型。在图 4-14 的例子中,我们定义了两个具有唯一名称和类型的资源。
在图 4-15 的例子中,deploy-ui-app
任务需要名为mydocker-image
的build-ui-app
任务的输出作为其输入。
图 4-15
管道输入/输出片段
因此,build-ui-app
任务将在deploy-ui-app
任务之前执行,而不管这些任务在管道定义中的声明顺序。见图 4-15 。
-
runAfter
: If the tasks must be executed in a specific order as per the CI/CD requirements and they do not have any resource dependencies, those tasks are mentioned underrunAfter
. In the example in Figure 4-16,code build
should be run before the unit testing happens. There is no output linking required between these tasks, so theunittesting-java-app
task usesrunAfter
to indicate thatbuild-java-app
must run before it, regardless of the order in which they are referenced in the pipeline definition.图 4-16
runAfter 管道片段
-
retries
: 指定任务执行失败后重试的次数。
在图 4-17 所示的例子中,build-docker-image
任务的执行在失败后会重试两次。如果重试执行也失败,则任务执行失败。
图 4-17
重试管道片段
conditions
:指定某个条件,当满足该条件时,允许任务执行。
在图 4-18 的例子中,is-feature-branch
指的是一个条件资源。只有当条件评估成功时,才会执行生成任务。
图 4-18
条件管道片段
更多信息,请点击此链接: https://tekton.dev/docs/pipelines/pipelines/
。
管道运行
PipelineRun 在 Kubernetes 集群中实例化并执行管道。PipelineRun 按照定义的顺序执行管道中的任务,直到所有任务都成功执行或出现故障。PipelineRun 为管道中引用/定义的每个任务自动创建相应的任务运行,以执行任务。
图 4-19 显示了在 Tekton 中定义 PipelineRun 的示例。
图 4-19
pipeline 运行管道片段
现在,让我们了解一下在前面的示例中使用的管道配置中必需的强制和可选字段。以下是必填字段:
-
apiVersion
:同上。 -
kind
:用于标识 Kubernetes 资源对象,如 pod、service 等。 -
元数据:用于唯一标识 PipelineRun 对象。比如一个
name: build-ci-cd-java-app
。 -
spec
:pipeline run 的规范,包括管道触发事件及其输入输出资源。 -
pipelineRef
或pipelineSpec
:指定需要执行的目标管道名。
以下是可选字段:
resources
:在流水线中,任务需要资源作为要执行的步骤的输入/输出。PipelineResources
提供这些资源。我们将在下一节了解更多关于PipelineResources
的内容。在资源字段中,我们提供了PipelineResources
的详细信息。
有两种方法可以在 PipelineRun 配置中定义 PipelineResources:
图 4-23
serviceAccountName 管道代码段
-
Provide a reference of the PipelineResources in the
resourceRef
field, as shown in the example in Figure 4-20.图 4-20
pipeline 运行管道片段
-
Embed the
PipelineResource
definition in the PipelineRun using theresourceSpec
field, as shown in the example in Figure 4-21.图 4-21
resourceSpec 管道代码段
-
params
: Specifies parameters that are required by the pipeline at execution time, as shown in the example in Figure 4-22.图 4-22
Params 管道片段
-
serviceAccountName
:指定一个 KubernetesServiceAccount
对象,为管道在 Kubernetes 集群上执行提供具体的执行凭证,如图 4-23 中的例子所示。
更多信息,请访问此链接: https://tekton.dev/docs/pipelines/auth/
。
timeout
:指定管道运行失败前的超时时间(分钟)。如果没有为timeout
指定值,Tekton 将应用全局默认超时值,即 60 分钟。如果超时值设置为0
,则在执行过程中出现任何错误时,PipelineRun 都会立即失败。
要了解更多关于 PipelineRun 的信息,请访问以下链接: https://tekton.dev/docs/pipelines/pipelineruns
。
工作空间
Workspace 是 Tekton 管道和任务用来共享数据的文件系统,因为输入/输出 Workspace 类似于 Kubernetes 卷。唯一的区别是它不提供实际的卷,而是用它来声明文件系统的用途。一个工作区可以用多种方式来声明,比如ConfigMap
、PersistenceVolumeClaim
、Secrets
等等。
在 Tekton 中,出于以下原因可以使用 Workspace。
-
在任务间共享数据。
-
任务和管道可以用它来存储输入/输出。
-
用于分别通过
ConfigMap
和Secrets
访问应用配置和凭证。 -
用作构建缓存文件以加速 CI/CD 过程。
在本节中,您将学习如何在 Task、TaskRun、Pipeline 和 PipelineRun 中配置工作区。
任务中的工作区
借助图 4-24 中的示例,我们将了解 Tekton 任务中的工作空间配置及其字段。
图 4-24
工作区配置片段
在前面的例子中,我们在一个名为mvn
的任务中定义了一个名为mavenrepo
的工作空间。这个工作区定义了每当mvn
运行时,应该提供并挂载一个卷作为本地 Maven 仓库。
然后,这个工作区的路径被传递给 Maven 命令,以便与Dmaven.repo.local=$(workspaces.mavenrepo.path)
一起用作本地 Maven 存储库。任务定义可以根据需要包含任意数量的工作空间。Tekton 建议您最多使用一个可写工作空间。让我们来看看 workspace 的必填和可选字段。
-
name
(必填):工作区的唯一标识。 -
description
:描述工作区的用途。 -
readOnly
:任务写入/读取工作区的布尔值。 -
mountPath
:工作区在磁盘上可用位置的路径。挂载路径可以是相对的或绝对的,其中相对路径以目录名开始,绝对路径以/
开始。如果在工作区定义中没有提供mountPath
,工作区将默认放置/workspace/<name>
,其中<name>
是工作区的唯一名称。
任务运行中的工作区
如前所述,TaskRun 执行任务。如果任务包含工作空间,那么它应该与实际的物理卷绑定,因为工作空间只是一个声明。物理卷可以是任何 Kubernetes 卷类型,如emptyDir
、PersistentVolumeClaim
等。为了提供同样的功能,TaskRun 包含了自己的工作空间,如图 4-25 中的示例所示。
图 4-25
TaskRun 代码片段中的工作区
-
name
(必填):为其提供卷的任务中工作区的名称。 -
subPath
:卷上的可选子目录,用于存储该工作区的数据。子路径必须在 TaskRun 执行之前存在,否则 TaskRun 执行将失败。
管道中的工作空间
在下面的例子中,我们在名为docker-build
的管道中定义了一个名为pipeline
-workspace
的工作空间。这个管道决定哪个任务将使用pipeline-workspace
。例如,名为task
的任务使用pipeline-workspace
工作空间(见图 4-26 )。
图 4-26
管道片段中的工作区
管线管路中的工作空间
PipelineRun 提供了一个将与管道的工作区字段相关联的卷。该列表中的每个条目必须对应于管道中的一个工作区声明。工作区列表中的每个条目必须指定以下内容,如图 4-27 中的示例所示。
-
name
(必选):为其提供卷的管道定义中指定的工作空间的名称。 -
subPath
(可选):卷上的一个目录,将存储该工作区的数据。TaskRun 执行时,此目录必须存在;否则,执行将会失败。
图 4-27
PipelineRuns 代码段中的工作区
管道资源
管道资源提供一组由任务用作输入/输出的对象。任务可以有多个输入/输出。图 4-28 显示了一个这样的配置的示例片段。
图 4-28
管道资源片段
在这个例子中,我们用名称git-repo-url
定义了PipelineResource
,它提供了源 Git 存储库。
以下是 PipelineResource 的必填字段:
-
apiVersion
:与上一节所述相同。 -
kind
:与上一节所述相同。对于 PipelineResource,kind
将始终仅是 PipelineResource。 -
metadata
:与上一节所述相同。 -
spec
:在spec
中,我们指定了 PipelineResource 资源对象的配置信息。 -
type
:在type
中我们指定了 PipelineResource 的类型,比如git
。
以下是可选字段:
-
description
:资源的描述。 -
params
:特定于每种 PipelineResource 的参数,用唯一的名称和值定义。 -
optional
:将资源标记为可选的布尔标志(默认情况下,optional 设置为false
,使资源成为强制)。
现在,您将学习如何使用图 4-29 中的示例在管道中调用 PipelineResource。
图 4-29
管道代码段中的管道资源
在资源部分下的管道定义中,我们将 PipelineResource 名称作为git-repo-url
传递,将类型作为git
传递。
在 GCP 建立泰克顿管道
Tekton 管道是在 Kubernetes 上本地执行的 CRD(自定义资源定义)。Tekton 建立在 Kubernetes 原型机的基础上。为了帮助您理解这个概念,请参考图 4-30 。
图 4-30
Tekton 管道和 Kubernetes
表 4-2 概述了 Tekton 如何使用 Kubernetes 对象——主要是 pod 和 CRD 对象——来形成 CI/CD 管道的构建块。
表 4-2
泰顿和库比涅斯
|情定
|
作为 Kubernetes 原语的实现
|
| --- | --- |
| 工作 | 任务是要执行的一系列命令。它实际上是一个 pod,而每个步骤都是该 POD 中的一个容器。 |
| TaskRun(任务运行) | 引用任务对象的 CRD。它接受任务对象的名称并执行它们。 |
| 管道 | 引用 TaskRun 对象的 CRD。它接受 TaskRun 对象的名称和执行顺序。它链接所有管道对象,如 task 和 PipelineResource 项。 |
| 管道运行 | 引用管道对象的 CRD。它产生 TaskRun 对象。它获取管道对象的名称并执行它们。它管理管道的执行和状态。 |
| 管道资源 | 要结帐的 git 存储库,要构建的 Docker 映像。 |
正如您在表 4-2 中看到的,PipelineRun 采用管道的名称,并创建运行任务对象(pod)的 TaskRun 对象,任务对象运行步骤(容器)。定义可以嵌套。例如,可以在 TaskRun 中定义任务,但是如果将它们定义为单独的对象并通过引用应用,通常会更容易跟踪它们。
由于任务是作为 Kubernetes pod 执行的,所以我们可以在 TaskRun 中定义 pod 调度规则,这样当 TaskRun 产生一个 pod 时,就会为它添加注释,以利于 kube-scheduler。此外,由于 Tekton 运行只是另一个 Kubernetes 对象,它的输出可以像任何其他资源一样通过使用kubectl get <POD_NAME> -o yaml
来记录和读取。
我们还可以使用kubectl logs -f
跟踪 pod 的日志。这意味着我们不需要登录到 CI/CD 提供商的网站来查看构建日志。因此,这为 Kubernetes 事件和管道事件提供了单一的日志来源。
我们现在将在 Kubernetes 集群上安装和配置 Tekton,并安装 Tekton CLI。对于动手练习,我们将在 GCP 云壳上安装预先安装的 Kubernetes 版本 1.17.8-gke.17 的 Tekton 官方版。使用以下步骤安装 Tekton 及其所需的依赖项。
步骤 1:使用以下命令创建服务帐户:
gcloud iam service-accounts create tekton --display-name Tekton
图 4-31 显示了结果。
图 4-31
创建服务帐户
步骤 2:现在使用以下命令向服务帐户添加权限。首先:
export GCP_PROJECT=$(gcloud config get-value project)
图 4-32 显示了该命令成功执行后的输出。
图 4-32
向服务帐户添加权限
然后发出以下命令:
gcloud projects add-iam-policy-binding ${GCP_PROJECT} \--member serviceAccount:tekton@${GCP_PROJECT}.iam.gserviceaccount.com \--role roles/storage.admin
图 4-33 显示了该命令成功执行后的输出。
图 4-33
绑定到帐户的策略
下面是下一个命令:
gcloud projects add-iam-policy-binding ${GCP_PROJECT} \--member serviceAccount:tekton@${GCP_PROJECT}.iam.gserviceaccount.com \--role roles/container.developer
图 4-34 显示了该命令成功执行后的输出。
图 4-34
绑定到帐户的策略
步骤 3:在这一步中,使用以下命令启用 Kubernetes 引擎 API:
gcloud services enable container.googleapis.com
步骤 4:现在让我们创建一个名为tekton-workshop
的集群。在 GCP 控制台上,导航到 Kubernetes 引擎➤集群,如图 4-35 所示。
图 4-35
创建一个集群
第五步:输入tekton-workshop
等必填字段,选择us-east1-d
区,如图 4-36 。
图 4-36
向集群添加参数
另外,请确保选择“主版本”作为发布版本,并在单击“创建”按钮之前,从“发布通道”下拉列表中选择“快速通道–1 . 17 . 8-gke . 17”。见图 4-37 。
图 4-37
选择 Kubernetes 版本
创建集群需要一些时间。创建后,其名称将出现在 Kubernetes 引擎仪表板中,如图 4-38 所示。
图 4-38
创建集群仪表板
步骤 6:安装 Tekton CLI,因为使用 Tekton 实现 CI/CD 需要它。要安装 Tekton CLI,首先下载 TAR 文件,并使用以下命令将其复制到本地/bin
文件夹:
curl -LO https://github.com/tektoncd/cli/releases/download/v0.2.0/tkn_0.2.0_Linux_x86_64.tar.gz
sudo tar xvzf tkn_0.2.0_Linux_x86_64.tar.gz -C /usr/local/bin/ tkn
成功执行如图 4-39 所示。
图 4-39
下载 tekton cli
步骤 7:我们将首先通过执行以下命令,连接到我们在本章前面使用云外壳创建的集群:
gcloud container clusters get-credentials tekton-workshop --zone us-east1-d --project learndmproject
图 4-40 显示了该命令成功执行后的输出。
图 4-40
连接到集群
步骤 8:设置完成后,我们通过运行以下命令将 Tekton 安装到集群中:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
图 4-41 显示了该命令成功执行后的输出。
图 4-41
安装 Tekton 集群
步骤 9:现在,通过执行以下命令查看可用的名称空间来验证 Tekton 在集群上的安装(参见图 4-42 )。第二个命令获取一个吊舱列表(参见图 4-43 )。第三个命令获取关于 Tekton 名称空间的详细信息(参见图 4-44 )。
第一个命令是:
kubectl get namespace
图 4-42 显示了结果。
图 4-42
获取 Tekton 名称空间
第二个命令是:
kubectl get pods –namespace tekton-pipelines
图 4-43 显示了结果。
图 4-43
去拿泰克顿豆荚
第三个命令是:
kubectl get all --namespace tekton-pipelines
图 4-44 显示了结果。
图 4-44
获取 Tekton 名称空间详细信息
步骤 10:为了可视化 Tekton 管道,我们将安装 Tekton 仪表板。为此,请运行以下命令:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
图 4-45 显示了结果。
图 4-45
安装 Tekton 仪表板
要验证 Tekton 仪表板的安装,请执行以下命令:
kubectl get all --namespace tekton-pipelines
图 4-46 显示了该命令成功执行后的输出。
图 4-46
验证 Tekton 安装
步骤 11:为了检查仪表板,我们将设置从云 Shell 到 Tekton 仪表板的端口转发。为此,请执行以下命令:
export TEKTON_POD=$(kubectl get pods -n tekton-pipelines -o jsonpath="{.items[0].metadata.name}" -l app=tekton-dashboard)
kubectl port-forward --namespace tekton-pipelines $TEKTON_POD 8081:9097 >> /dev/null &
图 4-47 显示了结果。
图 4-47
仪表板端口转发
要验证仪表板,请在云外壳中单击 web 预览,然后选择 8081 端口上的预览,如图 4-48 所示。
图 4-48
Tekton 仪表板预览端口
点击端口 8081 后,Tekton 仪表盘将打开,如图 4-49 所示。此时,将看不到任何任务、管道、PipelineResource 或 PipelineRun,因为我们尚未创建任何任务、管道、管道资源或管道运行。我们将在后续部分中创建这些。
图 4-49
泰克顿仪表板
Tekton 管道的用例实现
现在让我们学习如何创建和运行任务和管道。为此,我们将考虑一个 hello world 示例。按照这些步骤来理解在 GCP 上使用 Tekton 的 CI/CD 实现。我们将首先看到如何创建和运行一个任务。
步骤 1:在本地创建一个名为task
的文件夹,并在其中创建一个名为hello-world.yaml
的 YAML 文件。将图 4-50 中的代码片段复制到文件中。
图 4-50
你好 Tekton 车间示例
现在执行这个命令:
kubectl apply -f tasks/hello-world.yaml
图 4-51 显示了该命令成功执行后的输出。
图 4-51
部署 Tekton 研讨会示例
步骤 2:该任务在集群中不会显示为 pod。为了使它可见,我们将创建一个 TaskRun 来调用我们创建的任务。执行以下命令:
kubectl apply -f taskruns/hello-world.yaml
图 4-52 显示了该命令成功执行后的输出。
图 4-52
部署 Tekton 研讨会示例
使用以下命令验证部署:
kubectl get pods
图 4-53 显示了该命令成功执行后的输出。
图 4-53
检查展开的吊舱
现在使用以下命令检查日志:
kubectl logs -l tekton.dev/task=echo-hello-world
图 4-54 显示了该命令成功执行后的输出。
图 4-54
检查展开的吊舱
现在,让我们构建一个 CI/CD 管道,了解 Tekton 的所有组件如何在 GCP 上协同工作。在这个用例中,我们将使用 Tekton 配置一个管道。在第一阶段,我们将从 GitHub 中检查代码,在第二阶段,我们将构建代码并将其推送到容器注册中心。管道的流程如图 4-55 所示。
图 4-55
CI/CD 管道流量
您可以下载 Git 资源库中的代码。使用以下命令克隆存储库:
git clone https://github.com/dryice-devops/GCPAutomation-Tekton.git
在您克隆了存储库之后,转到GCPAutomation-Tekton/getting-started/src/
目录;它包含两个文件夹和一个文件:
-
app
:包含一个简单的 Python Flask web 应用 -
tekton
:包含用例将要使用的规范 -
Dockerfile
:将用于构建应用和创建图像的 dockerfile 文件
对于这个用例,我们将把图像存储在本地文件夹中。
步骤 1:为了开始这个用例,我们将首先在集群中创建一个名为tekton-example
的新名称空间,并提供所需的权限。要创建新的集群,请执行以下命令:
kubectl create namespace tekton-example
图 4-56 显示了该命令成功执行后的输出。
图 4-56
创建名称空间
现在创建一个名为tekton-example-rbac.yaml
的 YAML 文件,并将图 4-57 所示的代码粘贴到其中。
图 4-57
角色访问文件
现在运行以下命令来应用角色访问级别更改:
kubectl apply -f tekton-example-rbac.yaml
图 4-58 显示了该命令成功执行后的输出。
图 4-58
配置基于角色的访问
步骤 2:创建一个集群,如“在 GCP 建立 Tekton 管道”一节中的步骤 4 和 5 所述。我们将创建一个名为tekton-example
的集群。创建集群后,从云外壳使用以下命令连接到集群:
gcloud container clusters get-credentials tekton-example --zone us-central1-c --project learndmproject
步骤 3:现在通过运行以下命令将 Tekton 安装到这个集群中:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
图 4-59 显示了该命令成功执行后的输出。
图 4-59
安装 Tekton
步骤 4:现在,通过执行以下命令查看名称空间和 pod,验证 Tekton 在集群上的安装:
kubectl get namespace
图 4-60 显示命令成功执行后的输出。
图 4-60
Tekton 部署
步骤 5:现在是时候为应用的构建和部署设置环境了。执行这些命令:
sudo mkdir mnt/data
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
kubectl apply -f ~/GCPAutomation-Tekton/getting-started/src/tekton/init.yaml --namespace=tekton-example
kubectl delete configmap/config-artifact-pvc -n tekton-pipelines
kubectl create configmap config-artifact-pvc --from-literal=storageClassName=manual -n tekton-pipelines
这些命令将设置环境,如图 4-61 所示。
图 4-61
环境设置
步骤 6:在这一步中,我们将创建任务来运行在app/
文件夹中可用的测试。它将首先从 GitHub 克隆源代码。接下来,它将使用 Docker 构建容器映像,并将其保存在本地。克隆 YAML 文件中代码的说明如图 4-62 所示。在下面的代码片段中,spec.input.resource
字段中指定的类型git
是 Tekton 的内置资源类型之一。它指定任务必须将 GitHub 存储库作为其输入。名称git
告诉 Tekton 将存储库克隆到本地/workspace/git:
图 4-62
构建 YAML 代码片段
接下来,我们将在代码中定义步骤。Tekton 使用工具图像来运行命令。在下面的代码片段中,使用了python
图像,并运行命令以切换到app/
目录。它安装所需的依赖项,并使用pytest
运行所有测试,如图 4-63 所示。
图 4-63
构建 YAML 代码片段
下一步确定测试完成后,YAML 文件必须将代码容器化。我们将使用 Docker 构建容器映像,并以名称app
保存在本地,如图 4-64 所示。
图 4-64
构建 YAML 代码片段
现在,我们通过运行以下命令来应用该任务:
cd ~/GCPAutomation-Tekton/getting-started/src/tekton/ && kubectl apply -f tasks/build.yaml --namespace=tekton-example
该命令将应用构建和测试 app,如图 4-65 所示。
图 4-65
应用构建
步骤 7:在构建和测试步骤执行之后,我们将应用kubectl
命令,该命令将用于启动构建在集群中的容器。图 4-66 描述了使用 Kubernetes 命令的工具映像lachlanevenson/k8s-kubectl
进行部署,然后公开映像以供外部访问。
图 4-66
部署 YAML 代码片段
现在,我们将通过运行以下命令来应用该任务:
cd ~/GCPAutomation-Tekton/getting-started/src/tekton/ && kubectl apply -f tasks/deploy.yaml --namespace=tekton-example
这些命令将应用 app 的部署,如图 4-67 所示。
图 4-67
部署构建
在上一节中,我们已经部署了 Tekton 仪表板,因此我们可以看到在仪表板中创建的任务,如图 4-68 所示。
图 4-68
任务仪表板
步骤 8:现在任务已经创建,我们将创建构建这两个任务的管道。管道将包括任务将使用的所有资源。为了触发管道,我们将资源类型指定为git
,Tekton 将把它传递给请求它们的任务(在spec.resource
字段中指定,如图 4-69 )。
图 4-69
管道 YAML 代码片段
对于每个任务,我们还指定了 Tekton 管道可以分配给它们的输入和输出资源。在图 4-70 中,我们定义了流水线中任务的名称以及特定任务使用的输入/输出资源。
图 4-70
管道 YAML 代码片段
我们通过运行以下命令来应用任务:
cd ~/GCPAutomation-Tekton/getting-started/src/tekton/ && kubectl apply -f pipelines/pipeline.yaml --namespace=tekton-example
这些命令将创建如图 4-71 所示的管道。
图 4-71
管道部署
在 Tekton 仪表板中,我们可以看到管道已经创建,如图 4-72 所示。
图 4-72
管道仪表板
步骤 9:到目前为止,我们已经创建了管道,但是只指定了类型(Git)。我们现在将把该值指定为 GitHub 存储库的 URL。Tekton 使用管道资源来存储这些值。图 4-73 中的代码片段定义了图 4-73 的param.name
字段中显示的metadata
字段中显示的管道资源的名称、存储库的版本/分支以及存储库的 URL。
图 4-73
Git YAML 代码片段
我们通过运行以下命令来应用任务:
cd ~/GCPAutomation-Tekton/getting-started/src/tekton/ && kubectl apply -f resources/git.yaml --namespace=tekton-example
这些命令将创建一个 Git,如图 4-74 所示。
图 4-74
Git 部署
在 Tekton 仪表板中,我们可以看到 Git 已经被创建,如图 4-75 所示。
图 4-75
管道资源部署
步骤 10:现在我们已经创建了任务、管道和 PipelineResources,我们可以通过手动触发来运行 CI/CD。为了运行它,我们创建了一个 pipelineRun 类型的 YAML 文件。它应该包括管道的名称及其使用的管道资源,如图 4-76 所示。
图 4-76
运行 YAML 代码片段
我们通过运行以下命令来应用任务:
cd ~/GCPAutomation-Tekton/getting-started/src/tekton/ && kubectl apply -f pipelines/run.yaml --namespace=tekton-example
这些命令将运行管道,如图 4-77 所示。
图 4-77
管道运行
一旦管道成功执行,我们可以在 Tekton 仪表板中看到结果。它将显示一个带有勾号的绿色圆圈,如图 4-78 所示。
图 4-78
管道运行仪表板
您可以通过点击管线名称深入查看管线运行的状态,如图 4-79 所示。
图 4-79
管道运行仪表板
步骤 11:为了验证管道的状态,我们可以运行以下命令:
kubectl get pipelineruns/build-test-deploy-app-run -o yaml
这些命令将验证管道运行状态,如图 4-80 所示。
图 4-80
管道状态
当运行成功时,它将显示带有"Succeeded"
状态的"All Steps have completed executing"
消息。运行管道时检查错误消息;这些字段将显示原因以及故障排除说明。
您还可以使用以下命令检查群集的部署并查找已部署群集的 IP;输出如图 4-81 所示。
图 4-81
部署状态
kubectl get svc –namespace tekton-example
通过执行以下命令,可以使用外部 IP 35.238.215.121
访问部署的服务,如图 4-79 所示:
curl http:// 35.238.215.121
图 4-82 显示了命令成功执行时的输出。
图 4-82
部署的服务
同一个网址(http:// 35.238.215.121
)可以从浏览器访问,如图 4-83 所示。
图 4-83
在浏览器上部署服务
摘要
本章介绍了 Tekton 的核心概念以及如何使用 Tekton 定义管道的步骤。您还了解了如何使用配置文件定义 task、taskRun、pipeline 和 PipelineResource,并在 Google Cloud Platform 上的 GKE 中使用它们。在下一章中,我们将讨论如何利用 Jenkins 以及部署管理器、源代码回购等 GCP 本地服务在 GCP 上部署应用。
五、Jenkins 和 GCP 的自动化——本地 CI/CD 服务
本章介绍了在 GCP 上部署应用的 Jenkins 和 GCP 本地 CI/CD 服务。本章涵盖以下主题:
-
自动化简介
-
GCP 开发自动化概述
-
Jenkins 概述
-
使用 GCP 开发自动化工作流设置 Jenkins
-
使用 Jenkins 和 Google-native 服务的用例实现
自动化简介
快速的技术进步和对更短上市时间的需求正在推动组织投资自动化技术。这导致了我们现在都知道的哲学的发展。DevOps 的主要目标是提高组织高速交付服务的能力,同时确保质量、稳定性和安全性。
CI/CD(持续集成/持续部署)是 DevOps 生态系统中的常见实践。它带来了以下好处:
-
每天/每周/每月频繁部署
-
发布中的低失败率和更少的安全错误
-
连续修复/发布之间的时间更短
-
更快上市
典型的应用发布工作流程如图 5-1 所示。
图 5-1
DevOps 工作流程
该方法基于以下方法,主要由围绕人员-流程-工具的 DevOps 原则组成:
-
需求管理
-
使用 Scrum/看板流程实现敏捷的项目计划和交付方式
-
在 ALM 工具中收集和记录产品要求
-
通过持续产品开发活动、发布计划和依赖关系的单一仪表板视图,促进开发、测试和运营团队之间的协作
-
-
连续累计
-
支持新代码的 SDLC 流程集成,这些新代码是通过自动化构建、单元测试、代码质量和工件存储库开发的
-
为自动化应用和基础架构供应提供各种确定工具之间的协调
-
-
环境供应
-
通过自动化配置管理和验证活动,允许零接触配置基础架构组件,包括虚拟机或容器、存储、网络和产品
-
作为 API 参考点公开的基础设施组件将集成到自动化管道中
-
-
连续测试
-
支持左移方法,以缩短整个 SDLC 流程(包括基础架构构建)的交付时间
-
识别缺陷和不符合商定的设计原则的情况,避免过晚发现可能导致向最终用户交付的应用增加的问题
-
-
应用和基础架构的持续部署
-
将通过 CI 管道构建和测试的应用代码自动部署到目标环境中
-
在开发测试环境中包括自动化基础架构供应阶段,以支持开发人员按需请求
-
在前一章中,我们介绍了各种独立的自动化组件——GCP 部署管理器、Spinnaker 和 Tekton。我们还讨论了他们的架构和工作方式。现在,我们将了解如何使用 Jenkins 作为 CI 工具和 GCP 本地的自动化服务来实施端到端 CI/CD 流程。
GCP 开发的自动化
在这一章中,您将了解 Google 提供的用于应用开发和 CI/CD 的关键本地服务。在本章的后面,您还将学习如何与 Jenkins 一起使用这些服务。以下是我们将利用的 GCP 提供的服务:
-
云代码(IDE)
-
云资源存储库(SCM)
-
代码构建(CI/CD)
-
云存储
-
工件注册中心(图像存储库)
云代码
云代码帮助开发人员编写、运行和调试使用 Kubernetes 或 GCP 云的云原生应用。它允许开发人员在容器化应用开发期间专注于编写代码,而不用担心管理配置文件。此外,它还提供了现成的模板示例,具有快速入门的优势。开发人员可以在从 IDE 开发应用时轻松利用本机云 API。它还有用户友好的文档。
诸如代码完成、内联文档、林挺和代码片段等各种功能都与原生 GCP 服务捆绑在一起。
云资源存储库
Google Cloud Source Repository 用于管理应用和基础设施供应流程的源代码。它是一个托管在 Google 云平台上的全功能私有 Git 存储库,提供了从 GitHub 和 Bitbucket 存储库镜像代码的灵活性,并使用强大的正则表达式跨多个目录执行代码搜索、代码浏览和代码诊断。
Cloud Source Repository 带有内置集成,用于持续集成,帮助开发人员快速获得任何缺陷或错误的反馈。用户可以设置触发器,以便在新代码被推送到云源代码库中时,使用 Google Cloud Build 自动构建和测试代码。开发人员还可以在生产环境中调试代码行为,而无需停止/减慢应用,集成了 Google Cloud Debugger 和云源代码库。Google Cloud Repository 与云审计日志集成在一起,并提供有关已执行操作的信息。这有助于管理员跟踪更改。
代码构建
Cloud Build 是 Google 云平台提供的 CI/CD(持续集成和持续部署)解决方案,用于通过 pipeline 服务执行源代码构建、测试和部署。云构建实现了快速软件构建,并支持多种语言。开发人员可以在多个环境中部署工件,比如虚拟机、无服务器环境、Kubernetes 等等。它使用户能够控制构建、测试和部署过程的定制工作流的定义。
作为 CI/CD 管道执行的一部分,它还执行深度安全扫描,如漏洞扫描。如果发现任何漏洞,Cloud Build 会根据安全或 DevSecOps 团队设置的策略自动阻止部署。Cloud Build 是由 Google Cloud 提供的一个完全无服务器的平台,它可以根据负载进行伸缩。代码构建使用构建配置文件,该文件采用 YAML 或 JSON 格式,包含云构建执行构建、测试和部署过程的指令。
云存储
Google 提供了一种对象存储服务,称为云存储,可以存储任何文件格式(例如,PNG、ZIP、WAR 等。)而这些对象本质上是不可变的。这些对象存储在一个叫做桶的容器中,这个容器与项目相关联。创建存储桶后,您可以上传/下载对象。它支持对象级访问和权限,以精细地管理安全性。可以通过控制台、gsutil
、客户端库、REST APIs 与云存储交互。在本章中,我们使用云存储来存储构建工件,并使用命令行工具gsutil
通过云外壳与云存储交互。此外,GCP 云存储提供以下安全功能来保护您的对象:
-
身份和访问管理(IAM) : IAM 允许您授予成员对存储桶和对象的特定类型的访问权限,例如更新、创建或删除。
-
数据加密:默认情况下,云存储使用服务器端加密来加密对象。您还可以使用补充数据加密选项,如客户管理的加密密钥和客户提供的加密密钥。
-
桶锁:通过指定保留策略来控制桶中的对象必须保留多长时间。
-
对象版本:防止数据被覆盖或意外删除。
工件注册表
Google 的工件注册中心存储构建工件。它是一个通用的构建工件管理系统,因为它存储了语言包,如 Maven、npm 和容器映像。它与 Google Cloud 的工具 runtimes 完全集成,并为您提供了与 CI/CD 工具集成的灵活性。通过 IAM 角色和权限,组织可以保持对谁可以访问、查看和下载工件的控制。您可以在给定的 Google Cloud 项目下创建多个存储库。通过使用标准的命令行界面,用户可以从 Artifact Registry 的私有存储库中推送和提取 Docker 映像、Maven 和 npm 包。Google Artifact Registry 支持区域和多区域存储库。
Jenkins 简介
正如本书关于 CI/CD 实践的介绍部分所讨论的,我们将使用 Jenkins 实现 CI。CI 是 DevOps 最重要的部分,主要用于将 DevOps 的各个阶段集成在一起。
Jenkins 是执行持续集成和构建自动化的领先开源工具之一。它是用 Java 编写的,带有内置的 CI 插件。它执行预定义的步骤集(如代码编译、构建执行、测试执行等。).执行的触发器可以基于时间或事件来控制。我们可以将 Jenkins 与源代码/版本控制系统集成,如 GitHub,并可以执行基于 Apache Ant 和 Apache Maven 的项目,以及任意 shell 脚本和 Windows 批处理命令。Jenkins 的主要功能包括代码管道、改进的插件和安全性,以及直观的 UX 和 UI。
Jenkins 基于主/从架构,如图 5-2 所示。从设备是一个代表主设备的执行器。master 是 Jenkins 工具的基础安装,参与基本管理操作,并作为用户界面工作。主设备触发在从设备上执行的工作。
图 5-2
Jenkins 主/从架构
在图 5-2 中,主 Jenkins 服务器是主服务器,执行调度构建作业和将构建分派给从服务器执行的工作。当需要记录和呈现构建结果时,主服务器还监控从服务器的在线和离线状态。主服务器甚至可以直接执行构建作业。
Jenkins 是一个广泛使用的 CI 工具,其功能将在以下章节中介绍。
Jenkins·UX 和 UI
Jenkins 有一个非常简单易用的 UI/UX,用于方便地可视化构建、测试和部署流程。您可以轻松地执行配置。您还可以很好地了解 Jenkins 管道,包括用于验证、查看和编辑这些管道的可视化编辑器。
Jenkins 插件和安全性
Jenkins 需要插件来集成不同的工具,以实现 CI/CD 管道流。集成任何特定的工具,如 Git,GCP 计算机引擎。或者 Amazon EC2,Maven project,HTML publisher 等等,都需要下载合适的插件,集成工具。大量的插件是可用的。如果插件不可用,您可以开发它并将其添加到社区中。Jenkins 还允许您设置各种安全功能,包括基于角色的访问(RBAC)、用户管理和凭证管理。
Jenkins 建立管道
Jenkins 中的一个项目是包含步骤和构建后操作的构建作业的重放。它是使用 Jenkins 创建的连续交付管道的实现和支持集成所需的插件的组合。您可以使用以下方法在 Jenkins 中创建工作。
自由式项目
自由式构建作业是一个高度灵活且易于使用的选项。它可用于任何类型的项目来构建 CI/CD 管道。Jenkins freestyle 项目中有许多标准插件可以帮助您构建步骤和管理构建操作。
管道
将源代码中的变更转换成发布工作产品的过程是在一系列阶段中定义的,这些阶段统称为管道。在这里,一个阶段的成功完成导致调用序列中的下一个自动化阶段。管道提供了一组可扩展的工具,用于通过管道领域特定语言(DSL)语法将简单到复杂的交付管道定义为“代码”。“管道代码”存储在源存储库中并进行版本控制。作为代码的管道可以使用“Jenkinsfile”来实现,它是包含“管道脚本”的存储库根项目的一部分可以使用两种方法编写 Jenkinsfile:
-
宣言的
-
有剧本的
声明式管道和脚本式管道的构造完全不同。声明性管道有大量的语法属性。表 5-1 中显示了示例代码的比较表示。
表 5-1
声明式和脚本式代码片段
|宣言的
|
有剧本的
|
| --- | --- |
| 管道{任何代理阶段{阶段('构建'){步骤{//}}阶段('测试'){步骤{//}}登台('部署'){步骤{//}}}} | 节点{阶段('构建'){//}阶段('测试'){//}登台('部署'){//}} |
Jenkinsfile 是在源代码项目的父目录中定义的。使用 Groovy DSL 定义了一个声明性的 Jenkinsfile 代码。
-
pipeline
是声明性的特定于管道的语法,其定义了包含用于执行整个管道的所有内容和指令的块。 -
agent
是特定于管道的声明性语法,指示 Jenkins 为整个管道分配一个执行器(在一个节点上)和工作空间。 -
stage
是描述该流水线的一个阶段的语法块。在脚本管道语法中,阶段块是可选的。 -
steps
是特定于管道的声明性语法,描述了将在此阶段执行的实际步骤。
脚本化的 Jenkinsfile 代码定义如下:
-
在任何可用的代理上执行此管道或其任何阶段。这定义了分别包含构建、测试和部署应用的代码的
build
、test
和deploy
阶段。 -
在脚本化管道语法中,块是可选的。但是,在脚本化管道中实现阶段块可以在 Jenkins UI 中更清晰地显示每个阶段的任务/步骤子集。
在本书的上下文中,我们将使用脚本化的 Jenkinsfile 代码。
用 GCP 开发自动化设置 Jenkins
现在,我们已经讲述了与 CI/CD、Jenkins 和 GCP 本地自动化服务相关的基本概念,我们可以开始设置实施 CI/CD 管道和部署应用的环境。
设置环境
在本教程中,我们将首先创建一个名为learncicd
的新项目。点击新建项目选项,如图 5-3 ,然后输入项目名称,如图 5-4 。创建新项目后,它将被列出,如图 5-5 所示。
图 5-5
显示新项目
图 5-4
创建新项目
图 5-3。
新建项目屏幕
推出谷歌云壳
在这一步中,我们将启动 Google Cloud Shell,并使用 Google CLI 命令继续下一个设置活动。点击 Google 云控制台左上角的图标打开云壳,如图 5-6 所示。这将为
learncicd
项目的会话打开 Google Cloud Shell,如图 5-7 所示。
图 5-7
谷歌云外壳屏幕
图 5-6
项目仪表板屏幕
安装和配置 Jenkins
要安装和配置 Jenkins,我们需要创建服务帐户。使用以下命令创建一个名为jenkins
的服务帐户:
gcloud iam service-accounts create jenkins --display-name jenkins
执行该命令后,我们可以看到名为jenkins
的服务账户已经创建,如图 5-8 所示。
图 5-8
创建服务帐户
设置环境变量
在下一步中,我们将在云 Shell 的运行会话中将服务帐户 email 和项目设置为环境变量。这些将用于设置环境。
export SA_EMAIL=$(gcloud iam service-accounts list \
--filter="displayName:jenkins" --format='value(email)')
export PROJECT=$(gcloud info --format='value(config.project)')
这将把电子邮件和项目 ID 设置为云外壳环境变量。
绑定角色
现在,我们需要将一些角色绑定到服务帐户,以便我们可以设置和配置环境。
gcloud projects add-iam-policy-binding $PROJECT \
--role roles/storage.admin --member serviceAccount:$SA_EMAIL
该命令会将存储管理员的 IAM 策略绑定到服务帐户,如图 5-9 所示。
图 5-9
设置存储管理 IAM 策略
gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.instanceAdmin.v1 \ --member serviceAccount:$SA_EMAIL
该命令会将 IAM 策略绑定到计算实例 admin 到服务帐户,如图 5-10 所示。
gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.networkAdmin \ --member serviceAccount:$SA_EMAIL
图 5-10
设置计算实例管理 IAM 策略
该命令会将计算网络管理员的 IAM 策略绑定到服务帐户,如图 5-11 所示。
gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.securityAdmin \ --member serviceAccount:$SA_EMAIL
图 5-11
设置计算网络管理 IAM 策略
该命令会将计算安全管理员的 IAM 策略绑定到服务帐户,如图 5-12 所示。
gcloud projects add-iam-policy-binding $PROJECT --role roles/iam.serviceAccountActor \ --member serviceAccount:$SA_EMAIL
图 5-12
设置计算安全管理 IAM 策略
该命令将服务账户 actor 的 IAM 策略绑定到服务账户,如图 5-13 所示。
图 5-13
设置服务帐户执行元 IAM 策略
下载服务帐户密钥
在此步骤中,我们需要下载服务帐户密钥,稍后将在安装过程中使用。要下载密钥,请使用以下命令:
gcloud iam service-accounts keys create jenkins-sa.json --iam-account $SA_EMAIL
该命令将创建服务账户密钥,如图 5-14 所示。
图 5-14
服务帐户密钥
现在已经创建了密钥,我们需要下载它并将其保存在本地文件夹中。点击三点图标,从下拉列表中选择下载文件选项,如图 5-15 所示。
图 5-15
下载服务帐户密钥
单击下载文件选项,这将依次显示一个窗口,要求您输入文件名。进入jenkins-sa.json
后点击下载按钮开始下载,如图 5-16 所示。
图 5-16
下载文件
文件将被下载并出现提示信息,如图 5-17 所示。
图 5-17
下载确认
可以看到下载的文件存储在本地下载文件夹中,如图 5-18 所示。
图 5-18
下载的文件在本地下载文件夹中
创建一个 SSH 密钥
现在我们将创建 SSH 密钥,这是使用 SSH 与其他实例通信所必需的。为了启用 SSH 访问,我们将创建并上传 SSH 密钥。使用以下命令创建密钥:
ls ~/.ssh/id_rsa.pub || ssh-keygen -N ""
该命令将创建密钥,如图 5-19 所示。
图 5-19
创建 SSH 密钥
我们将使用以下命令将密钥上传到云 Shell:
gcloud compute project-info describe \ --format=json | jq -r '.commonInstanceMetadata.items[] | select(.key == "ssh-keys") | .value' > sshKeys.pub
echo "$USER:$(cat ~/.ssh/id_rsa.pub)" >> sshKeys.pub
gcloud compute project-info add-metadata --metadata-from-file ssh-keys=sshKeys.pub
结果如图 5-20 所示。
图 5-20
密钥已上传到云壳
构建虚拟机映像
在这一步中,我们使用 Packer 来构建构建代理的 VM 镜像,它将被用作构建执行器。为此,我们将首先下载并解包 Packer,分别如图 5-21 和图 5-22 所示。
图 5-21
下载打包程序
wget https://releases.hashicorp.com/packer/0.12.3/packer_0.12.3_linux_amd64.zip
unzip packer_0.12.3_linux_amd64.zip
图 5-22
解压缩打包器
现在我们需要为打包映像构建创建一个配置文件。执行以下命令,将创建jenkins-agent.json
文件,如图 5-23 所示。
图 5-23
映像构建 JSON 文件
现在配置文件已经准备好了,我们将运行下面的命令来生成映像构建。
./packer build jenkins-agent.json
该命令将创建如图 5-24 和 5-25 所示的图像。
图 5-25
打包器构建输出
图 5-24
打包器构建输出
在图 5-25 的末尾,我们可以看到磁盘映像是为名为Jenkins-agent-1598599961
的 Jenkins 代理创建的,我们稍后将使用它来创建实例。我们可以在谷歌云控制台中看到新创建的图像。导航到计算引擎仪表板下的图像页面,如图 5-26 所示。
图 5-26
Jenkins-代理图像列表
创建计算引擎映像
在这一步中,我们将从云市场创建一个计算引擎实例,它将预先配置 Jenkins,并将在本教程中充当 Jenkins 主服务器。使用以下链接访问云市场,并使用预配置的 Jenkins 启动计算引擎实例:
点击该链接,将会打开云商城页面,如图 5-27 所示。单击启动按钮启动计算引擎。
图 5-27
Jenkins 实例启动屏幕
在下一页上,选择您在前面部分中创建的learncicd
项目。点击项目名称,如图 5-28 所示。
图 5-28
选择项目屏幕
在下一步中,将要求您输入关于您想要使用的虚拟机配置的详细信息,如图 5-29 所示。
图 5-29
Jenkins 实例详细信息屏幕
确保选择了4 vCPUs 15 GB Memory, n1-standard-4
机型,如图 5-30 所示。这是本教程剩余部分所需的最低配置。
图 5-30
Jenkins 实例详细信息屏幕
您可以将其余字段保留为默认值,并单击 Deploy 按钮(如图 5-31 所示)开始提供 Jenkins 实例。这需要一些时间,并将显示消息Jenkins-1 has been deployed
。
图 5-31
Jenkins 实例详细信息屏幕
一旦 Jenkins 实例被创建,从菜单中导航到部署管理器仪表板,如图 5-32 所示。
图 5-32
部署管理器菜单
在部署管理器仪表板上,将会看到新创建的名为Jenkins-1
的 Jenkins 实例,如图 5-33 所示。
图 5-33
部署管理器仪表板
在 Deployment Manager 屏幕中,您将看到实例上部署的 Jenkins 的详细信息。它将包括站点地址、管理员用户名和管理员密码,如图 5-34 所示。
图 5-34
Jenkins 站点详细信息屏幕
使用站点地址打开 Jenkins 实例,如图 5-35 所示。第一页将是登录控制台。输入用户名和密码进入控制台,如图 5-35 所示。
图 5-35
Jenkins 登录屏幕
成功登录后,您将看到 Jenkins 管理页面和 Jenkins 欢迎消息。在右侧面板菜单上,有一些选项可以帮助您创建管道和设置集成配置,以及用户管理和其他管理任务,如图 5-36 所示。
图 5-36
Jenkins 管理屏幕
将谷歌云服务与 Jenkins 整合
在本节中,我们将了解如何设置、配置和集成 Google 云服务,如 Cloud Build、Cloud Storage、Cloud Compute Engine 和 Cloud Deployment Manager 与 Jenkins,并使用它们来构建应用代码部署的 CI/CD 管道。要开始配置,点击右边菜单中的管理 Jenkins 选项,如图 5-37 所示。
图 5-37
管理 Jenkins 屏幕
点击“管理插件”选项将进入插件管理器屏幕,在这里我们将插件加载到 Jenkins 中。在插件管理器页面,安装与 Google 云服务相关的所有四个插件。要安装插件,我们需要在 Manage Jenkins 屏幕的 Available 选项卡中搜索插件,然后选择它们并单击 install。安装后,插件将在管理 Jenkins 屏幕的已安装选项卡中可见,如图 5-38 所示。
图 5-38
管理 Jenkins 屏幕
配置凭据
在这一步中,我们将配置凭据。为了与 Google Cloud Service 通信,Jenkins 需要使用步骤 6 中生成的密钥创建和配置一个凭证。点击 Jenkins 管理页面菜单部分的凭证选项,如图 5-39 所示。
图 5-39
Jenkins 屏幕
在凭据菜单中,单击名为系统的子菜单。接下来,点击系统页面中的全局凭证(无限制)链接,如图 5-40 所示。
图 5-40
Jenkins 管理页面凭证菜单选项
现在单击菜单中的添加凭证选项。在 Kind 下拉列表中,从 Private Key 选项中选择 Google 服务帐户,因为我们已经创建了一个密钥。项目名称将包含将要使用的 Google 帐户的项目 ID。参见图 5-41 。
图 5-41
Jenkins 凭据屏幕
当凭证被创建后,它们将被列出,如图 5-42 所示。
图 5-42
全局凭证列表屏幕
配置计算引擎插件
在这一步,我们需要在 Jenkins 中配置计算引擎插件。它将用于提供代理实例。同样,在 Jenkins 管理页面上,单击管理 Jenkins 选项,如图 5-43 所示。
图 5-43
管理 Jenkins 菜单选项
单击管理插件选项将打开插件管理器屏幕,您可以在其中单击配置系统选项。在此页面上,向下滚动,直到找到云选项。点击a separate configuration page
的超链接,如图 5-44 所示。这将导致您可以设置计算引擎实例配置的页面。
图 5-44
Jenkins 配置系统页
在“配置云”页面上,您需要添加一个新的云。单击添加新云下拉选项。这将显示 Google 计算引擎选项,它是可见的,因为我们在 Jenkins 中添加了 Google 计算引擎插件。选择选项,点击保存按钮,如图 5-45 所示。
图 5-45
Jenkins 配置云页面
在 Configure Clouds 页面中,我们将设置一系列值,Jenkins 将使用这些值在 Google Cloud 上创建实例。此处说明了字段及其值;也参见图 5-46 。
图 5-46
Jenkins Google 计算引擎详细信息页面
-
Name 字段包含 Google 计算引擎的名称,可以设置为任何名称。本教程使用
gce
。 -
项目 ID 字段包含与教程项目工作相关联的 Google 项目的 ID;我们将其设置为
learncicd-287805
。 -
“实例上限”字段需要一个数值,并指示在任何给定时间可以运行多少个构建实例。这里,我们随机将其设置为
8
-
服务帐户凭证下拉字段将列出我们在前面的步骤中在 Jenkins 中配置的凭证(请参考图 5-41 和 5-42 )。对于教程项目 ID,选择
learncicd-287805
值。
在实例配置部分,我们需要定义将在 Google Cloud 上创建的实例的细节。现在,我们将讨论本教程所需的相关字段及其值。此处未提及的字段可保留默认值或留空(参见图 5-48 )。
-
名称前缀字段用于为 Jenkins 启动的每个计算引擎实例创建唯一的名称。它可以是你想要的任何名字。在这里,我们将其命名为
ubuntu -1604
。 -
描述字段用于唯一定义实例,并适用于 Jenkins 启动的任何计算引擎实例;我们将它设置为
Ubuntu agent
。 -
节点保留时间字段指的是分钟数,在此时间后,非活动节点将被终止。最佳实践是将其设置为至少与实例的引导和配置时间一样长;我们将它设置为
6
。 -
Usage 字段确定 Jenkins 如何在该节点上安排构建。下拉菜单中有两个选项,如图 5-47 所示。
-
尽可能使用这个节点。通过此选项,Jenkins 在需要时使用节点;这是默认模式。
-
仅构建标签表达式与此节点匹配的作业。 Jenkins 只会在使用标签表达式将项目限制到某些节点,并且该表达式与该节点的名称和/或标签匹配时,在该节点上构建项目。
-
我们将设置默认选项,尽可能使用该节点,如图 5-47 所示。
图 5-47
Jenkins Google 计算引擎详细信息页面
-
标签字段将多个代理分组到一个逻辑组中;我们将它设置为
ubuntu-1604
。 -
“执行者数量”字段指示可以同时运行多少个进程。如果我们将其设置为两个执行者,这意味着 Jenkins 可以在任何给定的时间创建两个不同的流程,以便构建两个不同的任务;我们将它设置为
1
。 -
启动超时字段指示新节点必须供应并联机的秒数;我们将它设置为
300
。 -
“以用户身份运行”字段确定 Jenkins 代理进程将作为本地用户运行。默认为
jenkins
;我们将把它保留为jenkins
。
图 5-48
Jenkins Google 计算引擎详细信息页面
继续图 5-48 ,此处描述接下来的相关字段,其余可保留默认值或空白;参见图 5-49 。
图 5-49
Jenkins Google 计算引擎详细信息页面
-
Java Exec 路径字段指示要在代理上调用的 Java 可执行文件的路径;我们将它设置为
java
,这是 Jenkins 在$PATH
中默认设置的。 -
区域下拉列表将列出区域;我们将它设置为
us-central1
,我们用它来设置教程项目。 -
区域下拉列表将列出区域;我们将它设置为
us-central1-f
,我们用它来设置教程项目。
点击前进按钮,如图 5-49 所示。它将列出机器配置的字段。以下是相关字段(其他字段可以保留默认值或留空;参见图 5-50 。
图 5-50
Jenkins Google 计算引擎详细信息页面
- 机器类型下拉列表将列出所有自动可用的机器类型;我们将它设置为
n1-standard1
,我们用它来设置教程项目。
以下是相关的网络领域。其余的可以保留默认值或空白;参见图 5-51 。
图 5-51
Jenkins Google 计算引擎详细信息页面
- 网络和子网下拉列表将列出所有已定义的自动可用的网络和子网;我们将网络和子网设置为默认值
最后一组字段用于启动磁盘配置。以下是相关字段;其他可以保留默认值或留空;参见图 5-51 。
图 5-52
Jenkins Google 计算引擎详细信息页面
- 图像项目下拉列表会列出该项目中所有可用的图像,如图 5-52;我们选择名为
learncicd-287805
的教程项目。
图 5-53
Jenkins Google 计算引擎详细信息页面
- 图像名称下拉列表会列出所有可用的图像,包括我们之前创建的自定义图像(回头参考图 5-26 ,如图 5-53;我们将选择名为
jenkins-agent-1598599961
的自定义图像。
图 5-54
Jenkins Google 计算引擎详细信息页面
-
磁盘类型下拉列表会列出所有可用的磁盘类型,如图 5-54;我们将磁盘类型设置为
pd-balanced
。 -
Size 字段表示以千兆字节为单位的磁盘大小;我们将磁盘大小设置为
10
。 -
终止时删除字段指示实例将在终止时被删除;我们将选择此选项。
我们已经完成了设置,现在可以点击保存按钮保存配置,如图 5-55 所示。
图 5-55
Jenkins Google 计算引擎详细信息页面
测试配置
到目前为止,我们已经为 Jenkins 完成了所有的设置和配置,并将 Google 云服务与 Jenkins 集成在一起。现在我们将快速测试配置。为此,我们将使用 Jenkins 并创建一个测试管道作业,该作业在被触发时将自动启动一个实例。它将使用我们在前面的步骤中配置的名为ubuntu-1604
的代理。按照以下步骤构建测试管道。
第 1 步:在这一步中,导航到 Jenkins 管理控制台页面,并单击菜单中的 New Item 选项。这将打开一个窗口,输入项目的名称。将该项目称为test
。在选项中选择自由式项目选项,点击确定按钮,如图 5-56 所示。
图 5-56
创建自由式项目
步骤 2:在步骤 1 中创建的test
项目将显示在 Jenkins 管理控制台中。点击test
项并导航到项目测试页面。点击菜单项中的配置选项,如图 5-57 所示。
图 5-57
Jenkins 管理页面
步骤 3:从test
项目配置页面的 General 选项卡中,选择 Restrict Where This Project Can Run 选项,因为我们需要在代理机器上运行项目。在标签表达式文本框中,输入我们之前配置的代理名称(即ubuntu-1604
),如图 5-58 所示。
图 5-58
测试项目配置页面
向下滚动并导航到页面的 Build 选项卡,然后单击 Add Build Step。选择执行外壳选项(参见图 5-59 )。在执行 Shell 中(见图 5-60 ,输入echo "Hello World!"
命令。管道成功运行后,应该会在控制台中打印出来。单击 Save 并退出测试项目配置页面。
图 5-60
测试项目配置页面
图 5-59
添加构建步骤
在 Jenkins 项目测试页面,点击 Build Now 选项执行管道,如图 5-61 所示。
图 5-61
项目测试页面
管道运行成功后,我们可以看到控制台输出中打印出Hello World!
,如图 5-62 所示。
图 5-62
项目测试控制台输出页
在上一节中,我们介绍了 Jenkins 和 Google 云服务插件的安装、配置和设置。我们还在 Jenkins 中测试了配置。现在,您将设置一个 Google-native 服务——比如 Cloud Source Repository、Cloud Build、Cloud Storage 和 Deployment Manager——它将用于为应用部署设置 CD/CD。
设置 Google 原生服务
让我们从存储应用代码的云源代码存储库开始。按照以下步骤设置云资源存储库。
第一步:登录你的谷歌云平台,选择要做的项目。点击菜单部分,选择工具部分下的源库选项,如图 5-63 所示。
图 5-63
谷歌云:源代码库
步骤 2:单击 Source Repositories 选项,您将看到主页。点击开始选项,如图 5-64 所示。
图 5-64
谷歌云:源代码库:入门
下一页将提示您创建存储库。点击创建存储库选项创建存储库,如图 5-65 所示。
图 5-65
谷歌云:源存储库:创建存储库
第三步:接下来,会提示两个选项;
-
创建一个新的存储库,如果您想在 Google Source Repository 中创建存储库,可以使用它。
-
如果您想要镜像其他存储库,如 GitHub、Bitbucket 等,请连接一个外部存储库。
我们将选择第一个选项并单击继续按钮,如图 5-66 所示。
图 5-66
谷歌云:源存储库:添加存储库
步骤 4:在 Create Repository 页面上,提供存储库名称jpetstore
,并从下拉列表中选择项目。在我们的例子中,它将是learncicd-287805
。然后点击创建按钮,如图 5-67 所示。
图 5-67
谷歌云:源存储库-:添加存储库
下一个屏幕询问您希望如何将代码上传到存储库。有两种选择:
-
从本地 Git 存储库推送代码:这用于将您的本地存储库代码推送到一个新创建的云源代码存储库。在这种情况下,我们选择此选项将
jpetstore
源代码上传到云源代码库中,如图 5-68 所示。 -
将您的存储库克隆到本地 Git 存储库:当您想要将您的云源代码存储库克隆到您的本地 Git 存储库时,可以使用这个选项。
它还显示了将代码推送到存储库的步骤和命令。这可以通过三种方式实现——SS 认证、Google Cloud SDK 和手动生成凭证。在本教程中,我们将使用 Google Cloud SDK。
图 5-68
谷歌云:源代码库:代码推送
步骤 5:我们将在本教程项目中使用一个名为JpetStore
的小型 Java web 应用代码。GitHub 中提供了该应用的源代码,可以使用链接 https://github.com/dryice-devops/jpetstore
访问。我们将把相同的代码库推送到云储存库。
打开云 Shell,将 GitHub 存储库中的jpetstore
源代码克隆到您的本地存储库中。通过从主目录执行以下命令,可以做到这一点:
git clone https://github.com/dryice-devops/jpetstore.git
该命令会将源代码克隆到本地仓库,如图 5-69 所示。
图 5-69
谷歌云:源代码库:代码推送
第 6 步:执行以下命令进行 Google 身份验证。
gcloud init && git config --global credential.https://source.developers.google.com.helper gcloud.sh
第 7 步:进入jpetstore
目录,执行以下命令,将您的云存储库添加为远程存储库:
git remote add google https://source.developers.google.com/p/learncicd-287805/r/jpetstore
图 5-70
将云添加到本地存储库中
第八步:最后,我们将通过执行下面的命令把我们的本地jpetstore
代码推送到云源码库中,如图 5-71 所示。
图 5-71
谷歌云:源代码库:代码推送
git push --all google
第九步:一旦代码被推送到云源代码库,你会在 Google Cloud Console 上的云源代码库下看到整个代码库,如图 5-72 所示。
图 5-72
谷歌云:源代码库:代码推送
配置云构建
既然云存储库已经配置了示例代码库,我们将配置云构建来构建源代码并将工件存储到云存储中。按照以下步骤配置云构建。
第一步:在使用云构建之前,我们必须启用它的 API。导航到 APIs & Services 并选择 Dashboard 选项,如图 5-73 所示。
图 5-73
谷歌云:启用 API
第二步:在搜索框中搜索云构建 API 并选中,如图 5-74 所示。
图 5-74
谷歌云:启用 API
第三步:一旦你选择了这个选项,Google 会重定向到云构建 API 页面。点击启用按钮,启用其 API,如图 5-75 所示。
图 5-75
谷歌云:启用 API
启用云构建 API 后,将会打开云构建页面,如图 5-76 所示。
图 5-76
谷歌云:云构建
现在导航到 IAM 页面,选择我们创建的 Jenkins 服务帐户。添加云构建服务账户权限,如图 5-77 所示。Jenkins 需要云构建服务帐户权限才能从其管道执行云构建。
图 5-77
谷歌云:云构建
云存储设置
在本节中,我们将设置云存储来存储构建工件。
第一步:导航到存储区,点击浏览,如图 5-78 所示。
图 5-78
谷歌云:云构建
第 2 步:单击+ Create Bucket 选项,然后给这个 Bucket 起一个名字,比如tutorialstorage
。保持其他选项不变,点击创建按钮,如图 5-79 所示。
图 5-79
谷歌云:云构建
填写必填字段,如图 5-80 所示。
图 5-80
谷歌云:云构建
导航到存储浏览器页面,查看新创建的存储,如图 5-81 所示。
图 5-81
谷歌云:云构建
使用 Jenkins 和 Google-Native 服务的用例实现
在本章的前一部分,我们介绍了 Google Cloud-native services 和 Jenkins 的基本概念,包括它们的安装、设置和配置。现在,让我们开始创建 CI/CD 管道的真实场景,其中 Jenkins 充当指挥者。我们将实施端到端的应用、构建和部署流程,以及 Google Cloud-native 服务。CI/CD 管线的架构流程如图 5-82 所示。
图 5-82
CI/CD 管道流量
这个架构图显示 Jenkins 是一个编排者,他从 Google 云源代码库中检查代码库,并将控制权传递给 cloud build,用于构建应用和创建应用可部署工件。云构建将工件推到 Google 云存储中。Jenkins 触发部署经理启动 GCP 基础设施服务的供应,并在操作系统级别为应用部署设置先决条件。一旦部署管理器成功地完成了这个活动,它就会启动将工件从云构建部署到新创建的 GCP VM 的过程。
我们现在将看到如何通过 Jenkins 管道和 Google Cloud-native 服务来配置这个流。按照以下步骤实现 CI/CD 流程。
步骤 1:在创建管道之前,我们需要下载一个脚本,部署管理器将使用它来创建环境。遵循这些子步骤:
图 5-83
虚拟机实例仪表板
-
通过点击 VM 实例控制台中的 SSH 链接,登录到前面步骤中创建的 Jenkins 主服务器,如图 5-83 所示。
-
现在执行以下命令:
git clone https://github.com/dryice-devops/dmscript.git
图 5-84 显示了结果。
图 5-84
虚拟机实例仪表板
登录 Jenkins UI,点击新建物品选项,新建一个物品,如图 5-85 所示。
图 5-85
Jenkins 新项目选项
步骤 2:单击 New Item 选项,我们将看到一个新页面,用于在 Jenkins 中创建项目。
输入一个名称,在本例中我们使用的是tutorialProject
。选择 Freestyle 项目,点击 OK 按钮,创建 Jenkins 项目,如图 5-86 所示。
图 5-86
Jenkins 新项目
第三步:在新建的 Jenkins 项目中点击 Configure 选项,设置 CI/CD 流程不同执行步骤的配置,如图 5-87 所示。
图 5-87
Jenkins 配置选项
步骤 4:导航到 Build 选项卡,然后单击 Add Build Step。选择执行 Shell 选项,如图 5-88 所示。
图 5-88
Jenkins 添加构建步骤选项
步骤 5:选择执行 Shell 选项后,您将看到一个新的文本区域。添加下面的gcloud
命令,这是我们通过添加 Google Cloud 插件在设置 Jenkins 时配置的。这将从谷歌云仓库中提取代码,如图 5-89 所示。
图 5-89
Jenkins 添加构建步骤
gcloud source repos clone jpetstore --project=learncicd-287805
第 6 步:在同一个构建部分,再次点击添加构建步骤,选择执行 Google Cloud 构建选项,如图 5-90 所示。
图 5-90
Jenkins 添加构建步骤
步骤 7:在这一步中,我们将设置构建和打包代码的过程,并将构建工件(本质上是一个. War 文件)上传到 Google 云存储(tutorialstorage
),这是我们在前面的步骤中创建的。这里需要的第一个设置是从下拉列表中选择我们在 Jenkins 中创建的 Google 凭据,如图 5-91 所示。
图 5-91
Jenkins 执行谷歌云构建
现在我们需要提供附加源信息。源下拉选择本地,路径选择.
,如图 5-92 所示。
图 5-92
Jenkins 执行谷歌云构建
现在从下拉菜单中选择内联选项,并将下面的代码片段粘贴到文本框中(参见图 5-93 )。这个脚本是按顺序执行的,它首先使用 Maven(在/workspace/jpetstore
目录中)构建代码,然后传递 Maven 参数,比如用于清理工作目录的clean
。像package
这样的其他参数将构建代码并创建一个工件,在我们的例子中,它是一个. WAR 文件。这里,-DskipTests
参数用于忽略 Junit 测试用例。
图 5-93
部署脚本
工件选项定义了将包从/workspace/jpetstore/target/jpetstore.war
复制到 Google 云存储的tutorialstorage
桶所需的信息。
第 8 步:在这一步中,我们定义 Google Deployment Manager,它将创建 VM 实例和安装 Tomcat 8 的环境,并部署jpetstore.war
文件来引导应用进程。在同一个构建部分下,单击 Add Build Step 并选择 Execute Shell,如前所示。执行如下命令,如图 5-94 所示。
图 5-94
部署脚本
gsutil acl ch -u AllUsers:R gs://tutorialstorage/jpetstore.war
/bin/sleep 10
cd /home/learngcptutorial/dmscript && gcloud deployment-manager deployments create myfirstdeployment --config=createVMConfig.yaml
gsutil
命令(gsutil acl ch -u AllUsers:R gs://tutorialstorage/jpetstore.war
)将向所有用户提供读取级别的权限,以便部署管理器可以从tutorialstorage
桶下载jpertstore.war
文件,并将其部署到 Tomcat 8 上。
这个更改目录命令(cd /home/learngcptutorial/dmscript && gcloud deployment-manager deployments create myfirstdeployment --config=createVMConfig.yaml
)将遍历到dmscript
目录,其中包含我们从 GitHub 克隆的部署管理器相关文件。最后,我们执行部署管理器命令来创建基础设施和应用部署。这个部署叫做myfirstdeployment
。
**部署管理器用来构建基础设施的脚本如下。这与我们在第二章中介绍的创建 Google 云计算引擎实例的 YAML 脚本相同。在此用例的上下文中,YAML 文件更新如下:
图 5-97
部署脚本
-
We added a startup script section in the file.
Startup-script
is required to perform some tasks after the creation of the GCP VM, like installing Tomcat 8 and copying the deployable artifactjpetstore.war
” in Tomcat’s/webapps
directory to deploy the application. The code snippet added to the YAML file is shown in Figure 5-95.图 5-95
部署脚本
-
We need to add configuration for the Google
ServiceAccount
that is required on the instance that’s created using Deployment Manager. It performs the application installation and setup activities. In the code, the GoogleServiceAccount
is included and the required roles are provided for the activity. The code snippet added to the YAML file is shown in Figure 5-96.图 5-96
部署脚本
-
我们需要添加一个网络防火墙规则,以便提供对端口
8080
的访问,这是从互联网访问应用所必需的。添加到 YAML 文件中的代码片段如图 5-97 所示。
图 5-98 显示了部署管理器用来构建环境、安装所需软件和部署应用的完整 YAML 代码。
图 5-98
完成部署脚本
步骤 9:现在已经创建了管道任务,在这一步中,我们将执行它。导航到 Jenkins tutorialProject
主页,点击菜单中的立即构建选项,如图 5-99 所示。
图 5-99
Jenkins 管理屏幕
构建的成功执行出现在项目的控制台输出中,如图 5-100 和 5-101 所示。
图 5-101
Jenkins 控制台输出
图 5-100
Jenkins 控制台输出
您可以使用以下步骤来验证管道任务的成功执行:
图 5-102
Google 控制台虚拟机实例
- 导航到 GCP 控制台,验证 Google 计算引擎虚拟机已成功创建。参见图 5-102 ,显示
createfirstvm
已创建。
图 5-103
Tomcat 部署成功
- 您可以通过使用
http://<GCP VM Public IP>:8080
打开 web URL(用您实际的实例公共 IP 替换GCP VM public IP
)来确保 Tomcat 8 server 安装成功。输出信息参考参见图 5-103 。
图 5-104
JPetStore 应用已成功部署
- 您还可以通过打开
http://<GCP VM Public IP>:8080/jpetstore/actions/Catalog.action
URL(用您实际的实例公共 IP 替换GCP VM public IP
)来验证JPetStore
应用是否成功部署在 Tomcat 服务器上。您可以在图 5-104 中看到输出。
摘要
在本章中,我们详细介绍了 Jenkins 的主要概念,并解释了如何使用 Jenkins 和 Google Cloud-native 服务定义管道。至此,我们到达了本书的结尾,在这里我们讨论了自动化、持续集成和持续部署领域中 Google Cloud 领域中最常用的工具和技术。**