Jenkins使用Pipeline发布项目到K8S

创建Jenkins的Pipeline任务

创建连接gitlab和harbor的相关凭据:

然后新建Pipeline任务(流水线)即可;内容如下:

node{
    // 固化项目配置参数, 每项目一任务, 方便直接执行; 不建议外部调用
  
  // 镜像仓库
  String HarborUrl='nw-harbor.xxxx.cc'
    String HarborUser='admin'
    String HarborPasswd='Nw-Harbor123'
  
  // Jar构建用: 项目Gitlab地址
  String GIT_SRV='http://git.xxxx.tech'
  String GIT_URL="${GIT_SRV}/all/demo.git"
  // Docker镜像 推送,拉取用: 项目组名称,推送至此Harbor项目组 (e.g: ${HarborUrl}/${Group})
  String Group='zongs-nw'
  // Docker镜像 构建用,部署配置用,Docker镜像 推送,拉取用: 填写项目名称
  String Project_name='demo'
  // Docker镜像 构建用: 生成项目Docker镜像的时区
  String TIME_ZONE='Asia/Shanghai'
  // 项目tag(镜像构建的版本; 这里携带Jenkins任务构建版本)
  String Project_Tag="dm-${env.BUILD_NUMBER}"
  // Docker镜像 构建用,部署配置用
  String JVM_XMS_VALUE='256m'
  // Docker镜像 构建用,部署配置用
  String JVM_XMX_VALUE='256m'
  
  // 部署配置用: 部署至此命名空间
  String NAMESPACE='default'
  // 部署配置用: 运行的 Pod 数目
  String REPLICAS_NUM='1'
  // 部署配置用: 资源CPU需求
  String REQUESTS_CPU='50m'
  // 部署配置用: 资源Memory需求,与 JVM_XMX_VALUE 一致即可
  String REQUESTS_MEM='256Mi'
  // 部署配置用: spring.profiles.active
  String SPRING_PROFILE='dev'
  // 部署配置用: 新创建的Pod状态为Ready持续此时间后认为Available
  String MINREADSECONDS='5'
  
  // K8S YAML 模板文件所在服务器 (部署,服务模板文件)
  String TemplateUrl='http://172.16.220.105/k8s'
  // K8S 群集 操作主机 (用于SSH连接后执行 kubectl 命令)
  String KubernetHost='[email protected]'
  // 远端 操作主机 存放依模板生成的 YAML 文件
  String Yaml_Path='/root/k8s_deploy'
  // 用于SSH连接到 操作主机 的密钥文件 (若Jenkins运行用户可直接连接,则可留空)
  String SSH_KeyFile='/data/jenkins/.ssh/id_rsa'


  properties([
    parameters([
      string(name: 'GIT_BRANCH', defaultValue: 'master', description: '构建用: 填写Git分支地址', trim: false),
      string(name: 'Pom_path', defaultValue: 'pom.xml', description: '构建用: 填写POM文件', trim: false),
      string(name: 'Target_name', defaultValue: 'target/demo-0.0.1-SNAPSHOT.jar', description: '镜像 构建用: 生成的jar包路径名称', trim: false),
      
      choice(name: 'IS_SVC', choices: ['No', 'Yes'], description: '部署配置用: 是否创建服务(为 Yes 部署svc.yaml)'),
      string(name: 'SVC_PORT', defaultValue: '80', description: '部署配置用: 服务本身监听端口', trim: false),
      string(name: 'TARGETPORT', defaultValue: '8080', description: '部署配置用: 服务后端项目端口(即项目本身所监听的端口)', trim: false)
    ])
  ])

    if(!Project_name){
        error "项目名为空"  
    }
  
  if(SSH_KeyFile){
    if(!fileExists("${SSH_KeyFile}")){
      error "连接密钥文件 ${SSH_KeyFile} 不存在"
    }
    SSH_Command="ssh -i ${SSH_KeyFile} -p 22 -o StrictHostKeyChecking=no"
    SCP_Command="scp -i ${SSH_KeyFile} -P 22 -o StrictHostKeyChecking=no"
  }else{
    SSH_Command="ssh -p 22 -o StrictHostKeyChecking=no"
    SCP_Command="scp -P 22 -o StrictHostKeyChecking=no"
  }

    dir("${env.WORKSPACE}"){
        stage('Git阶段'){
      echo "1. 开始拉取代码 (${GIT_URL})"
            git branch: params.GIT_BRANCH, credentialsId: 'nw-gitlab', url: "${GIT_URL}"
        }
    
        stage('Maven阶段'){
            echo "2. 开始Maven编译"
            sh "/usr/local/maven-3.6.3/bin/mvn clean install -Dmaven.test.skip=true -f ${Pom_path}"
      if(!fileExists("${Target_name}")){
        error "编译生成的目标文件${Target_name}不存在"
      }
        }
    
        stage('Docker阶段'){
            echo "3. 开始执行Docker编译、推送、删除"
      echo "--生成 Dockerfile"
      sh "echo 'FROM ${HarborUrl}/library/baseimg-jdk8:c8' > Dockerfile"
      sh "echo 'ENV JVM_XMS=${JVM_XMS_VALUE} JVM_XMX=${JVM_XMX_VALUE}' >> Dockerfile"
      sh "echo 'RUN ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime' >> Dockerfile"
      sh "echo 'COPY ${Target_name} /app/app.jar' >> Dockerfile"
      sh "echo 'ENTRYPOINT [\"/app/start-jar.sh\"]' >> Dockerfile"

            echo "--构建并推送 Docker 镜像 (${HarborUrl}/${Group}/${Project_name}:${Project_Tag})"
      step([$class: 'DockerBuilderPublisher', dockerFileDirectory: "${env.WORKSPACE}", cloud: 'docker_w1', tagsString: "${HarborUrl}/${Group}/${Project_name}:${Project_Tag}", cleanImages: true, cleanupWithJenkinsJobDelete: false, pushCredentialsId: 'nw-harbor', pushOnSuccess: true])
        }
    
    stage('群集主机SSH验证'){
      echo "验证k8s群集内主机 ${KubernetHost} 是否可连通,并确保YAML文件存放目录 ${Yaml_Path}"
      sh "${SSH_Command} ${KubernetHost} mkdir -p ${Yaml_Path}"
    }
    
    stage('K8S-Deployment 配置'){
      echo "从 ${TemplateUrl} 拉取 K8S-Deployment 模板文件"
      sh "wget ${TemplateUrl}/deployment.yaml -O ${Project_name}-deploy.yaml"
      
      echo "按参数配置修改模板文件"
      sh "sed -i 's#CI_PROJECT_NAME#${Project_name}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#NAMESPACE#${NAMESPACE}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#REPLICAS_NUM#${REPLICAS_NUM}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#JVM_XMS_VALUE#${JVM_XMS_VALUE}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#JVM_XMX_VALUE#${JVM_XMX_VALUE}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#SPRING_PROFILE#${SPRING_PROFILE}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#REPOSITORY_BASE#${HarborUrl}/${Group}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#BUILD_IMAGE_VERSION#${Project_Tag}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#REQUESTS_CPU#${REQUESTS_CPU}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#REQUESTS_MEM#${REQUESTS_MEM}#g' ${Project_name}-deploy.yaml"
      sh "sed -i 's#MINREADSECONDS#${MINREADSECONDS}#g' ${Project_name}-deploy.yaml"
      
      echo "将修改的文件 ${Project_name}-deploy.yaml 传送至 k8s 群集内部机器 ${KubernetHost}"
      sh "${SCP_Command} ${Project_name}-deploy.yaml ${KubernetHost}:${Yaml_Path}"
    }
    
    if(IS_SVC == 'Yes'){
      stage('K8S-SVC 配置(可选项)'){
        echo "从 ${TemplateUrl} 拉取 K8S-SVC 模板文件"
        sh "wget ${TemplateUrl}/svc.yaml -O ${Project_name}-svc.yaml"
        
        echo "按参数配置修改模板文件"
        sh "sed -i 's#CI_PROJECT_NAME#${Project_name}#g' ${Project_name}-svc.yaml"
        sh "sed -i 's#NAMESPACE#${NAMESPACE}#g' ${Project_name}-svc.yaml"
        sh "sed -i 's#SVC_PORT#${SVC_PORT}#g' ${Project_name}-svc.yaml"
        sh "sed -i 's#TARGETPORT#${TARGETPORT}#g' ${Project_name}-svc.yaml"
        
        echo "将修改的文件 ${Project_name}-svc.yaml 传送至 k8s 群集内部机器 ${KubernetHost}"
        sh "${SCP_Command} ${Project_name}-svc.yaml ${KubernetHost}:${Yaml_Path}"
      }
    }
    
    stage('部署至K8S'){
      echo "部署应用 ${Project_name}-deploy.yaml"
      status = sh(script: "${SSH_Command} ${KubernetHost} kubectl get deployments ${Project_name}", returnStatus: true)
      if("${status}" == '0'){
        sh "${SSH_Command} ${KubernetHost} kubectl replace -f ${Yaml_Path}/${Project_name}-deploy.yaml"
      }else{
        sh "${SSH_Command} ${KubernetHost} kubectl create -f ${Yaml_Path}/${Project_name}-deploy.yaml"
      }

      if(IS_SVC == 'Yes'){
        echo "部署服务 ${Project_name}-svc.yaml"
        status_svc = sh(script: "${SSH_Command} ${KubernetHost} kubectl get svc ${Project_name}", returnStatus: true)
        if("${status_svc}" == '0'){
          echo "服务 ${Project_name} 已存在, 如想重建, 需先删除."
        }else{
          sh "${SSH_Command} ${KubernetHost} kubectl create -f ${Yaml_Path}/${Project_name}-svc.yaml"
        }
      }
    }
    }
}

初次执行会失败,没关系,因为需要“初始化”里面的动态参数;之后再执行即可:

在k8s中查看:

通过配置的域名即可访问到demo项目:

Tips: 以上所有出现的域名均解析到内网地址,故外部网络不需要测试访问了。

《Jenkins使用Pipeline发布项目到K8S》有2条评论

  1. hello there. What can i do for you hehes thanks

    i registered 2 weeks ago but i cant find where can i search any words.

    thanks for help 🙂

    回复

发表评论

error: Content is protected !!