Jenkins workflowLibs库的使(妙)用
本文采用更为大白话的形式进行记录,实际应用在生产环境超过半年,现在整理出来分享一下
重温概念
开篇介绍,要写的当然还是一些文字性内容,不管是官方原文或书籍描述,都要花心思去理解,然后顺便表达一下我自己的理解。
- 可信共享库和不可信共享库
Jenkins的共享库形式,分为可信共享库和不可信共享库两种。
可信库可以调用/使用Java中的任何方法、Jenkins的API、Jenkins插件、Groovy语言等。由于可信库在它们可以调用和使用的内容方面具有如此广泛的优势,所以管理可在其中添加和更改代码的权限就非常重要了。因此对可信库进行更新应该需要适当级别的源码版本控制访问和验证。出于同样的原因,可能会造成任何损害的代码应该始终被包含在受监督的可信库中。
不可信库代码是被调用和使用限制的代码,调用先前列出的方法类型不允许使用相同的自由度,而且它不能像可信代码那样访问更大的内部对象集合。
- 内部库和外部库
共享库的另一个不同之处是,托管源码控制仓库的位置,不管是在Jenkins实例内部还是在外部源码控制系统中。
在大多数情况下内部被视为一种更偏向传统的选项,但出于完整性考虑,此处也包含了相关描述。
需求引入
本文标题提到的使(妙)用,就是指上面概念中提到的内部库,这个概念网上(千篇一律)很少能找到。是的,我这里将仔细分析出我的应用场景,以便于表达我的迫切需求(这也可能是很多共享库用户的需求)。
在大多数共享库使用场景下,我们都是将共享库的代码提交到公共的git仓库服务商,例如github、gitee,或者是提交到企业内部搭建的git服务端,例如gitlab。为了能够正常使用这个外部的共享库,Jenkins与之的一大要求就是网络能够连通,保障能通过ssh或者http协议进行通信。
但往往很多场景下,我们的Jenkins不能连通外网,甚至连必须的插件也需要离线下载后安装或者临时通过网络代理安装。如果网络不能连通,是不是就意味着我们的共享库不能用了呢?一开始我也这样以为,想要用到共享库方法的解决办法(未必最佳)可能有如下
-
方法一
拆分共享库的方法,单独集成到
pipeline流水线脚本中,但这样会导致每个pipeline的长度回归到使用共享库之前那样冗长和重复 -
方法二
再在
Jenkins所在的网络环境中搭建一个轻量的git服务端,例如git init创建一个,但无法可视化,且不安全,存在于服务器的仅仅是一个目录
以上方法虽然能实现我们想要使用共享库方法,但都不太友好。
再来聊一下内部库,在Jenkins 2.0时代,包含着一个内部库,可用于存储内部库或测试目的。内部库默认有一个特定的名称workflowLibs,这其实就是一个内置于Jenkins内部的Git仓库。那既然这个库内置了,存在于哪里呢?我们来看一下Jenkins的安装主目录,我这里的Jenkins基于k8s安装,并且做了数据卷的持久化,进入对应的pv下查看,其中的主要目录如下所示
$ tree -L 1 kube-system-jenkins-data-pvc-6866fcaf-b742-40e0-afa8-64b93e75ef52
kube-system-jenkins-data-pvc-6866fcaf-b742-40e0-afa8-64b93e75ef52/
├── backup
├── jobs
├── log
├── logs
├── nodes
├── pipeline-config-history
├── plugins
├── secrets
├── updates
├── userContent
├── users
├── war
├── workflow-libs # 内部库
└── workspace
内部库名为workflow-libs,这个内部库其实就是一个已经初始化且存在于Jenkins内部的Git仓库。
下面记录如何使用workflowLibs内部库。
开通workflowLibs
workflowLibs内部库和普通的git仓库一样,可以通过ssh访问或http访问,本文记录的是通过ssh协议访问,另外一种方式类似。
由于Jenkins部署在k8s中,因此我们只能通过ingress或者在内网环境下通过nodePort方式访问。在k8s中部署的Jenkins默认暴露的是8080端口,这个端口用于提供http访问。同时我这里使用到了基于k8s动态的slave模式动态构建以及管理外部的普通agent,相互通信需要再打开一个端口,端口号可以在Jenkins的系统配置—>全局安全配置—>代理中指定。
开通ssh端口
这里需要再为Jenkins开放一个ssh协议的端口,用于共享库的开发者和workflowLibs内部库通信,由于不想暴露给外部,我这里还是通过nodePort方式去访问,Jenkins Service声明如下
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: kube-system
spec:
type: NodePort
selector:
name: jenkins
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
nodePort: 30009
- name: agent
port: 35555
targetPort: 35555
protocol: TCP
nodePort: 35555
- name: jenkinsssh # Jenkins ssh
port: 22222
targetPort: 22222
protocol: TCP
nodePort: 32222
重新应用资源清单
$ kubectl apply -f jenkins-svc.yaml
登录到Jenkins,系统配置—>全局安全配置—>SSH Server,设置ssh端口,这个端口与上面Service中指定的端口对应

配置密钥
在http://<jenkins-url>/user/<userid>/configure页面的SSH公钥字段中添加用户的SSH