Jenkins所遇报错汇总及解决
# 1,前言
报错!是运维工作中不可豁免的一个问题。 出问题,就应是运维工作应该避免的问题。
我们有理由相信,运维的能力,就是解决问题的能力。
而有趣的是我们解决问题的能力的提升又有赖于问题的解决,如果平常连问题都无从解决,那么也毋谈能力的提升了。
我想到自己遇到问题的时各方求索无果的时候,一方面想骂一句网上的教程都是坑,但是到最后自己的答案还是需要去网上来找。事实就是如此荒唐。不知道别人提倡的理念是什么,总之我觉得,遇到问题,一定要去请教,如果自己死扣,浪费时间不说,还做了很多无用功,请教之后学会了,记住了,就变成自己的了。
鉴于此,个人打算专门开一篇文章收录Jenkins使用过程中遇到的报错,异常,问题等。
简单说明:
# 1,收集的问题皆是我所见到的,以及我所解决的。
说白了就是每个人遇到的问题可能不同,或者遇到同一个问题的原因也可能是不同的,那么我这里所给出的解决办法可能只适用于我所遇到的情况,不一定具有万能性。
# 2,我会尽量将问题重现,说明,解决。
我会尽自己能尽量将问题重现一下,把出现此问题的可能性给出来,解决的思路以及办法也都毫不保留的倾囊相述,如果那些地方是有毛病的,欢迎评论区指出,让此文章真正成为一个可以帮人解决燃眉之急的“及时雨”。
# 3,如果有问题,可与我联系。
每个人都是在不断学习当中成长的,我也一样,如果在某些地方有疑问,或者搞不懂,欢迎通过主页的qq或者微信与我联系。
# 4,本文会持续性更新。
本文将会在相当长的一段时间里,不断更新与补充,尽量将其完善成为一个问题解决小手册。
很早前,我每天都被深刻灌输以及践行“帮助别人,成就自己”的口号。现在,这句话仍旧被我传承发扬着。
技术人有一个很奇怪的癖好就是“敝帚自珍”(讽刺之意),总愿意把自己的那些或是很差的或是很好的东西保存,收藏,自用。这是一种很奇怪的癖好,一点也不好。
ok,接下来,开始表演。
表演之前仍旧先来个小福利缓解一下因为报错而受扰的心情。
# 2,忘记管理员密码怎么办。
平常我们都是通过普通用户来对Jenkins进行管理,配置,发布等操作,但是如果某天需要管理员的用户密码,而这个大家并不常用的密码,也就被遗忘到了九霄云外,这个时候该怎么办呢,有两种办法可以找回。
具体操作参考我的另外一篇,Jenkins忘记管理员密码怎么办。Jenkins实战应用–Jenkins忘记管理员密码怎么办 (opens new window)。
# 3,配置Git连接时报错怎么办。
有不少人在刚开始入门Jenkins的时候都会遇到与Git连接的问题,其实这里的问题并不复杂,只不过对其两者之间的关系不大清晰,因此才觉得一头雾水。
报错内容无非如下两种:
1,URL开头是http的报错。
Failed to connect to repository : Command “git ls-remote -h http://192.168.96.23/root/testa.git HEAD” returned status code 128:
stdout:
stderr: error: The requested URL returned error: 401 Unauthorized while accessing http://192.168.96.23/root/testa.git/info/refs
fatal: HTTP request failed
2
3
4
5
6
7
2,URL开头是git的报错。
Failed to connect to repository : Command “git ls-remote -h [git@192.168.96.23](mailto:git@192.168.96.23):root/testa.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: The remote end hung up unexpectedly
2
3
4
5
6
如下图:
如果你确确实实是第一次刚刚把主机初始化进入到Jenkins,然后配置了一个项目,配置完Git连接就见红报错了。那么这个时候你应该检查一下,是不是你的主机没有安装
git的命令
。使用yum -y install git即可解决。
之前有人在群里发过碰到这个错误怎么办,我当时因为理解不透,而且看到自己这边配置的地址是git@192.168.96.23:root/testa.git一直是成功的,因此就帮人指导说你换成git开头的URL就好了,熟不知问题的症结压根就不在这里,而是因为没有配置秘钥认证才导致的见红(报错)。
不过即便不是哪个开头的问题,我也推荐使用git开头的URL作为项目链接填写在这里,因为下午看廖雪峰Git教程时看到其中有这么说:使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。
因此,如果条件允许,那么我推荐使用git开头的url,如果公司禁止22端口,那么再选择其他。
现在说回刚才的问题。其实解决起来也非常简单。
不过此处也话分两头。
# 1,如果填写的url是刚才的http开头的。
那么此时点击红色提示下边的add添加可以登录到gitlab上并且对项目有权限的用户。
如我刚搭建的gitlab,账号还是默认的管理员root,如下将账号密码填写进去,点击add添加。
然后选择用户中,选中刚才添加的root账户。
此时就会发现,红色报错消失了,表明Jenkins与gitlab的连接通了。
# 2,如果刚刚填写的url是git开头的。
此时只用去到Jenkins服务器上,将其公钥放在gitlab的ssh key处,红色报错就消失了。
ssh-keygen #一路回车
cat /root/.ssh/id_rsa.pub #复制下来
2
1,点击头像选中设置。
2,点击ssh秘钥栏。
3,在此处将刚才复制的秘钥拷贝进来。
再回到Jenkins当中查看,发现报错也消失了。一旦这种互信创建完成之后,基本上两者就默认对上号了。
如果配置完了之后还不成功,而且报128的错误码,那么应该是在第一次建立互信的时候需要输入一下yes的问题,去Jenkins主机上,手动建立一次与gitlab的连接即可(建立ssh的连接或者git的连接都可以)。
其实上边刚才有两个地方的表述,是不严谨的,分别是1,2标题处我说当url的开头是什么什么,当时这么说只是为了让ssh与秘钥对应,http与用户名对应而已,事实上,只要配置了其中一种互信方式,那么无论url的开头是http还是git,都是可以连接的。
补充:
如果刚才add账户的时候错了,该怎么办呢?
去到首页—>点击Credentials就能看到自己添加过的用户,并进行管理了。
# 4,部署失败之ERROR: Couldn’t find any revision to build. Verify the repository and branch configuration for this job
当我们开发人员来找到我们说,我刚刚构建失败啦。
然后你去看到底什么问题。
ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.
看到这样的问题,那么基本可以断定,应该是他刚刚新建了一个分支,要进行测试构建,但是可能代码还没有push
到远端代码库,而在构建的时候又填写了这个分支,那么Jenkins就会报错:ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.(找不到任何修订版本。 验证此作业的存储库和分支配置--谷歌翻译)
就让他重新push之后在构建咯。这个问题可以通过构建一个不存在的分支进行复现测试。
# 5,部署之后代码没有改变的问题
最近两周新上项目较多,因此我与另外一位运维小伙伴两个人一起扛起了许多项目的交付与上线。
但是今天突然一个小伙伴跟我说,部署了之后发现代码没有变化。一开始我以为是Jenkins与Gitlab之间的问题,导致的代码更新问题。
后来跑到他身边,经过他那么一演示,我明白了。并根据经验解决了这次问题。
他给我演示的是原来代码里引用了某个类,现在呢,是把这个类给删除了,但是推了代码,重新发布,去看程序日志输出发现刚才删除的类,现在还在呢。
我就想应该是发布的时候没有清掉,估计就是mvn打包时候的问题啦,到Jenkins的配置里边一看,果然,只有正常打包的命令,而少了一个clean
的参数,从而使得这个程序的打包命令只会一直往前打包,也就是说代码里有新的依赖等的他会解决加进来,但是如果删掉了某个类或者依赖,他则不会做任何动作。
加上clean的参数,事实上就是首先将其清空,然后再来依据代码里边的pom文件或者其他装载着依赖的文件进行打包构建。于是,问题就解决啦!
更新之后的打包命令如下:
mvn clean install -Dmaven.test.skip=true
# 6,Jenkins与tomcat在同一台部署完毕进程被kill的问题
如果Jenkins与tomcat在同一台当中部署,这个时候部署项目的时候,发现部署完毕之后项目进程会被干掉。
问题过程大概是这样,当用户发起构建,系统当中会启动相应的进程进行构建任务,当构建任务完成之后,或者被人为中断之后,程序利用ProcessTreeKiller,获取计算机上运行的所有进程及其环境变量的列表,并查找最初为构建作业的进程设置的环境变量,然后终止在其环境中具有该环境变量的每个作业。
解决思路:实现这一目标的一种便捷方法是更改Jenkins的ProcessTreeKiller正在寻找的环境变量BUILD_ID,这将会让Jenkins认为您的守护进程不是由Jenkins构建生成的。
比如在执行shell当中添加如下变量即可:
BUILD_ID=dontKillMe
注意:如果Jenkins Pipeline使用JENKINS_NODE_COOKIE而不是BUILD_ID。
2
参考:https://wiki.jenkins.io/display/JENKINS/ProcessTreeKiller
# 7,配置了ldap之后无法启动
参看这里:https://www.58jb.com/html/jenkins_ldap_login_failure.html
# 8,项目连续构建第二次失败
我们配置的新项目,第一次构建正常,在进行第二次构建的时候会报如下错误:
Fetching changes from the remote Git repository
Using shallow fetch with depth 1
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from https://gitlab.eryajf.net/service/niffler-go.git
at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:996)
at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1237)
at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1297)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:125)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:93)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:80)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: hudson.plugins.git.GitException: Command "/usr/bin/git fetch --tags --progress --depth=1 https://gitlab.eryajf.net/service/niffler-go.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout:
stderr: fatal: git fetch-pack: expected shallow list
fatal: The remote end hung up unexpectedly
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2450)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandWithCredentials(CliGitAPIImpl.java:2051)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.access$500(CliGitAPIImpl.java:84)
at org.jenkinsci.plugins.gitclient.CliGitAPIImpl$1.execute(CliGitAPIImpl.java:573)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler$GitCommandMasterToSlaveCallable.call(RemoteGitImpl.java:161)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler$GitCommandMasterToSlaveCallable.call(RemoteGitImpl.java:154)
at hudson.remoting.UserRequest.perform(UserRequest.java:211)
at hudson.remoting.UserRequest.perform(UserRequest.java:54)
at hudson.remoting.Request$2.run(Request.java:375)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:73)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at hudson.remoting.Engine$1.lambda$newThread$0(Engine.java:118)
... 1 more
Suppressed: hudson.remoting.Channel$CallSiteStackTrace: Remote call to JNLP4-connect connection from 10.3.9.144/10.3.9.144:46742
at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1800)
at hudson.remoting.UserRequest$ExceptionResponse.retrieve(UserRequest.java:357)
at hudson.remoting.Channel.call(Channel.java:1001)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.execute(RemoteGitImpl.java:146)
at sun.reflect.GeneratedMethodAccessor559.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jenkinsci.plugins.gitclient.RemoteGitImpl$CommandInvocationHandler.invoke(RemoteGitImpl.java:132)
at com.sun.proxy.$Proxy92.execute(Unknown Source)
at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:994)
at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1237)
at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1297)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep.checkout(SCMStep.java:125)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:93)
at org.jenkinsci.plugins.workflow.steps.scm.SCMStep$StepExecutionImpl.run(SCMStep.java:80)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
... 1 more
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
这个错误在通过删除工作空间下的 .git
目录之后再发布就正常了,但这并不是解决问题的办法,网上看了很多的资料,说啥的都有,有说slave的jdk不能用openjdk的,这个变更之后没有效果。
也有说是git命名版本太低的,说低版本的git对浅层克隆支持的不太好,这倒是有可能的,因为我们的确在拉代码的地方加了 depth 1
的参数,于是乎,通过如下一顿操作,更换了git版本:
将如下内容写入到 /etc/yum.repos.d/wandisco-git.repo
:
[wandisco-git]
name=Wandisco GIT Repository
baseurl=http://opensource.wandisco.com/centos/7/git/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco
2
3
4
5
6
导入:
rpm --import http://opensource.wandisco.com/RPM-GPG-KEY-WANdisco
安装:
yum install -y git
查看:
git --version
之后上边的问题消失。
参考:
- https://issues.jenkins-ci.org/browse/JENKINS-37229
- https://github.com/sameersbn/docker-gitlab/issues/1968
# 9,ansible构建日志有乱码
通过Jenkinsfile调用的ansible命令,其中剧本中步骤名称使用的中文,在Jenkins的构建日志都都变成了 ??????
。
网上有的说更改ansible的配置文件,调整语言以解决此问题,但是调整之后并没有效果,其实还是Jenkins自身的语言影响的,此时在系统配置中,添加一条全局环境变量即可解决此问题:
LANG = en_US.UTF-8
# 10,Jenkins-有任务无法kill提示即将关闭
如果一些同学在构建的时候,中途将该构建取消,但是又没能正常取消的时候,这个构建可能会一直夯在这里,最终拖垮Jenkins。
构建日志中提示如下内容:
Click here to forcibly terminate running steps
Cancelling nested steps due to timeout
Body did not finish within grace period; terminating with extreme prejudice
2
3
然后Jenkins主界面会提示Jenkins 即将关闭
,其他构建也无法正常进行。
这个时候这个job怎么也无法取消,就算把Jenkins重启,之后仍然能看到这个job还卡在这里,拿着关键字在网上也搜不到解决办法。
如果想要彻底关闭这个构建,可执行如下方法关闭:
http://ci.eryajf.net/job/ops-test/job/dev-demo/22/kill
在对应构建ID之后,拼上kill请求之后,即可将这个异常的构建彻底kill掉。
# 11,pipeline中执行curl时双引号的问题
有时候在pipeline中会执行一些curl请求,此时大概率在请求体中的内容会有一些变量,那么就得使用双引号,而双引号被双引号包裹的时候,需要进行转义,但这里仍有一个需要注意的点,因为我们请求体通常为标准json,被Jenkins执行的时候,一层转义下来会把所有的引号脱掉,导致执行异常,这个时候需要添加两个转义符来解决这个问题。
比如,在shell脚本中中我们的操作如下:
JOB_BASE_NAME="test-job"
reqJson="{\"job_name\":\"${JOB_BASE_NAME}\"}"
echo "请求的body内容为: $reqJson"
curl --location --request POST 'http://test.eryajf.net/sendcards/' \
--header 'User-Agent: Jenkins' --header 'Content-Type: application/json' \
-d "${reqJson}"
2
3
4
5
6
7
8
此时脚本中是可以正常执行的,但是放到Jenkins的pipeline中,请求会变成:
curl --location --request POST http://test.eryajf.net/sendcards/ --header 'User-Agent: Jenkins' --header 'Content-Type: application/json' -d '{job_name:test-job}'
从而导致执行失败,此时放到pipeline里的代码应该如下:
script{
sh'''
JOB_BASE_NAME="test-job"
reqJson="{\\"job_name\\":\\"${JOB_BASE_NAME}\\"}"
echo "请求的body内容为: $reqJson"
curl --location --request POST 'http://test.eryajf.net/sendcards/' \
--header 'User-Agent: Jenkins' --header 'Content-Type: application/json' \
-d "${reqJson}"
'''
}
2
3
4
5
6
7
8
9
10
11
12
使用双转义符,就能够正常请求了。
参考:Escape double quotes in a Jenkins pipeline file's shell command (opens new window)