-
- 1、重温概念
- 2、需求引入
- 3、开通workflowLibs
- 3.1 开通ssh端口
- 3.2 配置密钥
- 3.3 初始化克隆workflowLibs库
- 3.4 配置使用workflowLibs库
- 4、自定义使用workflowLibs库
- 4.1 方法定义
- 4.2 插件配置
- 4.3 使用
- 5、总结
本文采用更为大白话的形式进行记录,实际应用在生产环境超过半年,现在整理出来分享一下
1、重温概念
开篇介绍,要写的当然还是一些文字性内容,不管是官方原文或书籍描述,都要花心思去理解,然后顺便表达一下我自己的理解。
- 可信共享库和不可信共享库
Jenkins
的共享库形式,分为可信共享库和不可信共享库两种。
可信库可以调用/使用Java
中的任何方法、Jenkins
的API
、Jenkins
插件、Groovy
语言等。由于可信库在它们可以调用和使用的内容方面具有如此广泛的优势,所以管理可在其中添加和更改代码的权限就非常重要了。因此对可信库进行更新应该需要适当级别的源码版本控制访问和验证。出于同样的原因,可能会造成任何损害的代码应该始终被包含在受监督的可信库中。
不可信库代码是被调用和使用限制的代码,调用先前列出的方法类型不允许使用相同的自由度,而且它不能像可信代码那样访问更大的内部对象集合。
- 内部库和外部库
共享库的另一个不同之处是,托管源码控制仓库的位置,不管是在Jenkins
实例内部还是在外部源码控制系统中。
在大多数情况下内部被视为一种更偏向传统的选项,但出于完整性考虑,此处也包含了相关描述。
2、需求引入
本文标题提到的使(妙)用,就是指上面概念中提到的内部库,这个概念网上(千篇一律)很少能找到。是的,我这里将仔细分析出我的应用场景,以便于表达我的迫切需求(这也可能是很多共享库用户的需求)。
在大多数共享库使用场景下,我们都是将共享库的代码提交到公共的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
内部库。
3、开通workflowLibs
workflowLibs
内部库和普通的git
仓库一样,可以通过ssh
访问或http
访问,本文记录的是通过ssh
协议访问,另外一种方式类似。
由于Jenkins
部署在k8s
中,因此我们只能通过ingress
或者在内网环境下通过nodePort
方式访问。在k8s
中部署的Jenkins
默认暴露的是8080
端口,这个端口用于提供http
访问。同时我这里使用到了基于k8s
动态的slave
模式动态构建以及管理外部的普通agent
,相互通信需要再打开一个端口,端口号可以在Jenkins
的系统配置—>全局安全配置—>代理中指定。
3.1 开通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
重新应用资源清单
代码语言:javascript复制$ kubectl apply -f jenkins-svc.yaml
登录到Jenkins
,系统配置—>全局安全配置—>SSH Server
,设置ssh
端口,这个端口与上面Service
中指定的端口对应
3.2 配置密钥
在http://<jenkins-url>/user/<userid>/configure
页面的SSH
公钥字段中添加用户的SSH
公钥,这个公钥在我们能够和Jenkins Server
进行ssh
通信的机器上生成即可,生成后在当前用户的设置界面下进行添加
3.3 初始化克隆workflowLibs库
上面的操作完成后,就可以在共享库代码的开发机器(ssh
客户端)上进行克隆了
➜ ~ git clone ssh://ssgeek@192.168.12.82:32222/workflowLibs.git
Cloning into 'workflowLibs'...
warning: You appear to have cloned an empty repository.
➜ ~ cd workflowLibs
➜ workflowLibs git checkout -b master
Switched to a new branch 'master'
3.4 配置使用workflowLibs库
要提到的是,与配置其他的共享库不一样,内部库在使用前并不需要在Jenkins
上单独配置使用共享库workflowLibs
内部库,内部库只要提交代码,就能直接在pipeline
中导入和使用。
4、自定义使用workflowLibs库
这里以我生产使用的workflowLibs
库中的其中一个方法为例,即上线通知,我把它称为“上线小喇叭”。
4.1 方法定义
使用这个功能时,我关注到Jenkins
最新的钉钉插件已经更新,这次的上线通知借助了此插件,如果是不想通过插件,更为灵活的自定义钉钉通知,可以参考我之前的文章JenkinsShareLibrary实践之自定义通知器,两种方式具体选择哪个,根据自己的需求合理定制即可。
我把关于钉钉插件和共享库使用的方法命名为dingtalk.groovy
,为了减少在pipeline
中的引用操作,将这个文件放在了共享库目录的全局方法目录中,对pipeline
来说,直接调用。
整个workflowLibs
库的目录结构如下
[root@dev workflowLibs]# tree -L 2
.
├── README.md
└── vars
└── dingtalk.groovy
1 directory, 2 files
方法如下,其中的消息内容需要按照插件说明编写固定的格式
代码语言:javascript复制/* dingtalk.groovy
##################################################
# Created by SSgeek #
# #
# A Part of the Project jenkins workflowLibs #
# https://www.ssgeek.com #
##################################################
*/
// post步骤
def dingTalk(BasicEnv,ImageTag,ReleaseMess){
wrap([$class: 'BuildUser']){
dingTalk (
// 机器人 id
robot: 'eb5e68bb-1ad7-4638-8008-9d0d1072d319',
// 消息类型
type: 'ACTION_CARD',
// 需要 @ 的手机号码
at:[],
// 是否 @ 全部
atAll: true,
// 消息标题
title: '生产上线小喇叭',
// 消息内容主体
text: [
"[${env.JOB_NAME}](${env.JOB_URL})n",
'---',
"- 任务编号:[${env.BUILD_ID}](${env.BUILD_URL})",
"- 上线版本:**${ImageTag}**",
"- 上线环境:**${BasicEnv}**",
// "- 上线结果:**☆${currentBuild.currentResult}☆**",
"- 上线结果:**?☆${currentBuild.currentResult}☆?**",
"- 上线发起:**${env.BUILD_USER}**",
"- 上线描述:**${ReleaseMess}**",
"- 持续时间:${currentBuild.durationString}n",
],
// 点击消息跳转的 URL
messageUrl: '',
// 图片 URL
picUrl:'',
// 单个按钮的方案,设置此项和 singleUrl 后 btns 无效
// singleTitle:'',
// singleUrl:'',
// 自定义按钮组
btns: [
[
title: '发布日志',
actionUrl: "${env.BUILD_URL}/console"
],
[
title: '控制台',
actionUrl: "https://jenkins.ssgeek.com"
]
],
// 按钮的排列方式:horizotal水平排列H、vertical垂直排列V
btnLayout: 'H',
// 是否隐藏发消息者头像
hideAvatar: true
)
}
}
4.2 插件配置
插件需要在Jenkins
中配置钉钉机器人的hook
地址,配置完成会生成一个id
,和上面方法中的robot
对应
4.3 使用
在pipeline
中使用,部分内容如下
post{
always{
script{
dingtalk.dingTalk(BasicEnv,ImageTag,ReleaseMess)
}
}
}
效果这里就不贴图啦,查看钉钉插件的文档即可。
5、总结
本文通过workflowLibs
库的灵活使用,实现了在无外网共享库环境下,独立的Jenkins
使用共享库的需求
希望能帮助到大家,See you ~
部分描述内容参考自官方文档