Jenkins安装完成后进入UI界面,首先需要安装需要的插件

Jenkins可以根据实际情况选择适合的源:
系统管理->插件管理->高级
https://updates.jenkins.io/update-center.json #官方源
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json #清华源

然后安装需要的插件:
Git plugin
Maven Integration plugin
Docker plugin
Kubernetes Continuous Deploy Plugin
Kubernetes plugin
Publish Over SSH plugin
SSH Agent Plugin
SSH Build Agents plugin
promoted builds plugin
Promoted Builds (Simple)

配置

Kubernetes plugin插件安装完成后在Jenkins设置里面点击【系统配置】拉到最下面就可以看到一个Cloud

jenkins SSH Source files配置 jenkins配置slave_docker


单击之,添加一个云:

jenkins SSH Source files配置 jenkins配置slave_kubernetes_02


名称:名字随便取,后面连接云的时候需要这个名字。

Kubernetes 地址:访问k8s master上kube-apiserver服务的地址。

Kubernetes 命名空间:Jenkins部署在哪个命名空间里面了。

Jenkins 地址:Jenkins访问地址。

Jenkins 通道:(这特么是一个大坑) :访问Jenkins容器内50000端口地址。因为Jenkins的Service配置文件中我把50000端口映射为nodePort,再加上我配置了dns所以我这里写了域名:端口号的格式,也可以使用IP地址+端口号。

因为Jenkins-master和Jenkins-slave都在k8s集群内部,所以写ClusterIP:端口号应该也是可以的,但是我没试过 略略略:),地址只要能访问到容器内部的50000端口就可以,但是有一点需要注意,这里的格式不能加http不能加/ 感觉应该是协议的问题,但是还没搞懂。

点击连接测试,是否能够成功。

测试

连接成功后,创建一个流水线job进行测试使用。

podTemplate(label: 'jnlp-slave', cloud: 'kubernetes', containers: [
    containerTemplate(name: 'maven', image: '10.0.0.59/jenkins/maven:3.3.9-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
  ],
volumes: [
    persistentVolumeClaim(mountPath: '/root/.m2', claimName: 'maven-m2'),
    persistentVolumeClaim(mountPath: '/home/jenkins/agent/workspace', claimName: 'workspace'),
    ]
)
{
  node("jnlp-slave"){
      stage('Build'){
          git branch: 'master', url: 'http://root:qrGw1S_azFE3F77Rs7tA@gitlab.gemantic.com/java/$JOB_NAME.git'
          container('maven') {
              stage('Build a Maven project') {
                  sh 'mvn clean package -U deploy'
              }
          }
      }
      stage('deploy'){
          sshPublisher(publishers: [sshPublisherDesc(configName: '76', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '/data/script/jenkins.sh $JOB_NAME', execTimeout: 120000000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/data/kubernetes/service/$JOB_NAME', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/$JOB_NAME*.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
      }
  }
}

pipeline解读:

  • podTemplate创建了一个pod模版。cloud字段指定了连接哪个kubernetes云,kubernetes就是刚才创建一个一个k8s,云的名字就是kubernetes。
  • maven镜像为了加快下载速度,我传到了私有仓库,官方镜像就是把IP地址去掉对应的镜像。
  • persistentVolumeClaim定义了目录挂载,把maven构建的缓存目录.m2和构建产生的数据目录workspace都挂载了一下(对应第一篇文章中的pvc)
  • 下面的pipeline指定后面的操作在jnlp-slave中(也就是pod模版同时也是slave节点)
  • 在build操作中,需要先拉取代码,gitlab拉取代码这里使用了gitlab的root token进行拉取的。gitlab用户获取token方法:
  • 下面就是开始编译啦~,因为是一个java服务,编译完成后会生成一个jar包。
  • deploy步骤就是开始发布了,下面的pipeline是用流水线语法自动生成的

然后点击构建进行测试。

jenkins SSH Source files配置 jenkins配置slave_devops_03

  • 构建过程中,可以看到pod调度到master3上进行构建了。
  • 构建过程中用到了两个镜像,一个maven(已被上传到了私有仓库),一个inbound-agent镜像。inbound-agent镜像是官方的镜像,和maven的关系是都在同一个pod中共享数据,并和Jenkins-master进行交互。(inbound-agent镜像怎么修改为私有仓库镜像还没搞明白,总是去公网下载速度慢)
  • 构建过程中不断的下载java程序依赖的各种包,因为是第一次 时间久了一点,但是我们已经把.m2缓存目录挂载出来了,下次再次构建的时候就可以大大缩减构建的时间。
  • workspace也被挂载了出来,每次构建的数据也会保留,以备不时之需。

构建成功后查看nfs共享目录中的数据:

jenkins SSH Source files配置 jenkins配置slave_jenkins_04

root@sa-storage:/data/dev_jenkins# du -sh m2/
218M	m2/
root@sa-storage:/data/dev_jenkins# du -sh workspace/
65M	workspace/

至此所有的需求都实现了,slave实现了动态伸缩,相关的目录都被挂载出来了。

排错

kubectl get pod -n kubernetes-plugin -o wide命令可以查看slave的pod状态,如果出现问题slave一直无限重启,需要查看pod日志。

kubectl logs `kubectl get pod -n kubernetes-plugin -o wide|grep jnlp-slave|awk '{print $1}'` -n  kubernetes-plugin

每次重启pod的名字都会重新生成,而且正在创建中的pod是无法查看日志的,就算有问题pod也是瞬间就重启了,所以只能上面的这个命令无限的刷。手速快的可以手动哦~手速跟不上的也可以写个循环哒。主要就是文中说的那个大坑,那个坑过去,小问题都可以通过看日志解决的。如果忘记大坑在哪里,可以ctrl+f搜索关键字 “大坑” 哦~