微信公众号:运维开发故事,作者:乔克

在《Tekton系列之实践篇-我的第一条Pipeline》中我们已经实现了第一条流水线,但是这条流水线还是比较简单,完成了基础的功能。这篇文章带你怎么根据Jenkins的Jenkinsfile来定制自己的Tekton Pipeline。

首先我们来看看Jenkinsfile中是什么样子,如下:

// 引入方法
def dingmes = new org.devops.sendDingTalk()
def BUILD_USER
def IS_IMAGE_PUSHpipeline {agent {kubernetes {label "jenkins-slave-${UUID.randomUUID().toString()}"yaml """
apiVersion: v1
kind: Pod
spec:nodeSelector:kubernetes.io/hostname: node-2containers:- name: gradleimage: registry.cn-hangzhou.aliyuncs.com/coolops/builder-gradle:v2command: ['cat']tty: truevolumeMounts:- name: cachesmountPath: /root/.gradle/caches/- name: indockermountPath: /var/run/docker.sock- name: helmimage: registry.cn-hangzhou.aliyuncs.com/coolops/helm3:3.2.4 command: ['cat']tty: true       - name: sonarimage: registry.cn-hangzhou.aliyuncs.com/coolops/gradle:5.6.4-jdk11command: ['cat']tty: truevolumeMounts:- name: sonarcachemountPath: /root/.gradle/caches/volumes:- name: cacheshostPath:path: "/data/jenkins-job/${JOB_NAME}/gradle/"- name: indockerhostPath:path: "/var/run/docker.sock"- name: sonarcachehostPath:path: "/data/jenkins-job/${JOB_NAME}/sonar/"
"""}}environment {APP_NAME = "${params.APP_NAME}"DOCKER_CREDENTIAL_ID = 'dockerhub-token'GIT_CREDENTIAL_ID = 'git-token'SONAR_CREDENTIAL_ID = 'sonar-token'KUBECONFIG_CREDENTIAL_ID = 'kubeconfig-token'REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'DOCKERHUB_NAMESPACE = 'coolops'CHART = 'coolops/rd'CHART_USERNAME=xxxCHART_PASSWORD=xxxIMG_REPO = "$REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME"IMG_TAG = "$GIT_COMMIT"COMMON_ARGS = "--set image.repository=$IMG_REPO \--set image.tag=$IMG_TAG \--set ingress.hosts[0].paths[0]=/ "}parameters {choice(description: '通过 Gradle --refresh-dependencies 参数进行 Jar 包强制刷新',  name: 'refresh', choices: ['false', 'true'])}options {timeout(time: 30, unit: 'MINUTES') }stages {stage('Checkout SCM') {steps {checkout(scm)}}stage('Build & Push') {steps {container('gradle') {withCredentials([usernamePassword(credentialsId: "$DOCKER_CREDENTIAL_ID", passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME')]) {sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'sh '''export EXIST_IMG=$(docker pull $IMG_REPO:$IMG_TAG &>/dev/null && echo true || echo false)echo $EXIST_IMGif [ $refresh == "true" -o $EXIST_IMG == "false" ]thenecho "开始编译并推送镜像" ;$refresh && gradle clean bootJar --configure-on-demand --build-cache --refresh-dependencies || gradle clean bootJar --configure-on-demand --build-cache            docker build -f Dockerfile -t $IMG_REPO:$IMG_TAG . ;docker push $IMG_REPO:$IMG_TAG ;elseecho "镜像已存在,跳过编译";fi'''}}}}stage('helm3 add repo') {steps {container('helm') {withCredentials([kubeconfigContent(credentialsId : 'kubeconfig-token' ,variable : 'kubconfig' ,)]) {sh '''set +xmkdir ~/.kube/echo "$kubconfig" > ~/.kube/config'''sh 'helm repo add coolops https://repomanage.rdc.aliyun.com/helm_repositories/66465-coolops --username=${CHART_USERNAME} --password=${CHART_PASSWORD}'}    }}} }stage('Deploy To Dev') {environment {NAMESPACE = 'coolops-dev'ENV = 'dev'}when {expression {return "$BRANCH_NAME".contains('dev')}}steps {container('helm') {script {stepsHelm()}               }}}stage('Deploy To test') {environment {NAMESPACE = 'coolops-test'ENV = 'test'}when {expression {return "$BRANCH_NAME".contains('test')}}steps {container('helm') {script {stepsHelm()}               }}}stage('Deploy To Uat') {environment {NAMESPACE = 'coolops-uat'ENV = 'uat'}when {expression {return "$BRANCH_NAME".contains('uat')}}steps {container('helm') {                                   script {stepsHelm()}               }}}stage('Deploy To Pre') {environment {NAMESPACE = 'coolops-pre'ENV = 'pre'}when {expression {return "$BRANCH_NAME".contains('pre')}}steps {container('helm') {                                   script {stepsHelm()}               }}}stage('Deploy To Prod') {environment {NAMESPACE = 'coolops-prod'ENV = 'prod'}when {expression {return "$BRANCH_NAME".contains('prod')}}steps {container('helm') {                                   script {stepsHelm()}               }}}// 扫描stage('Sonarqube Scanner') {   when {expression {return "$JOB_NAME".contains('skip')}}    steps {timeout(time:20,unit:'MINUTES'){catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {container('sonar') {sh 'gradle sonarqube \-x test\-Dsonar.host.url=http://sonar.coolops.cn \-Dsonar.login=c17650fa820d985daf1f29d8a3f685d789e47e45'}}}}}}}

整体的Jenkinsfile我做了一些删减,但是整个流程是没变的,咋一看是不是同样很简单?我将步骤整理如下:

  • 从代码仓库拉取代码

  • 编译代码并推送到仓库

  • 根据不同的分支推送到不同的环境

  • 代码扫描

整体的流程和上一篇文章没太大不同,区别在于:

  • 多分支流水线发布

  • 由kubectl改成了helm chart

  • 新增了代码扫描

这里采用Helm Chart来部署应用,我使用的是阿里云的Chart仓库。不会使用的朋友可以通过阿里云–>云效DevOps–>研发–>私有仓库进行申请。

我们现在先创建Task,然后再组装Pipeline。

使用Helm Chart发布应用Task

我们在之前的文章中使用的是kubectl来发布应用,由于在我实际的使用过程中,是使用的Helm来管理的,为了保持一致,这里先创建一个Helm发布应用的Task。

在创建之前,我们先来看看有哪些地方是需要参数的:

  • namespace:由于我是不同环境不同的namespace,所以在多分支发布的时候需要指定namespace。

  • app_name:应用名,

  • chart_name:helm chart 名

  • args:helm chart 的其他参数

所以我们定义的Task如下:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:name: helm-to-k8s
spec:workspaces:- name: source- name: kubernetesconfigmountPath: /root/.kubeparams:- name: IMAGE- name: TAG- name: NAMESPACE- name: BRANCH_NAME- name: CHART_NAME- name: CHART_USERNAME- name: CHART_PASSWORD- name: APP_NAMEsteps:- name: run-helmimage: registry.cn-hangzhou.aliyuncs.com/coolops/helm3:3.2.4workingDir: $(workspaces.source.path)script: |helm repo add coolops https://repomanage.rdc.aliyun.com/helm_repositories/66465-coolops --username=$(params.CHART_USERNAME) --password=$(params.CHART_PASSWORD)common_args="--set image.repository=$(params.IMAGE) --set image.tag=$(params.TAG) --set ingress.hosts[0].paths[0]=/"helm  -n $(params.NAMESPACE) upgrade $(params.APP_NAME) $(params.CHART_NAME) ${common_args} || \helm  -n $(params.NAMESPACE) install $(params.APP_NAME) $(params.CHART_NAME) ${common_args} 

代码扫描Task

由于在Jenkins中使用了代码扫描,所以这里加一个代码扫描的Task,如下:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:name: sonar-scanner
spec:workspaces:- name: sourceparams:- name: SONAR_USERNAME- name: SONAR_PASSWORD- name: SONAR_URL- name: APP_NAMEsteps:- name: sonar-scannerimage: registry.cn-hangzhou.aliyuncs.com/coolops/sonar-scanner:2.2.0workingDir: $(workspaces.source.path)script: |scanTime=`date +%F-%H-%M-%S`sonar-scanner -Dsonar.host.url=$(params.SONAR_URL) \-Dsonar.projectKey=$(params.APP_NAME)  \-Dsonar.projectName=$(params.APP_NAME)  \-Dsonar.projectVersion=${scanTime} \-Dsonar.login=$(params.SONAR_USERNAME) \-Dsonar.password=$(params.SONAR_PASSWORD) \-Dsonar.projectDescription="$(workspaces.source.path)"

需要新增的Task就这两个,接下来就是组装Pipeline了,多分支发布也是在Pipeline中组装。

整合Pipeline

在整合Pipeline之前,还是先来梳理一下流程:

  • 拉代码

  • 编译构建、推送镜像

  • 发布应用----多环境

  • 代码扫描

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: rd-pipeline
spec:workspaces: # 声明 workspaces- name: rd-repo-pvc- name: docker-config- name: kubernetes-configparams:# 定义代码仓库- name: git_url- name: revisiontype: stringdefault: "master"- name: gitInitImagetype: stringdefault: "registry.cn-hangzhou.aliyuncs.com/coolops/tekton-git-init:v0.29"# 定义镜像参数- name: pathToDockerfiledescription: The path to the build context, used by Kaniko - within the workspacedefault: .- name: imageUrldescription: Url of image repository- name: imageTagdescription: Tag to apply to the built imagedefault: latest- name: chart_nametype: stringdefault: coolops/coolops-rd- name: chart_usernametype: string- name: chart_passwordtype: string- name: app_nametype: string- name: namespacetype: stringdefault: default# 定义代码扫描- name: sonar_usernametype: stringdefault: admin- name: sonar_passwordtype: stringdefault: admin- name: sonar_urltype: stringtasks: # 添加task到流水线中- name: clonetaskRef:name: git-cloneworkspaces:- name: outputworkspace: rd-repo-pvcparams:- name: urlvalue: $(params.git_url)- name: revisionvalue: $(params.revision)- name: gitInitImagevalue: $(params.gitInitImage)- name: unit-testworkspaces: # 传递 workspaces- name: sourceworkspace: rd-repo-pvctaskRef:name: unit-testrunAfter:- clone- name: build-push-imageparams:- name: pathToDockerfilevalue: $(params.pathToDockerfile)- name: imageUrlvalue: $(params.imageUrl)- name: imageTagvalue: $(tasks.clone.results.commit)taskRef:name: build-push-imagerunAfter:- unit-testworkspaces: # 传递 workspaces- name: sourceworkspace: rd-repo-pvc- name: dockerconfigworkspace: docker-config- name: deploy-to-devwhen:- input: $(params.revision)operator: invalues:- devtaskRef:name: helm-to-k8sparams:- name: IMAGEvalue: $(params.imageUrl)- name: TAGvalue: $(tasks.clone.results.commit)- name: BRANCH_NAMEvalue: $(params.revision)- name: CHART_NAMEvalue: $(params.chart_name)- name: CHART_USERNAMEvalue: $(params.chart_username)- name: CHART_PASSWORDvalue: $(params.chart_password)- name: APP_NAMEvalue: $(params.app_name)- name: NAMESPACEvalue: coolops-devworkspaces:- name: sourceworkspace: rd-repo-pvc- name: kubernetesconfigworkspace: kubernetes-configrunAfter:- build-push-image- name: deploy-to-testwhen:- input: $(params.revision)operator: invalues:- testtaskRef:name: helm-to-k8sparams:- name: IMAGEvalue: $(params.imageUrl)- name: TAGvalue: $(tasks.clone.results.commit)- name: BRANCH_NAMEvalue: $(params.revision)- name: CHART_NAMEvalue: $(params.chart_name)- name: CHART_USERNAMEvalue: $(params.chart_username)- name: CHART_PASSWORDvalue: $(params.chart_password)- name: APP_NAMEvalue: $(params.app_name)- name: NAMESPACEvalue: coolops-testworkspaces:- name: sourceworkspace: rd-repo-pvc- name: kubernetesconfigworkspace: kubernetes-configrunAfter:- build-push-image- name: deploy-to-prewhen:- input: $(params.revision)operator: invalues:- pretaskRef:name: helm-to-k8sparams:- name: IMAGEvalue: $(params.imageUrl)- name: TAGvalue: $(tasks.clone.results.commit)- name: BRANCH_NAMEvalue: $(params.revision)- name: CHART_NAMEvalue: $(params.chart_name)- name: CHART_USERNAMEvalue: $(params.chart_username)- name: CHART_PASSWORDvalue: $(params.chart_password)- name: APP_NAMEvalue: $(params.app_name)- name: NAMESPACEvalue: coolops-preworkspaces:- name: sourceworkspace: rd-repo-pvc- name: kubernetesconfigworkspace: kubernetes-configrunAfter:- build-push-image- name: deploy-to-prodwhen:- input: $(params.revision)operator: invalues:- prodtaskRef:name: helm-to-k8sparams:- name: IMAGEvalue: $(params.imageUrl)- name: TAGvalue: $(tasks.clone.results.commit)- name: BRANCH_NAMEvalue: $(params.revision)- name: CHART_NAMEvalue: $(params.chart_name)- name: CHART_USERNAMEvalue: $(params.chart_username)- name: CHART_PASSWORDvalue: $(params.chart_password)- name: APP_NAMEvalue: $(params.app_name)- name: NAMESPACEvalue: coolops-prodworkspaces:- name: sourceworkspace: rd-repo-pvc- name: kubernetesconfigworkspace: kubernetes-configrunAfter:- build-push-image- name: sonar-scannerwhen:- input: $(params.revision)operator: invalues:- testtaskRef:name: sonar-scannerrunAfter:- cloneparams:- name: SONAR_USERNAMEvalue: $(params.sonar_username)- name: SONAR_PASSWORDvalue: $(params.sonar_password)- name: SONAR_URLvalue: $(params.sonar_url)- name: APP_NAMEvalue: $(params.app_name)workspaces:- name: sourceworkspace: rd-repo-pvc

编排一个PipelineRun运行一下,如下:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:name: test-hello-world-pipeline-run
spec:pipelineRef:name: rd-pipelineparams:- name: revisionvalue: test- name: git_urlvalue: https://gitee.com/coolops/devops-hello-world.git    - name: imageUrlvalue: registry.cn-hangzhou.aliyuncs.com/coolops/devops-hello-world- name: imageTagvalue: latest- name: pathToDockerfilevalue: Dockerfile- name: chart_usernamevalue: username- name: chart_passwordvalue: password- name: app_namevalue: hello-world- name: sonar_usernamevalue: username- name: sonar_passwordvalue: password- name: sonar_urlvalue: http://sonarqube.coolops.cnworkspaces:- name: rd-repo-pvcvolumeClaimTemplate:spec:accessModes:- ReadWriteOncestorageClassName: openebs-hostpathresources:requests:storage: 1Gi- name: docker-configsecret:secretName: docker-config- name: kubernetes-configsecret:secretName: kubernetes-configserviceAccountName: tekton-build-sa

运行效果如下:

上面只是把应用部署到同一个集群得不同namespace下,在实际情况下可能有多个集群,我们只需要指定不同的kubernetes-config即可,当然, 需保证Tekton所在的集群能与其他集群相通。

sonar上的扫描结果如下:

总结

从Jenkins迁移到Tekton,主要就是Pipeline的改写,但是从整体来看并不复杂,因为Jenkins中的过程都是定义好的,我们只需要按它的步骤改造成Tekton适配的语法即可。

最后,求关注。如果你还想看更多优质原创文章,欢迎关注我们的公众号「运维开发故事」。

如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

你还可以把我的公众号设为「星标」,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。


我是 乔克,《运维开发故事》公众号团队中的一员,一线运维农民工,云原生实践者,这里不仅有硬核的技术干货,还有我们对技术的思考和感悟,欢迎关注我们的公众号,期待和你一起成长!

Tekton系列之实践篇-由Jenkins改成Tekton相关推荐

  1. Tekton系列之实践篇-如何用Jenkins来管理Tekton

    微信公众号:运维开发故事,作者:乔克 在<Tekton系列之实践篇-由Jenkins改成Tekton>中,我们可以将Jenkinsfile改成Tekton Pipeline,但是Tekto ...

  2. Tekton系列之实践篇-使用Tekton Trigger让Tekton使用更简单

    微信公众号:运维开发故事,作者:乔克 在<Tekton实践篇-如何用Jenkins来管理Tekton>我们介绍了如何使用Jenkins来管理Tekton,这种方式是运维主动式管理,也就是需 ...

  3. Tekton系列之实践篇-我的第一条Pipeline

    作者 | 乔克 博客 | https://www.coolops.cn 公众号 | 运维开发故事((ID:mygsdcsf)) 前面已经完成了Tekton的安装和理论知识的介绍,如果你认真的看完了文章 ...

  4. 三菱A系列程序改成Q系列程序,实例说明 包含原程序与改后的程序,方便对照

    三菱A系列程序改成Q系列程序,实例说明 包含原程序与改后的程序,方便对照 程序里包含模数和数模转换模块,通信模块的应用 控制上包含模拟量控制和简单的PID控制,顺序结构 现工厂PLC升级换代,尤其是A ...

  5. Jenkins由英文界面改成中文界面

    今天安装了个Jenkins,但发现是英文界面,对于我这英文大部分还给老师的人来说,不太友好,为了方便操作,我将界面改成了中文版,这里记录下操作内容 界面本来是上图这样的,那我们要将英文版改成中文版怎么 ...

  6. 一点就分享系列(实践篇3-中篇)— 虽迟但到!全网首发?yolov5之“baseline修改小结“+“CV领域展开-Involutiontransformercnn”

    一点就分享系列(实践篇3-中篇)- yolov5之"修改总结以及baseline算子的分享" 说明 上篇有很多朋友照搬了我的yaml结构,这里抱歉下也有原因是我的工作偏工程,真的研 ...

  7. 一点就分享系列(实践篇3-上篇)— 修改YOLOV5 之”魔刀小试“+ Trick心得分享+V5精髓部分源码解读

    一点就分享系列(实践篇3-上篇)-修改YOLOV5 魔刀小试+ Trick心得分享 DL部署大热,而我觉得回归原理和源码更加重要!正如去年,我也提倡部署工程化,眼争上班工作我这里也是以搬砖产出为主.但 ...

  8. 一点就分享系列(实践篇6——上篇)【迟到补发_详解yolov8】Yolo-high_level系列融入YOLOv8 旨在研究和兼容使用【3月份开始持续补更】

    一点就分享系列(实践篇5-补更篇)[迟到补发]-Yolo系列算法开源项目融入V8旨在研究和兼容使用[持续更新] 题外话 [最近一直在研究开放多模态泛化模型的应用事情,所以这部分内容会更新慢一些,文章和 ...

  9. 六、Git多人开发: 把同一文件改成了不同的文件名如何处理?

    @Author:Runsen 把同一文件改成了不同的文件名如何处理? 我们接着上面的话题,如果把同一文件改成了不同的文件名,如何处理? 小A和小B首先对使用git pull命令同步下.小Auser.h ...

最新文章

  1. 查看LINUX发行版的名称及其版本号
  2. 19 java程序员面试宝典视频课程之正则表达式
  3. SDOD:基于depth的实时3D检测与分割
  4. sourcetree 回滚
  5. pypthon3精要(16)-enumerate
  6. android初学之退出应用程序
  7. js声明变量的三种方式
  8. some understanding of《Improved Use of Continuous Attributes in C4.5》
  9. WordPress主题制作全过程(二):主题文件构成
  10. jsp购物车和mysql_用jsp和数据库做的购物车的源程序
  11. xp精简版安装iis
  12. 笔记本电脑计算机恢复出厂设置密码,笔记本电脑怎么恢复出厂设置?
  13. 离线 维基百科 android,维基百科离线版(Kiwix)
  14. 在Windows Server 2012中搭建WEB服务器,附ASP配置方法
  15. Java 导出 PDF之固定模板导出
  16. Opencv学习笔记 常用函数、基础知识二
  17. 通过高德api获取经纬度
  18. SYN, FIN, ACK, PSH, RST, URG
  19. 平板win10 android哪个耗电,您会为平板电脑选择win10还是Android?
  20. Car-eye 车辆管理系统API设计

热门文章

  1. 三、CRUD(增删改查)
  2. Linux下tar bz gz等压缩包的压缩和解压
  3. React 热区组件
  4. 乱七八糟的笔记(%)
  5. uml各类图--完整全面实例
  6. 多行输入以及结束输入
  7. 专访中科创达软件工程师龙辉:Idea赋予实践的演进之路
  8. Vue项目在标签中如何书写多个内敛style样式
  9. 08 | QPaint绘图类
  10. idea中java文件都不能运行变成橙色文件