主旨
本文主要記錄了下Jenkins升級插件過程中出現的場景,一次加班經歷,事發時沒有截圖,有興趣可以看看。
起因
需求
最近有個需求:在Jenkins流水線中完成下載Git上的文件簡單修改並提交的功能
起初找到了相關的插件用法,即使用 SSH Agent Plugin
來完成這個功能
插件不生效
經測試無法完成效果,分別懷疑了以下幾點:
- 憑據配置有誤
- 寫錯了腳本
- 當前未安裝此插件
- 當前插件版本過低
- 當前插件由於某種原因未生效
排查不生效原因
經排查,發現的確沒有生效,原因是之前運維同事做遷移時做的一系列騷操作搞的:
- 用最新的Jenkins war包部署 + 老版本Jenkins家目錄
- 由於新版本需要使用新版本的插件才能生效,升級了所有插件
- 升級完重啟,啟動不起來了……
- 回退老版本war包,繼續使用當前升級過插件的Jenkins家目錄
- 在插件管理處,按提示降級了部分插件
預感
等我看到 Manage Jenkins
那一片紅的時候,就有預感這次要不簡單,當時也沒多想,去檢查了下 SSH Agent Plugin
的版本
升級插件
發現提示Warn 需要升級此插件到某版本及以后,插件方能生效,沒多想,升級就是了
沒想此舉為我昨晚的加班,打開了潘多拉魔盒…… 升級完重啟,啟動不起來了!
Jenkins掛機
啟動報錯如下:(昨晚沒心情截圖,直接搜的錯誤)
com.thoughtworks.xstream.mapper.CannotResolveClassException: com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategyat com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:79)atcom.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at hudson.util.XStream2$CompatibilityMapper.realClass(XStream2.java:379)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at org.jenkinsci.jruby.JRubyMapper.realClass(JRubyMapper.java:34)
at hudson.util.xstream.MapperDelegate.realClass(MapperDelegate.java:43)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:48)
at hudson.util.RobustReflectionConverter.determineType(RobustReflectionConverter.java:461)
at hudson.util.RobustReflectionConverter.doUnmarshal(RobustReflectionConverter.java:327)
Caused: jenkins.util.xstream.CriticalXStreamException: com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
---- Debugging information ----
message : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message : com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy
class : hudson.model.Hudson
required-type : hudson.model.Hudson
converter-type : hudson.util.RobustReflectionConverter
path : /hudson/authorizationStrategy
line number : 11
version : not available
-------------------------------
at hudson.util.RobustReflectionConverter.doUnmarshal(RobustReflectionConverter.java:356)
at hudson.util.RobustReflectionConverter.unmarshal(RobustReflectionConverter.java:270)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1189)
at hudson.util.XStream2.unmarshal(XStream2.java:161)
at hudson.util.XStream2.unmarshal(XStream2.java:132)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1173)
at hudson.XmlFile.unmarshal(XmlFile.java:178)
Caused: java.io.IOException: Unable to read /var/lib/jenkins/config.xml
at hudson.XmlFile.unmarshal(XmlFile.java:181)
at hudson.XmlFile.unmarshal(XmlFile.java:161)
at jenkins.model.Jenkins.loadConfig(Jenkins.java:3005)
at jenkins.model.Jenkins.access$1300(Jenkins.java:304)
at jenkins.model.Jenkins$13.run(Jenkins.java:3104)
at org.jvnet.hudson.reactor.TaskGraphBuilder$TaskImpl.run(TaskGraphBuilder.java:169)
at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:296)
at jenkins.model.Jenkins$5.runTask(Jenkins.java:1066)
at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:214)
at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:117)
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: org.jvnet.hudson.reactor.ReactorException
at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:282)
at jenkins.InitReactorRunner.run(InitReactorRunner.java:48)
at jenkins.model.Jenkins.executeReactor(Jenkins.java:1100)
at jenkins.model.Jenkins.<init>(Jenkins.java:904)
at hudson.model.Hudson.<init>(Hudson.java:85)
at hudson.model.Hudson.<init>(Hudson.java:81)
at hudson.WebAppMain$3.run(WebAppMain.java:233)
Caused: hudson.util.HudsonFailedToLoad
at hudson.WebAppMain$3.run(WebAppMain.java:250)
經過
按錯誤信息排解問題
發現問題不可怕,一頓 Google Bing 發現了 StackOverFlow 的相關問題解決辦法
說是因為升級了 Role-based Authorization Strategy
插件會導致這個問題,What?? 我沒升級它啊,這怎么回事!先看看外國老哥的解法:
簡述解法:
- 備份下 Jenkins 家目錄下的 config.xml
- 修改原 config.xml,注釋掉
authorizationStrategy
塊,修改useSecurity
為 true - 重啟服務,訪問成功再關閉服務
- 恢復 config.xml 備份 替換 config.xml
- 重啟服務
按這一套操作后,的確服務能起來了
工程蒸發,引發的思考
接下來發現了另一個問題 ———— 所有工程都沒了!!
先顧不上工程蒸發了的問題,手動創建了個測試流水線工程來測下 SSH Agent Plugin
是否生效,發現依舊無效
工程沒了問題其實不大,因為用戶還在
、權限還在
、構建工程的流水線腳本在 GitLab 上
,大不了再配置一下就行了
我想了下,就算配置好工程后,使 SSH Agent Plugin 插件生效
還沒完成啊,插件版本還是亂成了一鍋粥,這不是定時炸彈么
簡單了解了下,Jenkins 的插件升級后,降級的版本是有一個默認值的,但這個值不一定是當前 Jenkins 版本默認或可用的值,最好的辦法是向上升級
思及此節,決定去升級下 Jenkins 及插件,另辟了一處實驗場
開搞
備份Jenkins家目錄
Jenkins 家目錄里最大的部分是 workspace 這個目錄,就是每個構建工程運行時的家目錄的父級,這個目錄里的數據無需備份
將 Jenkins 家目錄備走后,手動創建 workspace 目錄,以防新工程無法構建
下載新war包,部署Tomcat
在中科大的靜像站下載了2.222.3的war包 https://mirrors.ustc.edu.cn/jenkins/war-stable/2.222.3/
部署到Tomcat的ROOT目錄下
修改Tomcat conf/server.xml,修改 Tomcat 編碼為UTF-8
修改 conf/context.xml,修改靜態資源緩存最大值,需添加一行 <Resources cachingAllowed="true" cacheMaxSize="100000" />
啟動Tomcat
訪問測試Jenkins服務,查看插件錯誤警告
訪問服務后,發現服務還可以登錄,進來看到工程都還在!點開 Manage Jenkins
處,發現仍是大面積報紅,檢查發現是 Pipeline
依賴的組件不正確,按錯誤提示去 pluginManager updates處找到被依賴的插件,按提示升級,升級完重啟(大部分插件需要重啟以激活)
重啟后,Pipeline相關的錯誤不在了,再去看其他的,直到所有的都解決了,插件也都正常了
除了之前插件上的報紅,還有幾處安全提示,我們的Jenkins不連外網,就一並關掉了
最后 Manage Jenkins
就變成了這樣
備份,恢復服務
備份原服務家目錄,將新版本部署到原 Tomcat,還原新版本家目錄,重啟服務
在恢復過程中,有提示某些數據 Unreadable,這些可以通過點擊提示,管理這些舊數據,我這邊因為主要的東西都在,就選了清除不可讀數據了
后續工程修復,測試插件
所有失而復得的工程,其實只記錄了內部的一些參數,但 SCM 如Git,這些流水線腳本信息都沒記錄,可能是因為 Git 插件升級所致
苦逼的一個一個加回來,好在工程不多,也就10來個,等所有工程修復好后,我測試了下之前失效的插件,插件可用了 :happy:
結尾
寫這段文字主要記錄一下這件挺坑的事,警示自己或大家,不要在沒備份的情況下,去做一些不可逆的操作,比如升級 Jenkins,備份的作用同樣適用於其他場景