Jenkins-pipeline自动化构建Java应用

本实验操作需要:Jenkins,git代码仓库(如gitlab,gitee等都可以),maven,docker,docker镜像仓库(habor,nexus或者阿里云ACR等)以及k8s环境。

前期准备工作

本例需要Jenkins插件如下:

Git
Git Parameter
Git Pipeline for Blue Ocean
GitLab
Credentials
Credentials Binding
Blue Ocean
Blue Ocean Pipeline Editor
Blue Ocean Core JS
Pipeline SCM API for Blue Ocean
Dashboard for Blue Ocean
Build With Parameters
Dynamic Extended Choice Parameter Plug-In
Dynamic Parameter Plug-in
Extended Choice Parameter
List Git Branches Parameter
Pipeline
Pipeline: Declarative
Kubernetes
Kubernetes CLI

Kubernetes Credentials
Image Tag Parameter
Active Choices

安装完毕记得重启一下jenkins。

因为是实验环境,我这里直接拷贝一份杜宽老师的代码

杜宽/spring-boot-project放在我的代码仓库中。

  • 添加docker镜像仓库的凭证:

  • 在jenkins上添加git的ssh-key,每个代码仓库都会有指导创建,这里不赘述了,不了解的百度一下。 

如果添加后拉取代码有提示错误信息 :

Failed to connect to repository : Command "git ls-remote -h git@GIT_URL:/home/git/www.git HEAD" returned status code 128:
stdout:
stderr: Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

 在Manage Jenkins --> Configure Global Security 下有一个配置,这里的选项选择为No verification,即可解决。

  • 在jenkins上添加k8s集群kebectl控制认证配置,一般路径在~/.kube/config。

创建Jenkinsfile

在代码仓库根下创建Jenkinsfile文件。

pipeline {
  agent any
  stages {
    stage('Pulling Code') {
      parallel {
        stage('Pulling Code by Jenkins') {
          when {
            expression {
              env.gitlabBranch == null
            }

          }
          steps {
            git(changelog: true, poll: true, url: 'git@gitcode.net:qq_39626154/spring-boot-project.git', branch: "${BRANCH}", credentialsId: 'git-ssh-key')
            script {
              COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
              TAG = BUILD_TAG + '-' + COMMIT_ID
              println "Current branch is ${BRANCH}, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"
              
            }

          }
        }

        stage('Pulling Code by trigger') {
          when {
            expression {
              env.gitlabBranch != null
            }

          }
          steps {
            git(url: 'git@gitcode.net:qq_39626154/spring-boot-project.git', branch: env.gitlabBranch, changelog: true, poll: true, credentialsId: 'git-ssh-key')
            script {
              COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
              TAG = BUILD_TAG + '-' + COMMIT_ID
              println "Current branch is ${env.gitlabBranch}, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"
            }

          }
        }

      }
    }

    stage('Building') {
      steps {
            sh """ 
              /usr/local/maven/bin/mvn clean install -DskipTests
              ls target/*
            """
      }
    }

    stage('Docker build for creating image') {
      environment {
        HARBOR_USER     = credentials('HARBOR_ACCOUNT')
    }
      steps {
          sh """
          echo ${HARBOR_USER_USR} ${HARBOR_USER_PSW} ${COMMIT_ID} ${TAG}
          docker build -t ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${COMMIT_ID} .
          docker login -u ${HARBOR_USER_USR} -p ${HARBOR_USER_PSW} ${HARBOR_ADDRESS}
          docker push ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${COMMIT_ID}
          """
      }
    }

    stage('Deploying to K8s') {
      environment {
        MY_KUBECONFIG = credentials('study-k8s-kubeconfig')
    }
      steps {
           sh """
           /usr/local/bin/kubectl --kubeconfig $MY_KUBECONFIG set image deploy -l app=${IMAGE_NAME} ${IMAGE_NAME}=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${COMMIT_ID} -n $NAMESPACE
           """
      }
    }

  }
  environment {
    COMMIT_ID = ""
    HARBOR_ADDRESS = "registry.cn-hangzhou.aliyuncs.com"
    REGISTRY_DIR = "maodocker"
    IMAGE_NAME = "spring-boot-project"
    NAMESPACE = "kubernetes"
    TAG = ""
  }
  parameters {
    gitParameter(branch: '', branchFilter: 'origin/(.*)', defaultValue: '', description: 'Branch for build and deploy', name: 'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH')
  }
}

 创建Dockerfile

在执行流水线过程时,需要将代码的编译产物做成镜像。Dockerfile主要写的是如何生成公司业务的镜像,而本示例是Java项目,只需要把JAR包放在有JRE环境的镜像中,然后启动该JAR包即可:

# 基础镜像可以按需修改,可以更改为公司自有的镜像
FROM registry.cn-beijing.aliyuncs.com/dotbalo/jre:8u211-data
#JAR包名称改成实际的名称,本示例为spring-cloud-eureka-0.0.1-SNAPSHOT.jar
COPY target/spring-cloud-eureka-0.0.1-SNAPSHOT.jar ./
# 启动JAR包
CMD java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar

 定义 Kubernetes 资源

在GitLab创建的Group为kubernetes,可以认为其是一个项目,同一个项目可以部署至Kubernetes集群中的同一个Namespace中,本示例为kubernetes命名空间。由于使用的是私有仓库因此需要先配置拉取私有仓库镜像的密钥:

# kubectl create ns kubernetes
namespace/kubernetes created
# kubectl create secret docker-registry harborkey-docker-server=CHANGE HERE FOR YOUR HARBOR ADDRESS --docker-username=admin-docker-password=Harbor12345 --docker-email=mail@kubeasy.com -n kubernetes
secret/harborkey created

yaml文件app.yaml,资源限制部分请按照业务需求调整。

---
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: spring-boot-project
  name: spring-boot-project
  namespace: kubernetes
spec:
  ports:
  - name: web
    port: 8761
    protocol: TCP
    targetPort: 8761
  selector:
    app: spring-boot-project
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: null
  name: spring-boot-project
  namespace: kubernetes
spec:
  ingressClassName: nginx
  rules:
  - host: spring-boot-project.test.com
    http:
      paths:
      - backend:
          service:
            name: spring-boot-project
            port: 
              number: 8761
        path: /
        pathType: ImplementationSpecific
      
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: spring-boot-project
  name: spring-boot-project
  namespace: kubernetes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spring-boot-project
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: spring-boot-project
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - spring-boot-project
              topologyKey: kubernetes.io/hostname
            weight: 100
      containers:
      - env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        image: registry.cn-hangzhou.aliyuncs.com/maodocker/springboot-project:v0.0.1
        imagePullPolicy: IfNotPresent
        lifecycle: {}
        livenessProbe:
          failureThreshold: 2
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8761
          timeoutSeconds: 2
        name: spring-boot-project
        ports:
        - containerPort: 8761
          name: web
          protocol: TCP
        readinessProbe:
          failureThreshold: 2
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 8761
          timeoutSeconds: 2
        resources:
          limits:
            cpu: 994m
            memory: 1170Mi
          requests:
            cpu: 10m
            memory: 55Mi
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: harborkey
      restartPolicy: Always
      securityContext: {}
      serviceAccountName: default

先再集群上部署该应用:

# kubectl apply -f app.yaml

创建Jenkins任务

 

 

 点击Build Now,第一次构建之后会出现Build with Parameters就可以选择分支构建。

 点击构建查看控制台输出:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/31075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python网络爬虫基础进阶到实战教程

文章目录 认识网络爬虫HTML页面组成Requests模块get请求与实战效果图代码解析 Post请求与实战代码解析 发送JSON格式的POST请求使用代理服务器发送POST请求发送带文件的POST请求 Xpath解析XPath语法的规则集:XPath解析的代码案例及其详细讲解:使用XPath解…

k8s使用ceph存储

文章目录 初始化操作k8s使用ceph rbdvolumePV静态pv动态pv k8s使用cephfsvolume静态pv 初始化操作 ceph创建rbd存储池 ceph osd pool create k8s-data 32 32 replicated ceph osd pool application enable k8s-data rbd rbd pool init -p k8s-dataceph添加授权,需…

吴恩达ChatGPT《Building Systems with the ChatGPT API》笔记

1. 课程介绍 使用ChatGPT搭建端到端的LLM系统 本课程将演示使用ChatGPT API搭建一个端到端的客户服务辅助系统,其将多个调用链接到语言模型,根据前一个调用的输出来决定使用不同的指令,有时也可以从外部来源查找信息。 课程链接&#xff1a…

client-go的Indexer三部曲之三:源码阅读

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 《client-go的Indexer三部曲》全部链接 基本功能性能测试源码阅读 本篇概览 本文是《client-go的Indexer三部曲》系列的终篇,主要任务是阅读和…

VR全景智慧园区,沉浸式数字化体验,720度全视角展示

导语: 随着科技的迅猛发展,虚拟现实(Virtual Reality,简称VR)全景技术已经成为了人们趋之若鹜的新兴领域。 而城市园区作为现代社会的重要组成部分,也正在积极寻求创新的方式来吸引更多的人流和投资。 一&…

C++基础

C基础入门 1 C初识 1.1 第一个C程序 编写一个C程序总共分为4个步骤 创建项目创建文件编写代码运行程序 1.1.1 创建项目 ​ Visual Studio是我们用来编写C程序的主要工具,我们先将它打开 1.1.2 创建文件 右键源文件,选择添加->新建项 1.1.3 编…

SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础》提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/signalr/overview/getting-started…

【面试】标准库相关题型(二)

文章目录 1. deque底层实现原理1.1 概述1.2 原理图1.3 类结构1.4 操作函数 2. 什么时候使用vector、list、deque2.1 vector2.2 list2.3 deque 3. priority_queue的底层实现原理3.1 一句话概括:用堆来实现优先级队列3.2 堆结构3.3 底层容器3.4 STL对堆结构提供的接口…

Java-API简析_java.lang.SecurityManager类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/131346082 出自【进步*于辰的博客】 其实我的【Java-API】专栏内的博文对大家来说意义是不大的。…

Python入门(二十七)测试(二)

测试(二) 1.测试类2.各种断言方法3.一个要测试的类4.测试AnonymousSurvey类5.方法setUp() 1.测试类 前面我们编写了针对单个函数的测试,下面来编写针对类的测试。很多程序中都会用到类,因此证明我们的类能够正确工作大有裨益。如…

学了那么长时间的编程,C语言的各种操作符都搞不懂?点开这里有详细的介绍—>

目录 前言 一、原码、反码、补码的基础概念 1.原码 2.反码 3.补码 二、原码、反码、补码的计算方法 1.原码 2.反码 3.补码 三、算术操作符 四、移位操作符 1. 左移操作符 移位规则: 2. 右移操作符 移位规则: (1) …

电脑怎么录屏?推荐2款录制电脑屏幕的软件!

案例:我经常需要把电脑上的内容分享给别人,一般通过手机拍摄的方式。这就导致视频十分模糊,给人的观感不太好,有没有什么方法可以实现在电脑上直接录屏? 【我想录制我的电脑屏幕上的内容分享给别人,但是我…

几个SQL的高级写法

一、ORDER BY FLELD() 自定义排序逻辑 MySql 中的排序 ORDER BY 除了可以用 ASC 和 DESC,还可以通过 ORDER BY FIELD(str,str1,...) 自定义字符串/数字来实现排序。这里用 order_diy 表举例,结构以及表数据展示: ORDER BY FIELD(str,str1,..…

【Neo4j教程之CQL函数基本使用】

🚀 Neo4j 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,C…

3d重建+神经渲染

3d重建 基于深度相机(结构光、TOF、双目摄像头)的三维重建基于图像的三维重建:深度学习基于视觉几何的传统三维重建:这种三维重建方法研究时间比较久远,技术相对成熟。主要通过多视角图像对采集数据的相机位置进行估计,再通过图像…

一种对不同类型齐格勒-尼科尔斯 P-I-D 控制器调谐算法研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

常用工具类之AJ-Captcha入门

1.引入MAVEN依赖 若依官方引入的是1.2.7版本。我选择了目前最常用的1.3.0版本。 在项目中给的 ruoyi-framework\pom.xml 添加依赖 <!-- anji滑块验证码 --><dependency><groupId>com.anji-plus</groupId><artifactId>spring-boot-starter-captc…

通过调整图像hue值并结合ImageEnhance库以实现色调增强

前言 PIL库中的ImageEnhance类可用于图像增强&#xff0c;可以调节图像的亮度、对比度、色度和锐度。 通过RGB到HSV的变换加调整可以对图像的色调进行调整。 两种方法结合可以达到更大程度的图像色调增强。 调整hue值 __author__ TracelessLe __website__ https://blog…

vue2中引入天地图及相关配置

前言 项目中需要引入特殊用途的地图&#xff0c;发现天地图比高德地图、百度地图要更符合需求&#xff0c;于是看了看天地图。 正文 vue2项目中如何引入天地图并对相关的配置进行修改使用呢&#xff1f;官方给的4.0版本的使用说明。 引入&#xff1a; 进入到public/index.html中…

Cocos Creator3D:制作可任意拉伸的 UI 图像

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 制作可任意拉伸的 UI 图像 UI 系统核心的设计原则是能够自动适应各种不同的设备屏幕尺寸&#xff0c;因此我们在制作 UI 时需要正确设置每个控件元素的尺寸&#xff08;size&#…