微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

云原生DevOps篇:Jenkins集成Kubernetes实现动态Agent构建机制

Jenkins集成Kubernetes实现动态Agent构建机制


之前agent都是运行在k8s node节点上,一般项目更新都是在晚上或者中午,agent只会在更新的时候才会去用,平时一直运行agent也会造成系统的资源浪费,因此可以在Jenkins上集成Kubernetes插件,通过定义Pod模板,当任务开始执行后动态创建一个agent程序,去运行任务,当任务执行完成后,agent也会自动消失。

由于是容器版的agent,肯定有很多工具没有集成在容器里面,因此我们换需要自己制作一个容器,集成丰富的插件

1.Jenkins集成Kubernetes

主要就是安装一个Kubernetes插件,然后配置Kubernetes集群信息,定义agent容器Pod模板,实现创建任务时自动运行一个agent容器

1.1.安装Kubernetes插件

系统管理—>插件管理—>搜索Kubernetes—>直接安装

1622534703157

安装过程很可能会失败,可以尝试多安装几次,最后看到爆黄,重启Jenkins就好了

1622538596688

1.2.进入配置k8s信息以及Pod模板信息页面

1)跳转至Kubernetes插件配置页面

点击系统管理—>cloud—>点击超链接即可调整到配置Kubernetes信息的页面

1622539293408

2)配置集群列表选择Kubernetes

1622539367330

3)点击Kubernetes cloud details进行k8s集群信息配置

1622539424312

1.3.配置Kubernetes集群地址信息

填写kubernetes信息:

kubernetes地址:https://kubernetes.default //访问api的地址,由于Jenkins部署在k8s中可以通过服务发现方式访问api

kubernetes命名空间:jenkins //将来agent运行后存放于哪个命名空间下

1622540074855

填写Jenkins地址信息,声明agent如何连接Jenkins

Jenkins地址:http://jenkins-svc:8080

Jenkins通道:http://jenkins-svc:50000

可以查一下Jenkins的svc资源名称,通过服务发现的方式去连接Jenkins

[root@k8s-master1 ~]# kubectl get svc -n jenkins
NAME          TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                          AGE
jenkins-svc   NodePort   10.99.113.179   <none>        8080:38080/TCP,50000:50000/TCP   14d

1622698805419

最终样子

1623119933144

1.4.添加pod模板

pod模板就是运行agent pod的模板信息,定义一写agent pod的参数

1)点击Pod Templates

1622712023500

2)点击添加Pod模板

1622712202246

3)填写pod模板名称

名称:jnlp-slave

1622770870309

1.5.配置pod模板信息

这个pod模板其实就是agent容器,无需配置agent镜像地址,他会自己从官方拉取,新版的镜像地址为:jenkins/inbound-agent:4.3-4

1)点击 Pod Template details配置pod模板信息

1622770973598

2)配置pod模板信息

名称:jenkins-slave //jenkins agent pod的名称

命名空间:jenkins //jenkins agent pod所在的命名空间

标签列表:jenkins-slave //jenkins任务可以指定agent的标签,最终运行在这个agent上

用法:尽可能的使用这个节点

1622771557286

指定一个存储卷,持久化agent数据

卷类型选择nfs,填写nfs服务器的地址、提供存储的路径,jenkins会自动生成k8s yaml文件,这个nfs会自动被挂载到agent pod数据存储路径:/home/jenkins/agent,也可以使用pvc存储agent数据

1622771833311

配置完数据卷后,即可点击保存

由于我们将agent的数据持久化了,因此也需要把nfs共享路径的权限调整为agent容器的所属用户,否则无法存储数据

[root@k8s-master2 ~]# cd /data2/k8s/
[root@k8s-master2 /data2/k8s]# mkdir jenkins-agent
[root@k8s-master2 /data2/k8s]# chown -R 1000.1000 jenkins-agent

1.6.使用pvc存储agent pod数据(扩展)

1.5中关于agent pod的数据是持久化到nfs中,也可以将agent的数据持久化到pvc里

1.6.1.编写pvc资源yaml文件

apiVersion: v1
kind:  PersistentVolume
Metadata:
  name: jenkins-agent-pv
  labels:
    pv: jenkins-agent-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /data2/k8s/jenkins-agent-data
    server: 192.168.16.105

---

apiVersion: v1
kind: PersistentVolumeClaim
Metadata:
  name: jenkins-agent-pvc
  namespace: jenkins
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      pv: jenkins-agent-pv

1.6.2.创建pvc资源

[root@k8s-master1 jenkins]# kubectl apply -f jenkins-agent-pvc.yaml 
persistentvolume/jenkins-agent-pv create
persistentvolumeclaim/jenkins-agent-pvc create

[root@k8s-master1 jenkins]# kubectl get pv,pvc -n jenkins | grep agent
persistentvolume/jenkins-agent-pv                           10Gi       RWX            Retain           Bound      jenkins/jenkins-agent-pvc                                                    54m
persistentvolumeclaim/jenkins-agent-pvc               Bound    jenkins-agent-pv                           10Gi       RWX                                   54m

1.6.3.创建pvc存储路径并赋权

[root@k8s-master2 ~]# mkdir /data2/k8s/jenkins-agent-data
[root@k8s-master2 ~]# chown -R 1000.1000 /data2/k8s/jenkins-agent-data

1.6.4.配置jenkins pod模板信息使用pvc作为数据存储

jenkins配置k8s集群地址: http://192.168.16.104:38080/configureClouds/

找到pod模板,点击添加卷—>类型为Persistent Volume Claim—>申明值就是pvc的名称—>挂载路径就是要持久化容器的那个路径数据

1622788925831

在找到最下面的工作空间卷,类型选择Persistent Volume Claim Workspace volume,工作空间卷只能添加一个,主要是为agent进行数据持久化的

填写声明值:jenkins-agent-pvc,这个声明值也就是pvc的名称

1622789112124

配置完成后点击保存即可生效

2.调整pipeline脚本使用动态agent去执行任务

2.1.编辑pipeline脚本

仅需要调整使用哪个gaent即可

pipeline {
    agent { label 'jenkins-slave' }            //仅需要调整使用哪个gaent即可  

    environment {                                  
        IMAGE_REPO = "harbor.jiangxl.com/project"             
        DINGDING_TOKEN_CREDS = credentials('dingding-token')       
        TAB_STR = "\n                               \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"                    
    }

	parameters {                               
		gitParameter(name: 'VERSION',defaultValue: 'master',type: 'BRANCH',description: '选择要更新的分支')            
		string(name: 'project_namespace',defaultValue: 'kNow-system',description: '项目所在的命名空间',trim: true)               
        string(name: 'project_kind',defaultValue: 'deployment',description: '项目资源所使用的pod控制器',trim: true)            
        string(name: 'container_name',defaultValue: 'Nginx',description: '项目所使用的pod容器名称',trim: true)                
        string(name: 'project',description: '项目名称',trim: true)
	}	
    stages {                      
        stage('运维确认信息') {                               
            steps {
                input message: """                          
                jobname: ${project}
                branch: ${VERSION}""",ok: "更新"                       
                updateGitlabCommitStatus(name: env.STAGE_NAME,state: 'success')            
                script {
                    env.BUILD_TASKS = env.STAGE_NAME + " ✅ " + env.TAB_STR       
                }
            }
        }
        stage('拉取项目代码') {                               
            steps {
				checkout([$class: 'GitSCM',branches: [[name: '$VERSION']],extensions: [],userRemoteConfigs: [[credentialsId: 'gitlab-root',url: 'http://192.168.16.106:30080/root/kNow_system.git']]])
                updateGitlabCommitStatus(name: env.STAGE_NAME,state: 'success')
                script {
                    env.BUILD_TASKS += env.STAGE_NAME + " ✅ " + env.TAB_STR     
                }
            }
        }  
        stage('Dockerfile构建项目镜像') {			                        
            steps {
				sh """              
				echo "
FROM harbor.jiangxl.com/project/Nginx-project:v1-code

RUN mkdir /data/code/kNow_system
copY  ./* /data/code/kNow_system/
EXPOSE 80
				" >Dockerfile
				"""                            
 				retry(2) {sh 'docker build -t ${IMAGE_REPO}/${project}:master-v${BUILD_ID} . '}	   
                updateGitlabCommitStatus(name: env.STAGE_NAME,state: 'success')   
                script {
                    env.BUILD_TASKS += env.STAGE_NAME + " ✅ " + env.TAB_STR       
                }           
            }
        }   

        stage('推送镜像到Harbor仓库') {            
            steps {
 				sh 'docker push ${IMAGE_REPO}/${project}:master-v${BUILD_ID}'	
                updateGitlabCommitStatus(name: env.STAGE_NAME,state: 'success') 
                script {
                    env.BUILD_TASKS += env.STAGE_NAME + " ✅ " + env.TAB_STR          
                }
            }
        }           
        stage('更新项目至Kubernetes环境') {                     
            steps {                                    
                sh 'kubectl -n ${project_namespace} set image ${project_kind} ${project} ${container_name}=${IMAGE_REPO}/${project}:master-v${BUILD_ID} --record' 
                updateGitlabCommitStatus(name: env.STAGE_NAME,state: 'success')
                script {
                    env.BUILD_TASKS += env.STAGE_NAME + " ✅ " + env.TAB_STR   
                }
            }
        }                  
    }
    post {
    	success {				
    			echo "构建成功,发送消息到钉钉"
    			sh """
    			curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGDING_TOKEN_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown","markdown": {
                            "title":"project","text": "
                
                                 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐