问题描述
在使用Jenkins流水线时,有一个需求是希望在流水线结束时重启节点,但是他发现Jenkins会将流水线状态标记为失败。用户想知道是否有一种安全的方式来重启节点,以避免Jenkins将流水线状态标记为失败。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在Jenkins流水线中,可以使用sudo shutdown -r +m5
命令来代替sudo reboot
命令,这样可以避免流水线失败。sudo shutdown -r +m5
命令会将重启进程交给系统处理,让Jenkins代理完成流水线的清理工作。
以下是具体步骤:
1. 修改流水线代码,将sudo reboot
命令替换为sudo shutdown -r +m5
命令。
下面是一个示例的流水线代码:
node('baremetal') {
checkout scm
try {
stage('Benchmarks') {
// 运行基准测试
}
stage('Process data') {
// 处理数据并将结果发送给用户
}
}
finally {
stage('Clean up') {
sh 'sudo shutdown -r +m5'
}
}
}
在上面的示例中,我们将sudo reboot
命令替换为sudo shutdown -r +m5
命令。这样,当流水线执行到最后的清理阶段时,节点将会被重启。
请注意,sudo shutdown -r +m5
命令会在重启之前创建/run/nologin
文件,以确保不再允许登录。
方案2
使用单独的任务来关闭节点,并在流水线中调用该任务,使用
build
步骤的wait: false
参数。关闭节点的任务可能需要在关闭节点之前添加一个延时,以避免在父任务退出之前关闭节点。
以下是一些启发性的想法:
– 创建一个单独的任务来关闭节点,并在流水线中使用build
步骤调用该任务,使用wait: false
参数,例如:build(job: "shutdown_host", wait: false)
。shutdown_host
任务可能需要在关闭节点之前添加一个延时,以避免在父任务退出之前关闭节点。
– 执行一个简短的shell脚本,使用fork和detach的方式启动一个新进程来关闭主机。同样,你可能需要在fork的进程中添加一个延时,以避免在Jenkins任务退出之前关闭节点。此外,在这种情况下,你需要禁用进程树杀手(Process Tree Killer),以避免杀死fork的进程。
– 在Jenkins主节点上执行一个步骤,通过ssh登录到节点并关闭它。但是,这取决于Jenkins主节点能够通过ssh访问节点,并具有关闭节点的管理权限。
当然,还有其他一些聪明和创造性的想法,我可能没有提到。
请注意,这些解决方案可能存在竞争条件。你可以在流水线代码中检查节点上是否有任何正在运行的任务(应该有其他Stack Exchange问题解决了如何做到这一点),然后再重启之前检查,或者你可以使用资源锁(类似于信号量)来防止竞争条件。