Jenkins使用问题记录

版权声明:发扬开源精神,欢迎大家转载对自己有用的文章(●'◡'●) https://blog.csdn.net/jacksonary/article/details/84943777

1. 启动

使用Jenkins的版本为2.138.3,下载war包后启动即可运行:

# 指定使用8080端口,可自定义
java -jar jenkins.war --httpPort=8080

建议后台启动,命令如下:

# 1. 启动
# 指定后台启动
nohup java -jar jenkins.war --httpPort=8080 &
# 再指定日志路径
appending output to nohup.out

# 2. 停止
# 查看进程号
jobs -l
# 杀死
kill -9 进程号

默认使用Jenkins内置的Jetty,也可以根据自己需求放入其他的Servlet容器(如Tomcat)中。启动后,它会给一个初始密码,访问jenkins需要这个密码,访问后安装社区推荐的插件,最好修改一下密码;

注:我这边Jenkins的war包是直接放在/root/jenkins目录下的,默认Jenkins构建的工作区在/root/.jenkins/workspace目录下,相对配置文件也都在/root/.jenkins目录下,必要时可以查看。

2. “构建”模块中没有“Maven Version”选项

 在构建时,控制台出现如下的报错信息:

[my-jenkins] $ mvn -f SpringData/pom.xml -s /usr/local/apache-maven-3.6.0/conf/settings.xml -gs /usr/local/apache-maven-3.6.0/conf/settings.xml clean package -Dmaven.test.skip=true
FATAL: 命令执行失败
java.io.IOException: error=2, 没有那个文件或目录
	at java.lang.UNIXProcess.forkAndExec(Native Method)
	at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
	at java.lang.ProcessImpl.start(ProcessImpl.java:134)
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
Caused: java.io.IOException: Cannot run program "mvn" (in directory "/root/.jenkins/workspace/my-jenkins"): error=2, 没有那个文件或目录
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
	at hudson.Proc$LocalProc.<init>(Proc.java:249)
	at hudson.Proc$LocalProc.<init>(Proc.java:218)
	at hudson.Launcher$LocalLauncher.launch(Launcher.java:935)
	at hudson.Launcher$ProcStarter.start(Launcher.java:454)
	at hudson.Launcher$ProcStarter.join(Launcher.java:465)
	at hudson.tasks.Maven.perform(Maven.java:367)
	at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
	at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
	at hudson.model.Build$BuildExecution.build(Build.java:206)
	at hudson.model.Build$BuildExecution.doRun(Build.java:163)
	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:504)
	at hudson.model.Run.execute(Run.java:1819)
	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
	at hudson.model.ResourceController.execute(ResourceController.java:97)
	at hudson.model.Executor.run(Executor.java:429)
Build step '调用顶层 Maven 目标' marked build as failure
SSH: Current build result is [FAILURE], not going to run.
Finished: FAILURE

尝试解决:到/root/.jenkins/workspace中任务下的模块中的target目录下,发现确实没有jar包,定位到maven出现问题,配置没有生效。

解决方案:在配置任务时,选择“调用顶层Maven目标”,发现没有“Maven版本”(或Maven version)这个选项,系统管理–>全局工具配置–>Maven–>点击“Maven安装”–>将“自动安装”选项改为非选中状态–>填写Maven的NameMAVEN_HOME保存,最后回到任务配置中查看,即可出现“Maven版本这个选项”,然后选择刚刚填写的Maven别名再次构建即可。

3. 构建时提示没有Java环境

 在解决了上述问题后,尝试进行构建,控制台又出现下面的异常信息:

[my-jenkins] $ /root/.jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven-3.6.0/bin/mvn -f SpringData/pom.xml -s /usr/local/apache-maven-3.6.0/conf/settings.xml -gs /usr/local/apache-maven-3.6.0/conf/settings.xml clean package -Dmaven.test.skip=true
which: no java in (/root/.jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven-3.6.0/bin:/bin:/bin:/root/apache-maven-3.6.0//bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
The JAVA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
NB: JAVA_HOME should point to a JDK not a JRE

根据信息提示是没有JDK,或者是错误的将JAVA_HOME设置成了JRE目录而非JDK目录,检验虚拟机环境,正常配置,系统可以识别javajavac命令,郁闷中。

解决方案:Jenkins不能识别自动找到JDK的目录,需要手动配置,进入系统管理–>全局工具配置,进行如下操作:

配置Jenkins中JDK路径

再次构建,操作成功。

注:这里提一点JDK和JRE的概念区别,妈的,以前学java没搞那么多,也知道java是用于运行jav程序的命令,javac是用于编译java程序的,简单的说JRE是java的运行环境,而JDK是包含了java编译和运行的环境,即它们都包含java的运行环境JRE,至于编译环境只有JDK才会提供,所以现在JDK和JRE的概念应该会分的很清楚。

4. 通过SSH上传到远程部署机器

 具体任务配置的时候有多个地方可以配置,建议在Build Environment中勾选Send files or execute commands over SSH after the build runs进行SSH上传的具体配置:

在这里插入图片描述

注:使用这个插件上传的前提是首先将jenkins所在机器和远程部署机器之间配置好SSH免密登录(将jenkins所在机器的公钥追加到远程部署机器上的authorized_keys文件中即可)

4.1 配置SSH

 远程部署:简单点说就是,在机器A上打包好了之后,将jar包上传到机器B上,这里使用的SSH Server,所以在Jenkins上首先需要安装“publish over ssh”插件,重启即可(前提是两台机器已经配置了SSH登录),关于通过SSH将打包好的jar包上传到SSH Server时的具体配置如下:

系统管理–>全局设置–>Publish over SSH填写相关信息即可:

SSH配置

注:上述配置SSH Server时如果填写远程机器的登录密码(即这里的Passphrase),那么在上传时,只能通过执行Shell命令来远程复制;建议直接填写主机私钥文件的位置Path to key(正常为/root/.ssh/id_rsa),不要填写Passphrase,然后通过插件直接帮我们复制即可,不需要再写shell命令,在具体任务配置Send build artifacts over SSH时,只需要填写Name、Source files(Transfers)、Exec command(Transfers)这三项即可,不要作死去点“高级”勾选里面的选项(除Verbose output in console,勾选这个可以打印SSH操作日志)。

4.2 编码问题

 在构建完后推送到SSH Server时,出现诡异字符bash^M,具体如下:

编译报错

原因:原来的重启shell脚本太长,为了方便我直接在windows环境下更改过内容,编码有问题导致shell脚本执行错误,可以用vi或vim打开文本时进行验证,使用:set ff?命令查看文本类型,如果结果为fileformat=dos那就是windows平台创建的文件;

解决方案:如果为fileformat=dos继续执行:set ff=unix修改,然后保存退出即可,或者直接将原文件删除,在Linux中直接使用重新创建;

4.3 远程机器上目标目录中没有上传的文件

 这个问题就有点坑了,原来配置SSH Server中Transfers选项的时候,里面的源文件位置“Source files: ”我写的是/root/.jenkins/workspace/my-jenkins/SpringData/target/springdata-1.0-SNAPSHOT.jar,然后勾选“Verbose output in console”查看SSH上传的日志,发现如下输出:

SSH: Connecting from host [localhost.localdomain]
SSH: Connecting with configuration [jenkins-test] ...
SSH: Creating session: username [root], hostname [10.4.37.124], port [22]
SSH: Connecting session ...
SSH: Connected
SSH: Opening SFTP channel ...
SSH: SFTP channel open
SSH: Connecting SFTP channel ...
SSH: Connected
SSH: cd [/usr/local/test]
SSH: OK
SSH: Opening exec channel ...
SSH: EXEC: channel open
SSH: EXEC: STDOUT/STDERR from command [/usr/local/java/jdk1.8.0_191/bin/javac /usr/local/test/Hello.java] ...
SSH: EXEC: connected
SSH: EXEC: completed after 801 ms
SSH: Disconnecting configuration [jenkins-test] ...
SSH: Transferred 0 file(s)

发现SSH是连接成功的,但是在远程复制的时候发现只有cd(即进入远程机器的指定目录),并没有将文件放进目标目录(即没有put操作)中,而且最后一行Transferred 0 file(s)也告诉我们确实是没有上传文件,考虑是源文件路径写法有问题,查找官方文档,有如下的举例说明:

*可以匹配0个或多个字符,比如*.java可以匹配.javax.javaFooBar.java但不包括FooBar.xml(即不匹配任何不以.java结尾的字符串);

?可以仅且可以匹配1个字符,比如x.javaA.java,但不能匹配.javaxyz.java

**可以匹配多级路径,比如/test/**可以匹配所有test目录下的文件或目录,比如/test/x.java/test/foo/bar/xyz.html……需要注意的是,如果一个字符串以\/结尾,那么自动在其后面追加**,比如mypackage/test/实际就是mypackage/test/**,可以认为是一种缩写;

对于Transfers中整体的配置有如下栗子:

栗子1 Transfer directory

Source files: target/classes/**/*
Remove prefix:
Remote directory:

结果:

target/classes/my/code/HelloWorld.class
target/classes/my/code/HelloWorldImpl.class
target/classes/my/code/Main.class

栗子2 Remove prefix

Source files: target/classes/
Remove prefix: target
Remote directory:

结果:

classes/my/code/HelloWorld.class
classes/my/code/HelloWorldImpl.class
classes/my/code/Main.class
target/classes/ == target/classes/** == target/classes/**/*

栗子3 Environment variables

为了传输一个目录下的所有文件和文件夹,并将它们放在一个名字为工作目录的目录下(下面栗子中给的job名字为Hello World),然后构建数字(不懂):

Source files: target/classes/
Remove prefix: target/classes
Remote directory: $JOB_NAME/$BUILD_NUMBER

结果:

Hello World/99/my/code/HelloWorld.class
Hello World/99/my/code/HelloWorldImpl.class
Hello World/99/my/code/Main.class

栗子4 Transfer .class files

Source files: target/**/*.class
Remove prefix: target
Remote directory:

结果:

classes/my/code/HelloWorld.class
classes/my/code/HelloWorldImpl.class
classes/my/code/Main.class
test-classes/my/code/HelloWorldImplTest.class

栗子5 Transfer files with flatten

Source files: **/*.java
Remove prefix:
Remote directory: /java

结果:

java/HelloWorld.java
java/HelloWorldImpl.java
java/Main.java
java/HelloWorldImplTest.java

栗子6 Remote directory是日期格式的

Source files: target/**/*.jar
Remove prefix:
Remote directory: 'builds/'yyyy/MM/dd/‘build-$BUILD_NUMBER’
Flatten files: checked
Remote directory: is a date format checked

结果:

builds/2010/11/07/build-99/hello-world.jar

注意:The whole of Remote directory is quoted appart from the date tokens and the separators (which are not letters)

看完上述的内容,琢磨着Source files应该是填项目的相对路径(支持字符串匹配),不能填绝对路径,有点奇葩,我这里项目有点乱,具体目录结构见CodeRepository(其实这个项目我是把他作为一个代码分享仓库,并不是正规的项目结构形式),然后我要构建的是里面SpringData项目,maven构建后的jar的位置为SpringData/target/springdata-1.0-SNAPSHOT.jar,所以Source files应该填写SpringData/target/springdata-1.0-SNAPSHOT.jar,这里有一点需要说明的是如果只是这样,那么传输到远程部署机器上的将会保持源文件的目录结构,即在目标目录中依次创建SpringDatatarget文件夹,然后再将springdata-1.0-SNAPSHOT.jar放进去,但正常我是不需要这样的目录结构的,我只需要把jar包传输过去就行了,所以这时就可以利用Remove prefix将上述外面包裹的两层文件夹去除,直接传输jar包,如下:

在这里插入图片描述

最终构建后,可以发现在远程机器中的/usr/local/test目录中只用一个jar包,很舒服!

注:这里除了这种做法外,还可以使用下面一种很搓的方式。在配置好了SSH Server后,写远程复制命令,如下:

SSH上传

注:本地复制命令命令为cp file1 file2,相应的SSH远程复制命令:scp local_file remote_username@remote_ip:remote_file,手动写scp远程复制命令,但不建议这么干。

5 远程机器无法执行上传的jar包

 这个问题其实很脑残,在执行的时候提示我“没有这个目录”,然后检查的时候发现,SSH Server上没有JDK,当时也没反应过来,后来一想也是,你上面都没有java环境怎么运行jar程序,对吧,所以也安装一下JDK即可,安装好了之后,发现无法识别java命令(环境已配置),最后发现必须使用绝对绝对路径,如下:

# 两者都要指定绝对路径
/usr/local/java/jdk1.8.0_191/bin/java -jar /usr/local/test/hello.jar

猜你喜欢

转载自blog.csdn.net/jacksonary/article/details/84943777