安装Jenkins

准备工作

  • 安装MavenPusher Over SSHSSH server插件,后重启jenkins生效
  • 配置jenkins连接到服务器
    • 系统管理 –> 系统配置 –> Publish over SSH –> SSH Servers
      • Name: 易读的主机名
      • Hostname: 服务器IP
      • Username: 登录服务器账号
      • Remote Directory: 项目存放目录
      • 高级
        • [√] Use password authentication, or use a different key
          • 配置服务器密码,或者免密登录(提前配置好Jenkins服务器免密登录到目标机器)
          • Path to key 或者 Key(私钥) 二选一

构建maven项目方式

  • 任务名称:一般命名为 环境 + 项目名称

  • 源码管理:连接项目地址

    • Git
      • Repository URL: 项目地址(Gitlab仓库地址)
      • Credentials: 有权限的Gitlab账号密码,或者证书
      • Branches to build
        • */master
  • 构建环境

  • [√] Send files or execute commands over SSH after the build runs

    • SSH Publishers

      • Name: 选择刚刚配置的服务器
    • Transfers

      • Source files:打包后的jar包路径(基于Jenkins的工作目录)

        target/xxx.jar

      • Remove prefix:移除target目录前缀

        target

      • Remote directory:将jar上传到远程服务器的路径

        /data/java/

      • Exec command:将jar包上传到服务器之后执行的脚本

    sh /data/java/run_build.sh

  • Pre Steps

    • Maven Version

      全局配置的maven

  • Build

    • Root POM

      pom.xml

    • Goals and options

      clean install

    • MAVEN_OPTS(可选)

    -DskipTests -Dmaven.test.skip=true

    • [√] Enable triggering of downstream projects

      • [√] Block downstream trigger when building
  • Post Steps

    • Run regardless of build result
    • 执行 shell

      run_build.sh

Run build方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# cat run_build.sh
#!/bin/bash
# Des: Deploy and build Java containers
# -->> modify here to start <<--
app_dir=/data/java
group_name='rat'
app_name='rat-api'
app_port='10040'
app_version='1.0.jar'
profile_active='prod' # test| dev| prod
# -->> modify here to end <<--

# 清理旧容器,如果存在
if [ docker inspect ${app_name} &>/dev/null ];then
# 停止旧容器
echo '--->>>stop container<<<---'
docker stop ${app_name}

# 删除容器
echo '--->>>rm container<<<---'
docker rm ${app_name}

# 删除镜像
echo '--->>>rm image<<<---'
docker rmi ${group_name}/${app_name}:${app_version}
fi

# 构建新版镜像
echo '--->>build image<<---'
cd ${app_dir} # jar上传到服务器的路径
docker build -t ${group_name}/${app_name}:${app_version} .

# 启动Docker镜像
echo '--->>start container<<---'
docker run \
--name ${app_name} \
-p ${app_port}:10040 \
-e 'spring.profiles.active'=${profile_active} \
-e /etc/localtime:/etc/localtime:ro \
-d ${group_name}/${app_name}:${app_version}

log_time=$(date '+%F %T.%N' |cut -c -23)
if [ $? -ne 0 ];then
echo "$(log_time) [Warning] Project ${app_name} failed to start."; exit 1
fi
echo "$(log_time) [Info] Project ${app_name} started successfully."
# cat Dockerfile
FROM java:8

ADD rat-api-1.0.jar /app.jar
RUN bash -c 'touch /app.jar'

ENTRYPOINT ["java", "-jar","/app.jar"]

构建流水线方式

安装 Pipeline 插件

Manage Jenkins -> Manage Plugins -> 可选插件 -> Pipeline

创建流水线

  • 配置构建
    • 参数化构建,根据分支拉取代码

    • 名称

      branch

    • 默认值

      master

    • 描述

      输入分支名称

    • 流水线

    • 定义

      Pipeline script from SCM

      • SCM

        Git

        • Repository URL

          git@xxx:xxx/xxx.git

        • Credentials

          root(gitlab-auth)

        • Branches to build

          */master

        • 脚本路径

          Jenkinsfile

创建Jenkinsfile文件

在项目根目录创建Jenkinsfile文件,编写流水线脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pipeline {
agent any

options {
timeout(time: 1, unit: 'HOURS')
}

stages {
stage('拉取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '32d07987-5509', url: 'http://192.168.5.111:80/gitee/xx/xx/cabast']]])
echo '拉取代码成功'
}
}
}

}

Jenkinsfile中需提前配置好Git仓库地址相关凭证

验证构建

运行构建,可成功拉取代码即可

构建镜像

使用Dockerfile编译、生成镜像

流程:把Java项目打包成JAR包后在Dockerfile使用ADD命令把JAR文件放到镜像里,启动命令设置执行这个JAR文件即可

  • 将 ADD rat-api-1.0.jar 改成实际的jar包名
1
2
3
4
# cat Dockerfile
FROM openjdk:8-jre
ADD target/*.jar /application.jar
ENTRYPOINT ["java", "-jar","/application.jar"]
使用dockerfile-maven-plugin插件
  • 1.修改微服务项目根目录的pom.xml文件中加入dockerfile-maven-plugin插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!--  other  -->
<!-- dockerfile-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.7</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
<!-- other -->
  • 2.在微服务项目根目录下创建Dockerfile文件,注意修改端口
1
2
3
4
5
6
FROM openjdk:8-jdk-alpine
EXPOSE 8082
ARG JAR_FILE
ADD target/${JAR_FILE} /app.jar
ENTRYPOINT ["java", "-jar","/app.jar"]
# ${JAR_FILE} 这个参数是从pox.xml 文件中传过来的,名称必须一致才行。
  • 3.在微服务项目根目录下创建Jenkinsfile构建脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pipeline {
agent any

options {
timeout(time: 1, unit: 'HOURS')
}

stages {
stage('拉取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '32d079875509', url: 'http://192.168.5.111:80/gitee/xx/xx/cabast']]])
echo '拉取代码成功'
}
}

stage('编译打包成镜像') {
steps {
//sh "mvn -f ${project_name} clean package" //暂不用这种,如果多个微服务,多个pom工程可以参数化构建的时候指定对应项目。
sh "mvn -e clean package dockerfile:build"
echo "编译成功"
}
}
}

}

Jenkinsfile内容,根据配置的增加而更新

将镜像上传到Harbor仓库

  • Jenkins生成harbor账号凭据
    • 全局凭据 –> 新增Harbor服务器凭据
  • 生成凭证脚本代码
    • withCredentials: Build credentials to variables
  • 更新Jenkinsfile文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
pipeline {
agent any

options {
timeout(time: 1, unit: 'HOURS')
}

environment{
jar_file_name="test"
tag="1.0.0"
def imagename ="${jar_file_name}:${tag}"

DT="`date +%m%d%H%M`"
newimagename="cn.keyi/dwq"

def newtag ="v${DT}"
harbor_url="192.168.108.5:85"
harbor_project_name="project_dwq"
port=8082

}

stages {
stage('拉取代码') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '32d07987-5509', url: 'http://192.168.5.111:80/gitee/xx/xx/cabast']]])
echo '拉取代码成功'
}
}

stage('编译打包成镜像') {
steps {
//sh "mvn -f ${project_name} clean package" //暂不用这种,如果多个微服务,多个pom工程可以参数化构建的时候指定对应项目。
sh "mvn -e clean package dockerfile:build"
echo "编译成功"
}
}

stage('镜像打标签并上传') {
steps {
//对镜像打上标签
sh "docker tag ${imagename} ${harbor_url}/${harbor_project_name}/${newimagename}:${newtag}"

//上传镜像的前提需要登录对应镜像仓库,登录仓库需要先绑定账号和凭据
withCredentials([usernamePassword(credentialsId: '42521--69904', passwordVariable: 'Din1', usernameVariable: 'dwqn')]) {
//登录镜像仓库
sh "docker login ${harbor_url} -u ${dqin} -p ${Dadn1}"
echo "harbor 登录成功"

//推送镜像
sh "docker push ${harbor_url}/${harbor_project_name}/${newimagename}:${newtag}"
echo "上传完成"
}
}

stage('上传完成后删除本地镜像') {
steps {
sh "docker rmi -f ${newimagename}"
sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${newimagename}:${newtag}"
echo "删除成功"
}
}

}

}

推送镜像前先需要对镜像打标签(第42行)
需要Jenkins登录到harbor(第47行)
登录前先需要绑定凭据(第45行),绑定凭据这行代码可以在流水线语法生成器中生成。

  • Jenkins配置,将Harbor的访问地址加入到信任列表
1
2
# vim /etc/docker/daemon.json
"insecure-registries": ["192.168.111.136:8081"],
  • Jenkinsfile打标签和推送命令
1
2
3
4
5
6
7
8
9
# 给镜像打标签
docker tag test:1.0.0 192.168.111.136:8081/poject_name/test:v1
# test:1.0.0 这个是编译完后打包出来的默认镜像名
# poject_name 这个是harbor配置完后,创建的空间名称,需要提前配置和harbor
# test:v1 这个是打完标签后显示的镜像名称,可以自定义。


# 推送镜像(上传)
docker push 192.168.111.136:8081/poject_name/test/test:v1