【实践】持续集成和部署方面的 3 个最佳实践
本文介绍了三大主题:自动化持续集成 / 持续部署 (CI/CD) 配置、使用 Git 代码仓库用于常见的 CI/CD 工件以及参数化 Jenkins 管道。
术语介绍
先不妨定义几个术语。CI/CD 是一种让团队可以快速自动测试、打包和部署应用程序的实践。它常常通过利用名为 Jenkins 的服务器来实现,该服务器充当 CI/CD 编排器。Jenkins 侦听特定的输入 (常常是代码签入后的 Git 钩子),被触发后启动管道。
管道由开发团队及 / 或运维团队编写的代码组成,这些代码指示 Jenkins 在 CI/CD 过程中执行哪些操作。这个管道常常类似于“构建我的代码,然后测试代码,如果那些测试通过,将我的应用程序部署到下一个最高环境 (通常是开发、测试或生产环境)。”企业常常有更复杂的管道,结合工件仓库和代码分析器之类的工具,但这提供了大体例子。
我们已搞明白了关键术语,不妨深入了解几个最佳实践。
- 自动化是关键
想在 PaaS 上运行 CI/CD,需要在集群上配置适当的基础设施。在这个例子中,我将使用 OpenShift。
很容易实现“Hello, World”。只要运行 oc new-app jenkins- 就行了,你有了一台运行中的 Jenkins 服务器,随时可以上路。然而在企业中使用复杂得多。除了 Jenkins 服务器外,管理员还常常需要部署代码分析工具 (比如 SonarQube) 和工件仓库(比如 Nexus)。然后,他们要创建管道以执行 CI/CD,并创建 Jenkins 从节点以减轻主节点的负载。大多数这些实体受到 OpenShift 资源的支持,需要创建这些资源才能部署所需的 CI/CD 基础设施。
最终,可能需要复制部署 CI/CD 组件所需的手动步骤,你可能不是执行那些步骤的人。为了确保生成结果时快速、无错误、并与以前一模一样,应该在创建基础设施的方式中包含自动化方法。这可以是 Ansible playbook、Bash 脚本或者希望自动部署 CI/CD 基础设施的任何其他方式。
我使用 Ansible 和 OpenShift-Applier 角色来自动化我的实现。你可能觉得这些工具很有价值,也可能觉得别的工具更适合你和贵企业。无论怎样,你会发现自动化大大减少了重新创建 CI/ CD 组件所需的工作量。
配置 Jenkins 主节点
除了一般的“自动化”外,我想单单挑出 Jenkins 主节点,谈谈管理员可以利用 OpenShift 自动化 Jenkins 配置的几种方法。来自 Red Hat Container Catalog 中的 Jenkins 映像随附安装了 OpenShift-Sync 插件 (https://github.com/openshift/jenkins-sync-plugin)。
想创建 Jenkins 管道,要创建类似这样的 OpenShift BuildConfig:
apiVersion: v1
kind: BuildConfig
…
spec:
source:
git:
ref: master
uri:
…
strategy:
jenkinsPipelineStrategy:
jenkinsfilePath: Jenkinsfile
type: JenkinsPipeline
OpenShift-Sync 插件会注意到,拥有策略 jenkinsPipelineStrategy 的 BuildConfig 已创建,可将它转换成 Jenkins 管道,从 Git 源代码指定的 Jenkinsfile 来获取。还可以使用内联式 Jenkinsfile,而不是从 Git 代码仓库来获取一个。欲知详情,请参阅说明文档。
想创建 Jenkins 从节点,创建以下列定义开始的 OpenShift ImageStream:
apiVersion: v1
kind: ImageStream
metadata:
annotations:
slave-label: jenkins-slave
labels:
role: jenkins-slave
…
请注意这个 ImageStream 中定义的元数据。OpenShift-Sync 插件会将标签是 role: jenkins-slave 的任何 ImageStream 转换成 Jenkins 从节点。Jenkins 从节点将以来自 slave-label 标注的值命名。
ImageStreams 非常适合简单的 Jenkins 从节点配置,但是一些团队发现有必要配置一些基本细节,比如资源限制、就绪和活性探针以及实例上限。这时 ConfigMaps 可以派上用场:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
role: jenkins-slave
…
data:
template1: |-
注意仍需要 role: jenkins-slave 标签将 ConfigMap 转换成 Jenkins 从节点。Kubernetes pod 模块包括一段很长的 XML,可根据贵企业的喜好来配置每个细节。想查看该 XML 以及将 ImageStreams 和 ConfigMaps 转换成 Jenkins 从节点方面的更多信息,请参阅说明文档。
从上面三个例子中可以看出,没有一项操作要求管理员手动更改 Jenkins 控制台。通过使用 OpenShift 资源,Jenkins 能以一种轻松自动化的方式来配置。
- 共享就是关爱
第二个最佳实践是维护常见 CI/CD 工件的 Git 仓库。主要想法是,防止团队重新发明轮子。设想你的团队需要执行蓝 / 绿部署到 OpenShift 环境的工作,作为管道的 CD 阶段的一部分。团队中负责编写管道的成员可能不是 OpenShift 专家,他们也没能力从头开始编写这种功能。幸好,有人已经编写了一个将该功能整合到常见 CI/CD 仓库中的函数,因此你的团队可以使用该函数,而不是花时间编写一个。
在此基础上更进一步,贵企业可能决定要维护整条管道。你可能发现,团队在编写功能相似的管道。那些团队使用一条来自共同仓库的参数化管道而不是各自从头开始编写会来得更高效。
- 少就是多
如上所述,第三条最佳实践是参数化 CI/CD 管道。参数化可防止管道泛滥,使你的 CI/CD 系统更容易维护。设想我有多个地区来部署应用程序。要是没有参数化,每个地区都需要一条不同的管道。
想参数化编写成 OpenShift 构建配置的管道,将 env 这节添加到配置中:
…
spec:
…
strategy:
jenkinsPipelineStrategy:
env:
- name: REGION
value: US-West
jenkinsfilePath: Jenkinsfile
type: JenkinsPipeline
有了这个配置,我可以将 REGION 这个参数传递给管道,以便将应用程序部署到指定的地区。
一些企业可能决定将 CI/CD 管道分成独立的 CI 管道和 CD 管道,通常是由于在部署之前要有某个审批环节。设想我有四个映像和三个不同的环境要部署。要是没有参数化,我需要 12 条 CD 管道以支持所有的部署方案。这很快就会失控。为了让 CD 管道的维护更容易,企业会发现参数化映像和环境、好让一条管道执行多条管道的工作来得更明智。
结束语
企业层面的 CI/CD 往往比许多企业预料的来得复杂。幸好有了 Jenkins,有好多方法可以无缝提供自动化机制。维护常见 CI/CD 工件的 Git 仓库也会简化工作,因为团队可以从维护的依赖项来获取,而不是从头开始自行编写。最后,参数化 CI/CD 管道将减少需要维护的管道的数量。