CI/CD-Jenkins安装与应用

CI/CD-Jenkins安装与应用

Docker安装Jenkins

docker-compose.yaml

yaml 复制代码
version: "3.8"
# ========================
# 自定义网络配置
# ========================
networks:
  cicd:
    driver: bridge

services:
  jenkins:
    # 尽量使用新版本的Jenkins, 低版本的Jenkins的有些插件使用不了
    # jenkins/jenkins:lts-jdk17是长期支持版, jenkins/jenkins:jdk17是最新版
    image: jenkins/jenkins:jdk17
    container_name: jenkins
    ports:
      - 8080:8080 # WEB UI
      - 50000:50000
    volumes:
      # 将宿主机的Docker引擎挂载到Jenkins容器上,即Jenkins容器调用宿主机的Docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
      # 将宿主机的docker compose挂载到容器中
      - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
      # 让容器和宿主机时间保持一致
      - /etc/localtime:/etc/localtime
      # Jenkins工作存储位置/var/jenkins_home, 所有插件数据配置都在次目录下
      - /data/cicd/jenkins/jenkins_home:/var/jenkins_home
      # Docker打包Java涉及的Dockerfile, 镜像, docker compose命令的存储
      - /data/cicd/docker:/data/docker
    # 指定用户, 因为Jenkins镜像内部使用的用户是jenkins,但是我们启动容器时的账号是root,导致没有权限操作内部目录
    user: root
    networks:
      - cicd

初始化

配置镜像加速

启动容器后, 修改镜像源

sh 复制代码
vi /var/jenkins/jenkins_home/hudson.model.UpdateCenter.xml
xml 复制代码
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <!-- 华为镜像源 -->
    <url>https://mirrors.huaweicloud.com/jenkins/update-center.json</url>
  </site>
</sites>
登录Jenkins

查看初始化密码

sh 复制代码
docker logs jenkins

输入密码, 点击下一步

安装官方推荐插件

安装官方推荐插件

可能有部分安装失败(受网络, 墙, 数据源, 插件和Jenkins版本不匹配等原因限制), 可以尝试点多几次重试

继续下一步创建用户和配置Jenkins访问地址和端口, 然后进入Jenkins

安装JDK, Git, Maven, Publish over ssh, Gitee插件

JDK下载插件
Git
Maven Integration plugin
publish over shh
Gitee

安装JDK, Git, Maven

JDK

新版本Jenkins自带了JDK, 直接使用自带的JDK17

Git

新版本Jenkins自带了git, 配置路径即可

Maven

构建部署Java项目

新建Maven任务

新建任务->填写任务名称->选择maven项目->点击确定

填写描述

设置源码地址

根据官方提供的java demo项目地址: https://github.com/jenkins-docs/simple-java-maven-app

仓库地址(这个是github的镜像地址, gitcode提供的): https://gitcode.com/gh_mirrors/si/simple-java-maven-app.git

保存并构建

查看日志

发现日志构建成功

查看构建好的jar包

构建好的jar通常存放在包在**/var/jenkins_home/workspace/任务名/target**,

而我们通过docker方式启动并进行了数据卷挂载 我们可以在宿主机进行查看

sh 复制代码
cd /data/cicd/jenkins/jenkins_home/workspace/hello-word/target
ls

运行Jar包

这里演示的Jenkins服务器和项目运行服务器是同一个的情况

不同的情况后续说明

在官方提供的demo中,实际上仅控制台输出了 Hello World! 字符串

java -jar运行

进入容器

sh 复制代码
docker exec -it jenkins /bin/bash

容器中运行该命令

sh 复制代码
java -jar /var/jenkins_home/workspace/hello-word/target/my-app-1.0-SNAPSHOT.jar

发现确实输出了Hello World!

Docker打包镜像运行

宿主机执行一下创建文件夹命令

sh 复制代码
# Dockerfile存储地方
mkdir -p /data/cicd/docker/dockerFile
#docker-compose.yaml存储地方
mkdir -p /data/cicd/docker/compose_script
Dockerfile

宿主机中创建Dockerfile

sh 复制代码
vim /data/cicd/docker/dockerFile/Dockerfile
dockerfile 复制代码
FROM openjdk:17
# 设置工作目录
WORKDIR /data/app
# 将宿主机的目录挂载到容器的/app目录
VOLUME /data/app/data
# 复制.jar文件到工作目录
COPY my-app-1.0-SNAPSHOT.jar /data/app/my-app.jar
# 设置容器启动时执行的命令
CMD ["java", "-jar", "my-app.jar"]
docker-compose.yaml

宿主机创建docker-compose.yaml

sh 复制代码
vim /data/cicd/docker/compose_script/docker-compose.yaml
yaml 复制代码
version: "3.8"
services:
  my-app:
    image: my-app:v1
    container_name: my-app
构建镜像

进入容器中

sh 复制代码
docker exec -it jenkins /bin/bash

容器中执行构建镜像

sh 复制代码
# -f: 指定Dockerfile路径
# -t: 镜像的名字及标签, 通常 name:tag 或者 name 格式
# /var/jenkins_home/workspace/hello-word/target/: 相对路径
docker build -f /data/docker/dockerFile/Dockerfile --tag my-app:v1 /var/jenkins_home/workspace/hello-word/target/

如果宿主机中已经有OpenJDK17镜像, 那么就不会重新拉取, 如果没有, 那么此时拉取

博主这里已经有了JDK17镜像, 所以这里没有有拉去镜像的步骤

查看构建好的镜像

sh 复制代码
docker images my-app
运行镜像

启动my-app容器, 前台模式启动

sh 复制代码
docker-compose -f /data/docker/compose_script/docker-compose.yaml up
Jenkins自动部署

当构建成功后自动执行启动命令(这里以启动容器为例子)

Post steps -> 构建成功后执行 -> 执行shell

填写启动的shell命令

将之前构建容器, 启动容器等命令写入shell脚本中

sh 复制代码
# 使用docker ps和grep来检查容器是否存在
if docker-compose ps -a | grep "my-app" > /dev/null; then
    echo "容器存在"
    # 容器存在则停止并删除容器
    docker-compose -f /data/docker/compose_script/docker-compose.yaml down
    docker rm my-app:v1
else
    echo "容器不存在"
fi

# 构建镜像
docker build -f /data/docker/dockerFile/Dockerfile --tag my-app:v1 /var/jenkins_home/workspace/hello-word/target/
# 运行容器(后台启动, 和之前的前台启动不一样)
docker-compose -f /data/docker/compose_script/docker-compose.yaml up -d

重新构建, 并查看构建日志

查看容器日志

这里输出了几个Hello World!是因为博主启动了几次容器

拉取Gitee项目自动化部署

前提

  1. 有Gitee账户
  2. 会将SpringBoot项目推送到Gitee

创建SpringBoot项目

pom.xml
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.whiteBrocade</groupId>
    <artifactId>jenkins_demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jenkins_demo</name>
    <description>jenkins_demo</description>
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.whitebrocade.jenkins_demo.JenkinsDemoApplication</mainClass>
                    <skip>false</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

        <!-- 将根目录下的Dockerfile一并打包至target目录 -->

        <resources>
            <resource>
                <directory>${project.basedir}</directory>
                <targetPath>${project.build.directory}</targetPath>
                <includes>
                    <include>Dockerfile</include>
                </includes>
            </resource>
            <!-- maven默认会将资源目录下的资源文件进行打包, 而如果在pom.xml中配置了resources标签,
        则默认的资源打包策略就被覆盖掉了, 只会打包resources标签中配置的资源文件 -->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>

        </resources>
    </build>

    <!-- maven镜像源 -->
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

</project>
application.yaml
yaml 复制代码
# 应用服务 WEB 访问端口
server:
  port: 9999
TestController
java 复制代码
/**
 * @author whiteBrocade
 * @version 1.0
 */
@RestController
public class TestController {
    @GetMapping("/hello")
    public String hello(@RequestParam String name) {
        return "Hello " + name;
    }
}
Dockerfile
dockerfile 复制代码
# 用的是JDK17
FROM openjdk:17
LABEL authors="whiteBrocade"
# 设置工作目录
WORKDIR /data/app
# 将宿主机的目录挂载到容器的/app目录
VOLUME /data/app
# 复制.jar文件到工作目录
COPY jenkins_demo-0.0.1-SNAPSHOT.jar /data/app/jenkins_demo.jar
# 设置容器启动时执行的命令
CMD ["java", "-jar", "jenkins_demo.jar"]

提交代码到gitee中

Jenkins构建任务

创建Maven任务
设置源码地址
添加Post Steps

选择仅构建成功执行(Run only if build succeeds), 添加下边的shell脚本

sh 复制代码
# 默认操作在Jenkins工作目录下的项目名目录 即 workspace/jenkins-demo/target
cd target
# 构建镜像
docker build -t jenkins_demo . 
# 使用docker ps和grep来检查容器是否存在
if docker ps -a | grep "jenkins_demo" > /dev/null; then
    echo "容器存在"
    # 容器存在则停止并删除容器
    docker stop jenkins_demo
    docker rm jenkins_demo
else
    echo "容器不存在"
fi
# 运行容器
docker run -d -p 9999:9999 --name jenkins_demo jenkins_demo
保存并构建

保存后, 点击构建, 如下图, 构建成功

查看容器是否启动

访问项目

http://192.168.132.10:9999?hello=whiteBrocade

Gitee的WeHhooks触发自动构建

WebHooks介绍

WebHooks是一种基于HTTP协议的回调机制。当特定事件(如代码推送、Pull Request等)发生时,源系统会向预先配置的URL发送一个HTTP请求,以通知目标系统进行相应的操作。在CI/CD流程中,WebHooks常用于触发Jenkins构建任务

添加Gitee凭证

系统管理 的中配置Gitee令牌(令牌申请点击Gitee私人令牌)

添加触发器

选择之前的jenkins_demo构建任务, 点击Triggers

触发策略为

  • Push: 仓库推送代码, 推送/删除分支
  • Pull Request: 新建, 更新, 合并

生成随机密码, 这里的随机密码后续要复制到Gitee中的WebHooks中

Gitee添加WebHooksp

Gitee ->自己的jenkins_demo仓库 -> 管理 -> WebHooks -> 添加webHook

从Jenkins中获取URL

添加WebHooks

将刚刚的URL复制过来, 这里需要内网穿透, 详细请看内网穿透工具章节

修改代码并提交

触发自动构建了

访问新增的接口

远程推送和自动部署

Publish Over SSH配置SSH Servers

如果没有安装Publish Over SSH, 那么先安装

系统管理 -> 系统配置 -> Publish over SSH, 添加SSH Servers

添加推送

清空Post Steps

由于之前配置一个Post Steps会影响后续流程, 这里清空, 确保这个构建任务没有Post Steps

Post Steps添加步骤

注意事项

  • Jenkins会默认找到任务的工作目录, 这里就是/var/jenkins/jenkins_home/workspace/jenkins_demo
  • Source files可以传递多个文件, 文件通过英文逗号间隔

sh脚本

sh 复制代码
cd /data/storage
# 构建镜像
docker build -t jenkins_demo . 
# 使用docker ps和grep来检查容器是否存在
if docker ps -a | grep "jenkins_demo" > /dev/null; then
    echo "容器存在"
    # 容器存在则停止并删除容器
    docker stop jenkins_demo
    docker rm jenkins_demo
else
    echo "容器不存在"
fi
# 运行容器
docker run -d -p 9999:9999 --name jenkins_demo jenkins_demo

构建项目

效果

查看容器

进入192.168.132.11主机

查看容器

测试请求

访问http://192.168.132.11:9999/hello?whiteBrocade

内网穿透工具

  • natapp实现内网穿透

  • neutrino-proxy没有实现

natapp

这个免费的隧道过一段时间会失效, 所以有时候不行的话, 可以重新启动一个natapp, 用新分配的地址重新配置一个WebHooks

  1. 下载[NATAPP]客户端(https://natapp.cn/#download)
  2. 进入NATAPP注册
  3. 选择免费隧道
  1. 点击免费购买
  1. 复制authtoken
  1. 修改本机地址为VM内网地址
  1. natapp.exe同级目录下新建config.ini

    #将本文件放置于natapp同级目录 程序将读取 [default] 段
    #在命令行参数模式如 natapp -authtoken=xxx 等相同参数将会覆盖掉此配置
    #命令行参数 -config= 可以指定任意config.ini文件
    [default]
    authtoken=3xxxxxxxxxxx3 #对应一条隧道的authtoken
    clienttoken= #对应客户端的clienttoken,将会忽略authtoken,若无请留空,
    log=none #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none
    loglevel=ERROR #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG
    http_proxy= #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空

  1. 点击natapp.exe启动

neutrino-proxy

启动服务端
配置
创建文件夹
sh 复制代码
# 服务端
# 配置
mkdir -p /data/neutrino-proxy/server/config
# 运行数据
mkdir -p /data/neutrino-proxy/server/data
# 日志
mkdir -p /data/neutrino-proxy/server/logs
服务端app.yml

创建app.yml配置

sh 复制代码
vim /data/neutrino-proxy/server/config/app.yml
yaml 复制代码
server:
  # 服务端web端口,用于支持HTTP接口,管理后台页面访问
  port: 8888
# 日志级别
solon.logging:
  logger:
    "root":
      level: info
  appender:
    file:
      level: info

neutrino:
  proxy:
    # 隧道相关配置-用于维持服务端与客户端的通信
    tunnel:
      # 线程池相关配置,用于技术调优,可忽略
      boss-thread-count: 2
      work-thread-count: 10
      # 隧道非SSL端口
      port: 9000
      # 隧道SSL端口
      ssl-port: 9002
      # 隧道SSL证书配置
      key-store-password: 123456
      key-manager-password: 123456
      jks-path: classpath:/test.jks
      # 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
      transfer-log-enable: false
      # 是否开启心跳日志
      heartbeat-log-enable: false
    server:
      tcp:
        # 线程池相关配置,用于技术调优,可忽略
        boss-thread-count: 5
        work-thread-count: 20
        # http代理端口,默认80(不配置不支持)
        http-proxy-port: 80
        # https代理端口,默认443 (不配置不支持,同时需要配置域名、证书)
        https-proxy-port: 443
        # 是否开启代理服务报文日志(日志级别为debug时开启才有效)
        transfer-log-enable: false
      udp:
        # 线程池相关配置,用于技术调优,可忽略
        boss-thread-count: 5
        work-thread-count: 20
        # 是否开启代理服务报文日志(日志级别为debug时开启才有效)
        transfer-log-enable: false
  data:
    db:
      # 数据库类型,目前支持h2、mysql、mariadb
      type: h2
      # 数据库连接URL
      url: jdbc:h2:file:./data/db;MODE=MySQL;AUTO_SERVER=TRUE
      # 数据库用户名
      username:
      # 数据库密码
      password:
docker-compose.yaml
yaml 复制代码
version: '3.8'

networks:
  npServer:
    driver: bridge
services:
  # 服务端
  npServer:
    image: aoshiguchen/neutrino-proxy-server:latest
    container_name: npServer
    hostname: npServer
    restart: always
    environment:
        TZ: Asia/Shanghai
        LANG: zh_CN.UTF-8
    volumes:
      - /data/neutrino-proxy/server/config:/root/neutrino-proxy/config
      - /data/neutrino-proxy/server/data:/root/neutrino-proxy/data
      - /data/neutrino-proxy/server/logs:/root/neutrino-proxy/logs
    ports:
      - "8888:8888"
      - "9000:9000"
      - "9002:9002"
      - "9101-9120:9101-9120"
    networks:
      - npServer
设置内网穿透
访问首页

http://192.168.132.10:8888/

账号: admin

密码: 123456

添加License

添加一个专门用于jenkins回调穿透用的License

添加端口映射
启动客户端
配置
创建文件夹
sh 复制代码
# 客户端
# 配置
mkdir -p /data/neutrino-proxy/client/config
# 日志
mkdir -p /data/neutrino-proxy/client/logs
客户端app.yml
sh 复制代码
vim /data/neutrino-proxy/client/config/app.yml

下边有两个地方需要修改

  1. server-ip改成自己的本机的公网地址
  2. license-key改成后台配置的jenkins_demo的license
yaml 复制代码
solon.logging.logger:
  "root":
    level: info

neutrino:
  proxy:
    tunnel:
      # 线程池相关配置,用于技术调优,可忽略
      thread-count: 50
      # 隧道SSL证书配置
      key-store-password: 123456
      jks-path: classpath:/test.jks
      # 服务端IP(自己的公网IP)
      server-ip: xxx.xxx.xxx.xxx
      # 服务端端口(对应服务端app.yml中的tunnel.port、tunnel.ssl-port)
      server-port: 9002
      # 是否启用SSL(注意:该配置必须和server-port对应上)
      ssl-enable: true
      # 客户端连接唯一凭证(这里修改成服务端配置的Jenkins_demo的lin)
      license-key: xxxxxx
      # 客户端唯一身份标识(可忽略,若不设置首次启动会自动生成)
      client-id:
      # 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
      transfer-log-enable: false
      # 是否开启心跳日志
      heartbeat-log-enable: false
      # 重连设置
      reconnection:
        # 重连间隔(秒)
        interval-seconds: 10
        # 是否开启无限重连(未开启时,客户端license不合法会自动停止应用,开启了则不会,请谨慎开启)
        unlimited: false
    client:
      udp:
        # 线程池相关配置,用于技术调优,可忽略
        boss-thread-count: 5
        work-thread-count: 20
        # udp傀儡端口范围
        puppet-port-range: 10000-10500
        # 是否开启隧道传输报文日志(日志级别为debug时开启才有效)
        transfer-log-enable: false
docker-compose.yaml
yaml 复制代码
version: '3.8'

networks:
  npClient:
    driver: bridge
services:
  npClient:
    image: aoshiguchen/neutrino-proxy-client:latest
    container_name: npClient
    hostname: npClient
    restart: always
    environment:
        TZ: Asia/Shanghai
        LANG: zh_CN.UTF-8
    volumes:
      - /data/neutrino-proxy/client/config:/root/neutrino-proxy/config
      - /data/neutrino-proxy/client/logs:/root/neutrino-proxy/logs
    ports:
      - "10000-10500:10000-10500/udp"
    networks:
      - npClient

参考

Jenkins中文官网

Docker安装Jenkins

Jenkins+Docker 实现一键自动化部署项目!步骤齐全,少走坑路

Docker 快速安装Jenkins完美教程 (亲测采坑后详细步骤)

【Jenkins】之配置国内镜像加速

Jenkins安装插件提速

实战指南:使用Docker安装Jenkins并结合Buildx构建跨平台镜像

Index of jenkins-local

Jenkins首次安装选择推荐插件时出现": No such plugin: cloudbees-folder" 解决方案

Jenkins首次安装推荐插件出错 No such plugin: cloudbees-folder 超详细解决方案

Index of /jenkins/plugins/cloudbees-folder/latest/r

jenkins安装,打包,部署java项目_jenkins打包,发布,部署

更换 Jenkins 插件下载源(解决 Jenkins 插件安装失败)【图文详细教程】

jenkins安装,打包,部署java项目

Jenkins之java代码上线

Jenkins+Gitee 的Java项目提交自动部署

Jenkins查看版本

24年最新 Docker安装jenkins并发布服务器,配置环境,最全,已成功验证

Jenkins_Micro麦可乐的博客

Docker 安装 Jenkins-jdk17

内网穿透工具neutrino-proxy

内网穿透Neutrino-Proxy的安装部署和使用

Linux搭建NeutrinoProxy(中微子代理) 内网穿透教程

【从0开始搭建内网穿透】开源内网穿透神器

开源内网穿透神器,中微子代理(NeutrinoProxy)2.0.0重磅发布

内网穿透神器 NeutrinoProxy 1.8.0 版本发布

linux 获取公网 IP 方法

iP地址查询--手机号码查询归属地 | 邮政编码查询 | iP地址归属地查询 | 身份证号码验证在线查询网

jenkins自动部署代码到多台服务器

使用docker build命令构建镜像时遇到警告信息 The legacy builder is deprecated and will be removed in a future release

关于maven打包时, 资源文件没有被打包进来的问题

gitee使用webhoot触发Jenkins自动构建

jenkins使用gitee插件自动部署webhook404问题记录

GitEE提交代码自动构建Jenkins项目

jenkins自动化部署构建后Publish Over SSH失败问题解决办法

jenkins报错code记录

解决 jenkins exit status not zero error (status code 125)

相关推荐
多多*21 分钟前
Java设计模式 简单工厂模式 工厂方法模式 抽象工厂模式 模版工厂模式 模式对比
java·linux·运维·服务器·stm32·单片机·嵌入式硬件
南鸳6102 小时前
Linux常见操作命令(2)
linux·运维·服务器
Kaede62 小时前
怎么安装JSON服务器?JSON服务器最新安装教程
运维·服务器·json
西北大程序猿3 小时前
linux进程信号 ─── linux第27课
linux·运维·服务器·信号处理
inxunoffice3 小时前
批量给 PDF 添加或删除密码保护,支持设置打开密码、只读密码、限制复制和打印
运维·服务器·pdf
Brandon汐6 小时前
Linux中常用的文件管理命令
linux·运维·服务器
Vacancy空白7 小时前
【Ubuntu常用命令】
linux·运维·ubuntu·ssh
老天文学家了7 小时前
课表周视图数据【示例】
linux·运维·服务器
爪娃侠7 小时前
解决wsl2下CentOS 7 的 yum 仓库无法连接问题
linux·运维·centos
fengyehongWorld7 小时前
Linux 随机数据生成
linux·运维