• 通过pipeline实现jenkins的ci/cd功能


    pipeline是基于groove进行实现的,不过从jenkins官方的说明中,pipeline分为脚本式和声明式,参见链接。经过对两种的比较,个人比较偏向脚本式的方法。也就是

    Jenkinsfile (Scripted Pipeline)
    
    node {  
        stage('Build') { 
            // 
        }
        stage('Test') { 
            // 
        }
        stage('Deploy') { 
            // 
        }
    }
    

     因为声明式的方法用起来不方便,还有就是语句执行的结果不知道怎么赋值到变量中去。

    如下简单介绍下现有的jenkinsfile,由于能力有限,如有错误,请指正。

    1.由于是部署的spring-cloud的项目,会依赖maven环境,所以使用了dockerfile的多步编译。

     1 FROM maven:3-alpine as builder
     2 ADD . /build/
     3 WORKDIR /build
     4 COPY ./settings.xml   /root/.m2/
     5 COPY ./repository   /root/.m2/
     6 RUN   mvn  -DskipTests clean install package -q -U -Ppro
     7 
     8 
     9 
    10 FROM frolvlad/alpine-oraclejdk8:slim
    11 WORKDIR /home/
    12 ENV LC_ALL=en_US.UTF-8
    13     LANG=en_US.UTF-8
    14     JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom "
    15 
    16 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
    17 RUN apk add --no-cache tzdata 
    18     && ln -sf /usr/share/zoneinfo/Asia/Chongqing /etc/localtime 
    19     && echo "Asia/Chongqing" > /etc/timezone 
    20     &&rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache ## 清除缓存
    21 
    22 
    23 COPY --from=builder /build/target/x.jar /home/app.jar
    24 EXPOSE 19090
    25 ENTRYPOINT [ "sh", "-c", "java -server -Xms2048m -Xmx2048m $JAVA_OPTS -jar app.jar --spring.profiles.active=test" ]

     多步编译完成之后,编写pipeline文件

    node('xx-jnlp'){
              def  DockerTestImage = ''
              def  DockerProductImage = ''
              def  REPOSITORY = 'imagename'
    
    
          stage('clone git'){
            echo "BRANCH IS :${BRANCH}"
            checkout([$class: 'GitSCM', branches: [[name: "${BRANCH}"]],
            userRemoteConfigs: [[url: 'git@x.x.x.x:java/x.git',credentialsId:'xxxxxxxxxxxxxxxx']]
            ])
            echo "hello ${DockerTestImage}"
            echo "hello ${BRANCH}"
          }
          
          stage('init'){
            script {
    
                build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                GIT_COMMIT=sh(script:"echo ${build_tag} | cut -c 1-8", returnStdout:true).trim()
                LOCALDATE=sh(script:"date '+%F'",returnStdout:true).trim()
                VERSION = "V1-${LOCALDATE}-${GIT_COMMIT}"
              }
          }
          stage('Build master') {
            if (env.BRANCH_NAME == 'master'){
              echo "3.Build Docker Image Stage for master"
              sh "ls -l /root/.m2"
              echo "ls -l /root/.m2"
              sh "cp /root/.m2/settings.xml /root/.m2/repository . -rfp"
              sh "docker build -f Dockerfile_product_k8s -t ${REPOSITORY} . "
    
            }
          }
          stage('Build test'){
            if (env.BRANCH_NAME != 'master'){
              echo "3.Build Docker Image Stage for test"
              sh "ls -l /root/.m2"
              echo "ls -l /root/.m2"
              sh "cp /root/.m2/settings.xml /root/.m2/repository . -rfp"
              sh "docker build -f Dockerfile_test_k8s -t ${REPOSITORY}  . "
            }
          }
          stage('Push to master') {
            if(env.BRANCH_NAME == 'master'){
              echo "4.Push Docker Image master Stage"
              withCredentials([usernamePassword(credentialsId: 'registry.cn-hangzhou.aliyuncs.com', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]){
                sh "docker login --username=${dockerHubUser} --password=${dockerHubPassword} registry.cn-hangzhou.aliyuncs.com"
                sh "docker tag  ${REPOSITORY}  ${DockerProductImage}:${VERSION}"
                sh "docker push  ${DockerProductImage}:${VERSION}"
    
              }
              
              
    
            }
          }
    
    
          stage('Push to test'){
            if(env.BRANCH_NAME != 'master'){
              echo "4.Push Docker Image test Stage"
              withCredentials([usernamePassword(credentialsId: 'registry.cn-hangzhou.aliyuncs.com', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]){
                sh "docker login --username=${dockerHubUser} --password=${dockerHubPassword} registry.cn-hangzhou.aliyuncs.com"
                sh "docker tag  ${REPOSITORY}  ${DockerTestImage}:${VERSION}"
                sh "docker tag  ${REPOSITORY}  ${DockerTestImage}:latest"
                sh "docker push  ${DockerTestImage}:${VERSION}"
    
              }
            }
          }
          stage('YAML') {
              echo "5. Change YAML File Stage"
            
          }
          stage('Deploy') {
    
              echo "6. Deploy Stage"
          }
    
    
    }
    

     说明:

    1、node后面指定的是k8s slave节点的tag名称,当运行此任务时k8s会新建节点,在此节点上运行节点,并执行dockerfile,完成打包和生成镜像的功能。

    2、git clone stage是复制代码到slave节点

    3、init stage 初始化变量

    4、build stage根据不同的代码分支执行不同的创建命令步骤,并完成不同的镜像文件创建

    5、push stage将创建好的镜像推送到服务器上。

    6、发布的命令暂时使用的阿里云的触发器来实现的。

    如上。

    遇到过的坑。

    1、如果使用声明式的流水线,会发现bash变量的值不是太好赋值到变量中,而只能使用parameter实现,不能满足要求。后面忍痛切换到node方式。

    2、由于node和pipeline用法上有很多区别,所以切换的时候注意小心小心。

    3、由于docker的编译环境和镜像生成环境是使用不同的镜像,所以生成后的jar包如果不使用多步编译只能stash到生成镜像的docker镜像中,会比较麻烦。目前使用的dockerfile的多步编译,会好些。但是每次编译都会下载网络依赖,会耗时比较久。

  • 相关阅读:
    KMP的next数组性质运用
    谁说前端不需要懂-Nginx反向代理与负载均衡
    Vue源码
    js学习网站
    CSS文本溢出显示省略号
    Js中带有小数的值相加产生的问题
    使用ueditor的时候,style样式传递到后台时被过滤没了
    实现div里的内容垂直居中
    安装sass报错
    js方法
  • 原文地址:https://www.cnblogs.com/chrrydot/p/10811583.html
Copyright © 2020-2023  润新知