美文网首页
Jenkins agent-Java项目实践

Jenkins agent-Java项目实践

作者: 阿当运维 | 来源:发表于2023-02-15 17:04 被阅读0次

前言

之前我们已经将jenkins agent环境搭建好(基于docker或k8s动态创建),并且已经通过流水线跑通了一个Demo示例,基于前面搭建的环境,实际项目中针对后端java项目如何通过agent进行发布呢? 其实主要思路还是跟以前一样的:

  • 拉代码
  • maven构建打包
  • 构建镜像
  • 上传至私有镜像仓库
  • 部署服务
    只不过现在这些事情由jenkins master全权交给agent来做, agent做完即销毁。

注意:k8s的方式中,jenkins agent是一个pod,而一个pod可以是一组容器,在这一个pod中这一组容器的数据是共享的,所以系统默认会有一个jnlp的容器用来agent与master连接这是一个必须有的容器,我们还可以在这个pod中加一个maven的容器来实现maven构建打包的阶段。当然了,也可以将这个jnlp容器重构,加入docker,maven等相关工具只用这个镜像去完成也可以,不过目前我还没这么做,只是聚集需要的容器在一个pod中作为一个整体agent去完成的。

思路

  1. 创建流水线任务
  2. jenkins管理节点中创建pod模板,并配置maven容器与docker容器
  3. pod配置-挂载卷 (主要为/root/.m2 以及 kubectl 和.kube下的配置)
  4. 配置 凭据(登录habor的凭据,git拉取代码的凭据)
  5. 流水线代码
  6. 测试调试发布

一.创建流水线任务

新建任务--流水线--填写名称(略)

二.创建Pod模板

1. 模板配置

系统管理-->节点管理-->Configure Clouds-->Pod Temlates-->填写pod模板名称-->detalis展开更详细配置
-->填写命名空间-->agent标签列表(后期通过这个标签名去调用相应的一组agent pod来完成任务)

1-java实践-模板置1.png

2. 容器配置

maven打包构建需要maven容器,docker打包上传镜像需要docker容器

1-jenkins实践-容器配置1.png 1-jenkins实践-容器配置2.png

三. 挂载卷

有些目录或者数据需要挂载到pod中,这里我是有一台nfs服务器(搭建过程略),如果没有nfs存储服务器那么就需要k8s集群中每台机器都需要放一份相同数据了哦~

需要挂载:maven构建需要的/root/.m2; kubectl以及链接的config文件; 宿主机上的docker.sock;rancher工具(看需求);

注意:我们配置了docker容器,经过测试如果不将docker.sock进程挂载进去的话,是无法在docker中操作docker的。
这样挂出来也是比较省事的方法,也是用的比较多的方案,这种操作跟宿主机的docker是同步的。还有一种叫dind,有兴趣的可以自己了解一下。

  1. 查看nfs共享的目录里都有哪些东西?
# nfs共享目录
# showmount -e 
Export list for k8s01.test.hw:
/opt/jenkins_agent_data          *

/opt/jenkins_agent_data# ls -a
.  ..  _data  .kube  rancher-tools  .ssh.bak

/opt/jenkins_agent_data/_data下放的是/root/.m2的数据,将其挂载出来避免每次启动maven agent都会拉一遍所有依赖

/opt/jenkins_agent_data/_data
root@k8s01.test.hw:/opt/jenkins_agent_data/_data# ls
copy_reference_file.log  repository  settings-docker.xml  settings.xml  settings.xml-bak-20211117  settings.xml-bak-20211118  settings.xml.bak_20220711

.kube包含了kubectl工具和k8s集群的config文件,用于在agent直接可发布项目至k8s集群

root@k8s01.test.hw:/opt/jenkins_agent_data/.kube#  ls
cache  config  config.dev  config.uat  kubectl

rancher-tools中为rancher工具,跟kubectl一样,是用来发布项目至rancher集群中(如果你没有rancher集群项目请忽略)

root@k8s01.test.hw:/opt/jenkins_agent_data/rancher-tools# ls
rancher
  1. jenkins-pod模板--容器配置处,添加卷(注意类型)
2-jenkins实践-卷配置1.png 2-jenkins实践-卷配置2.png

四. 配置凭据

系统管理---安全---Manage Credentials

需要配2个凭据:

  1. 拉代码用到访问gitlab项目的凭据
  2. docker推镜像用到的Docker login凭据
    以下为docker凭据配置,gitlab配置的方式同理
3-jenkins实践-凭据管理1.png 3-jenkins实践-凭据管理2.png

五. Pipeline编写

发布至k8s

agent.label这里要写之前配置的pod标签

pipeline {
    agent {
         label 'mavenpod' 
    }
    options {
        skipDefaultCheckout()
    }
    environment {
        IMAGE_REPO = "harbor.hw.xxxx:5000/k8s-test"
        PROJECT_NAME = "health-cloud-evaluation"
        RUN_ENV = "k8s-dev"
    }
    stages {
        stage('get code'){
            steps{
                    git branch: 'tianye-cicd', credentialsId: '248e1fa0-6165-4a81-8297-4107e413207c', url: 'https://gitlab.xxxx.com/java-dev/health-cloud-biz/health-cloud-evaluation.git'
                    //git branch: 'dev', credentialsId: '248e1fa0-6165-4a81-8297-4107e4132017c', url: 'git@gitlab.xxxx.com:java-dev/health-cloud-biz/health-cloud-evaluation.git'
                    // get image-version
                    script {
                            env.GIT_COMMIT_MSG = sh (script: 'git rev-parse --short=8 HEAD', returnStdout: true).trim()
                            IMAGE_VERSION = "${GIT_COMMIT_MSG}-${RUN_ENV}"
                            IMAGE_NAME = "${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                    }    
            }
        }
        stage('maven build'){
            steps{
                container('maven-agent') {
                       sh 'mvn clean package -DskipTests -Pdev'
                }
            }
        }
        stage('build image'){
            steps{
                container('docker-agent') {
                    withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f17d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                        sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'
                        sh "docker build -t ${PROJECT_NAME}:${IMAGE_VERSION} -f deploy/test/Dockerfile ."
                        sh "docker tag ${PROJECT_NAME}:${IMAGE_VERSION}  ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                        sh "docker push ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                        sh 'echo build images success'
                    }
                       
                }
            }
        }
        stage('deploy to k8s'){
            steps{
                sh "sed -i \"s#IMAGE_NAME#${IMAGE_NAME}#g\" deploy/test/k8sdeployment.yaml"
                sh "/home/jenkins/.kube/kubectl apply -f deploy/test/k8sdeployment.yaml"
            }
        }
        stage('health-check'){
            steps{
                sh '/home/jenkins/.kube/kubectl rollout status -n nacos deployment ${PROJECT_NAME}'
            }
        }
        
    }
}
发布至Rancher
pipeline {
   agent {
        label 'mavenpod' 
   }
   options {
       skipDefaultCheckout()
   }
   environment {
       IMAGE_REPO = "harbor.hw.xxx.com:5000/k8s-test"
       PROJECT_NAME = "health-cloud-evaluation"
       RUN_ENV = "dev"
       OLD_IMAGE = "harbor.hw.xxxx.com:5000/health-cloud-server/health-cloud-evaluation:latest"
   }
   stages {
       stage('get code'){
           steps{
                   git branch: 'tianye-cicd', credentialsId: '248e1fa0-6165-4a81-8297-4107e4131207c', url: 'https://gitlab.xxxx.com/java-dev/health-cloud-biz/health-cloud-evaluation.git'
                   //git branch: 'dev', credentialsId: '248e1fa0-6165-4a81-8297-4107e4132017c', url: 'git@gitlab.xxx.com:java-dev/health-cloud-biz/health-cloud-evaluation.git'
                   // get image version
                   script {
                           env.GIT_COMMIT_MSG = sh (script: 'git rev-parse --short=8 HEAD', returnStdout: true).trim()
                           IMAGE_VERSION = "${GIT_COMMIT_MSG}-${RUN_ENV}"
                           IMAGE_NAME = "${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                   } 
           }
       }
       stage('maven build'){
           steps{
               container('maven-agent') {
                      sh "sed -i \"s#${OLD_IMAGE}#${IMAGE_NAME}#g\" deploy/test/docker-compose.yml"
                      sh 'mvn clean package -DskipTests -Pdev'
               }
           }
       }
       stage('build image'){
           steps{
               container('docker-agent') {
                   withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f17d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                       sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'
                       sh "docker build -t ${PROJECT_NAME}:${IMAGE_VERSION} -f deploy/test/Dockerfile ."
                       sh "docker tag ${PROJECT_NAME}:${IMAGE_VERSION}  ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                       sh "docker push ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                       sh 'echo build images success'
                   }
                      
               }
           }
       }
       stage('deploy to rancher'){
           steps{
               sh '/home/jenkins/rancher-tools/rancher --url https://dev.hw.xxxxrancher.com/ --access-key 926407BB131AE8EE5010 --secret-key ksPBDn1fr97bjzAqYk5KaVU8aRfLQF6UHxFdtfwP2 --env 1a5 up -s health-cloud-server -d  -f deploy/test/docker-compose.yml --rancher-file deploy/test/rancher-compose.yml --pull --upgrade --confirm-upgrade'
           }
       }
   }
}

六. 测试发布

3-jenkins实践-结果1.png

——————————————————————————————————————————————————

关于jenkins变量引用用单引还是双引的问题

jenkins 中和shell语法是一致的。

  1. 要引用的是普通字符,单双引号都可以。
  2. 引用的内容中有需要解释的符号,如提取变量的$需要用双引号
  3. 但jenkins的流水线声明的env变量中,解析它的变量用单引号
    如:
   withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f171d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                       sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'

这一段中,经过测试,双引号就解析不出来变量。

  1. 如果需要用双引号里面的命令还需要用双引号,那可以利用转义,如
       sh "sed -i \"s#IMAGE_NAME#${IMAGE_NAME}#g\" deploy/test/k8sdeployment.yaml"

To Do List :

  1. job的workspace挂载出来,省去每次都重新去拉代码(已更新)

  2. 通过git-commit号来作为镜像版本标识,更加有助于回滚 (已更新)


20230220更新:

agent构建的时候,持久化数据也是有必要的,不然首先麻烦的就每次都要重新拉取代码,尝试把agent工作目录挂载到宿主机:

1.将agent的工作目录挂载到nfs服务器上:
系统管理---节点管理---找到你的cloud--pod模板设置中


7-工作目录挂载.png

设置后,会自动将agent的工作路径/home/jenkins/agent下的workspace挂载到nfs服务器的/opt/jenkins_agent_workspace下

查看一下(workspace下job名,而下面就是各job下的数据):

root@k8s01.test.hw:/opt/jenkins_agent_workspace# ls workspace/
k8s-test_health-cloud-evaluation  k8s-test_health-cloud-evaluation@tmp  test-bottom-library_H5-node12.20.2  test-bottom-library_H5-node12.20.2@tmp
root@k8s01.test.hw:/opt/jenkins_agent_workspace# pwd
/opt/jenkins_agent_workspace

不用每次都重新拉代码了:


7-挂在后效果.png

相关文章

网友评论

      本文标题:Jenkins agent-Java项目实践

      本文链接:https://www.haomeiwen.com/subject/zwtukdtx.html