2.4 持续部署工具对比

本节将介绍目前工程实践上常用的持续部署工具,包括本书的主角——由Netflix开源的Spinnaker,以及由Google开源的Tekton、由Intuit开源的Argo CD。

Spinnaker和Tekton目前是持续交付基金会(CDF)的成员,其他成员还包括Jenkins、Jenkins X项目。Argo由CNCF托管,是CNCF目前在CI/CD领域的唯一项目。

2.4.1 Tekton

Tekton是专注于Kubernetes集群的CI/CD工具,它是本节所介绍工具中“最年轻”的项目。Tekton起源于Knative Build组件。

使用Tekton之前,需要在集群内安装它,安装完成后,Tekton会通过Kubernetes CRD(Custom Resources)的方式扩展负载类型,并实现用自定义控制器来完成对CRD的逻辑处理。

Tekton扩展的CRD如下。

• Task:描述任务的模板,用于描述单个任务的执行过程,可以有多个有序的步骤(Step),可包含变量定义。

• TaskRun:用于描述运行Task,实例化Task并支持传递参数。

• Pipeline:TaskRun一次只能运行一个Task,当需要运行多个Task时,就要使用Pipeline对Task进行编排。

• PipelineRun:和Task一样,PipelineRun是用于实例化Pipeline,用于启动Pipeline,并指出传递参数。

• PipelineResource:资源定义,例如Git仓库信息、Docker仓库信息等,这些资源可以在不同的Task之间共享。

Tekton Task和Pipeline的调度关系如图2-3所示。

对于Tekton Task和Pipeline的关系和实现,例如Task A内不同的Step由同一个Pod内不同的Container实现流水线逻辑,每个Step之间是有序的。在Tekton中实现有序,是由每个步骤监听上一个步骤执行完成后,生成用于标识索引的文件(tekton/tools/$index)来控制顺序的。不同的Task之间由不同的Pod负责运行,Task之间的依赖关系和启动顺序由Tekton Controller通过生成有向无环图(DAG)来进行调谐(Reconcile)。

通过编写声明式Manifest文件实现Tekton的自定义资源,并提交至Kubernetes集群,这样便能够启动Tekton流水线。

图2-3 Tekton Task和Pipeline的调度关系

以下是一个最简单的Task例子,将以下内容保存为task.yaml。

定义了Task后,需要再定义TaskRun才能够运行它,将以下内容保存为task_run.yaml。

首先在命令行运行kubectl apply -f task.yaml提交Task,再运行kubectl apply -f task_run.yaml提交TaskRun运行echo-hello-world Task。

使用Pipeline能够对Task进行编排,将以下内容保存为pipeline.yaml。

还要使用PipelineRun来运行Pipeline,将以下内容保存为pipeline_run.yaml。

首先在命令行运行kubectl apply -f pipeline.yaml提交Pipeline,再运行kubectl apply -f pipeline_run.yaml提交PipelineRun运行Pipeline。

PipelineResource可以将公用的信息进行存储和复用,例如定义Git仓库为PipelineResource的代码如下。

提交到Kubernetes集群后,在PipelineRun内便能够利用引用的方式。

由于Tekton不同,Task都在单独的Pod内运行,可以通过kubectl apply get pod -n tekton-pipelines获取运行Task Pod的状态。此外,还可以通过kubectl logs $pod_name -n tekton-pipelines查看对应Pod输出的Log来查看流水线的日志信息。

Tekton通过在Kubernetes集群运行,并监听自定义资源的提交及外部资源的变化来实现CI/CD流水线,对运行在Kubernetes环境下的应用的CI/CD相对友好,同时内置最佳实践案例能够快速创建持续部署流水线。

对于容器化的应用及完全使用Kubernetes作为运行环境的团队来说,Tekton是一个很好的选择,且当组织采用各团队“自己吃自己的狗粮”的管理方式时,Tekton能够为其提供强大的灵活性;对于那些同时使用虚拟机和多个Kubernetes集群的大型团队来说,Tekton无法为他们提供一个中心化的控制和管理中心。

Tekton提供的流水线编排能力相对较弱,在做技术选型时需要额外注意这一点。

2.4.2 Argo CD

在介绍Argo CD之前,首先来了解Argo CD背后的核心理念——GitOps。

GitOps是一种为应用程序实施持续部署的方法。它着重于开发人员的体验,通过使用开发人员已经熟悉的工具(例如Git和CI工具)对基础架构进行操作和变更。

GitOps的核心思想是拥有一个Git仓库,该仓库始终包含生产环境所需的基础架构的声明式描述文件,结合自动化工具,如果要部署或变更当前的应用程序,只需要像提交代码一样更新描述文件即可自动完成变更。

在GitOps的理念中,不同环节的自动化串联可以使用Webhook或Trigger来实现。Webhook一般是通过HTTP请求的方式来触发下一个自动化阶段;Trigger的概念则更加广泛,既可以是由上一阶段主动触发的Webhook及消息通知或GRPC触发的方式,还可以是由下一阶段通过主动拉取检查变化实现触发,其工作流程如图2-4所示。

图2-4 GitOps工作流程

图2-4是一个典型的GitOps工作流程,开发者在更新应用时会首先更新应用代码,持续集成流程在收到触发后启动构建流程,并将构建物推送到镜像仓库。如果本次提交涉及对线上环境的修改,那么还会触发持续部署流程对线上基础架构进行变更,例如更新环境变量或更新镜像等。需要注意的是,触发持续部署的流程可能通过Webhook触发,也可能是持续部署工具通过定期主动拉取的方式检查是否有差异,进而触发流程。

Argo CD遵循GitOps的思想模式,使用Git仓库作为定义应用状态的来源,并可在Git仓库发生变化时自动同步和部署应用程序。Argo CD的实现要依靠Kubernetes控制器,该控制器会监视正在运行的应用,以及比较当前状态和Git仓库的指定清单文件,一旦文件发生修改,就会自动触发流水线。这意味着对Git仓库的任何修改都可以自动应用到对应的环境中。

Argo CD的核心概念如下。

• Application:定义Kubernetes资源清单,这是Argo CD的一个自定义资源定义(CRD),存储在Kubernetes集群中。

• Application source type:使用哪个工具来构建应用。

• Target state:应用的期望状态,由Git仓库存储的文件表示。

• Live state:应用程序实时的状态,例如部署了哪些Pod。

• Sync status:应用的期望状态和实时状态是否同步。

• ync:使应用状态迁移至期望状态的过程,一般是部署行为。

• Refresh:将Git中最新的代码与实时状态进行对比,并找出不同点。

• Health:应用程序的运行状态是否正常运行。

• Tool:从文件目录创建清单的工具,例如Kustomize或Ksonnet。

下面通过简单的示例来详细介绍上述概念。

准备一个Kubernetes集群,并执行以下命令安装Argo CD。

使用kubectl port-forward进行端口转发。

打开浏览器访问localhost:8080,进入Argo CD登录页,如图2-5所示。

图2-5 Argo CD登录页

输入账号admin,密码为完整的argo-server Pod名称(运行kubectl get pods -n argocd | grep argocd-server即可获得)。进入首页后,单击左上角的“NEW APP”创建应用,如图2-6所示。

图2-6 Argo CD创建应用

以部署实例应用guestbook为例,在对应的表单分别选择或填写以下内容。

• Application Name:guestbook。

• Project:default。

• SYNC OPTIONS:USE A SCHEMA TO VALIDATE RESOURCE MANIFESTS。

• Repository URL。[1]

• Revision:HEAD。

• Path:guestbook。

• Cluster URL。[2]

• Namespace:default。

填写完成后,单击上方的“CREATE”完成创建,并展示guestbook应用的状态,如图2-7所示。

图2-7 Argo CD应用状态

注意,完成创建后,Argo CD并不会立刻进行自动部署,而是需要手动进行触发。查看应用状态当前为OutOfSync(未同步),意味着集群已部署的应用和Git仓库存储的应用状态不同步,手动单击“SYNC”即可完成应用部署。

同步完成后,将显示应用具体的状态,例如Healthy、Synced、Sync OK,这意味着当前应用状态和Git仓库存储的期望状态一致,并展示工作负载的类型和拓扑图,如图2-8所示。

图2-8 Argo CD应用拓扑图

完成以上步骤即实现了将Git仓库存储的Kubernetes(Manifest)部署到目标集群中,当Git仓库被修改后,应用状态将重新变更为OutOfSync,重复SYNC同步动作即可同步应用。

当然,Argo CD还提供了Webhook,用于非常方便地实现自动触发,无须人工操作,当Git仓库被修改后,会自动触发同步动作。

Argo CD通过实现GitOps的工作流,进而实现了应用状态的自动监控和自动部署。Argo CD支持多集群,主要针对Kubernetes集群的部署场景,同时弱化了流水线的理念,对较复杂的部署场景的支持较弱(如蓝绿发布和金丝雀发布),也不支持传统虚拟机的部署。