谷歌云自动化高级教程(二)
四、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 astringtype, 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 等。如果是管道类的,永远都是Pipelineonly。 -
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 buildshould be run before the unit testing happens. There is no output linking required between these tasks, so theunittesting-java-apptask usesrunAfterto indicate thatbuild-java-appmust 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
resourceReffield, as shown in the example in Figure 4-20.图 4-20
pipeline 运行管道片段
-
Embed the
PipelineResourcedefinition in the PipelineRun using theresourceSpecfield, 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-scriptis 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/webappsdirectory 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
ServiceAccountthat is required on the instance that’s created using Deployment Manager. It performs the application installation and setup activities. In the code, the GoogleServiceAccountis 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.actionURL(用您实际的实例公共 IP 替换GCP VM public IP)来验证JPetStore应用是否成功部署在 Tomcat 服务器上。您可以在图 5-104 中看到输出。
摘要
在本章中,我们详细介绍了 Jenkins 的主要概念,并解释了如何使用 Jenkins 和 Google Cloud-native 服务定义管道。至此,我们到达了本书的结尾,在这里我们讨论了自动化、持续集成和持续部署领域中 Google Cloud 领域中最常用的工具和技术。**